FileBands.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.harmony.unpack200;

  18. import java.io.IOException;
  19. import java.io.InputStream;

  20. import org.apache.commons.compress.harmony.pack200.Codec;
  21. import org.apache.commons.compress.harmony.pack200.Pack200Exception;
  22. import org.apache.commons.compress.utils.IOUtils;

  23. /**
  24.  * Parses the file band headers (not including the actual bits themselves). At the end of this parse call, the input stream will be positioned at the start of
  25.  * the file_bits themselves, and there will be Sum(file_size) bits remaining in the stream with BYTE1 compression. A decent implementation will probably just
  26.  * stream the bytes out to the reconstituted Jar rather than caching them.
  27.  */
  28. public class FileBands extends BandSet {

  29.     private byte[][] fileBits;

  30.     private int[] fileModtime;

  31.     private String[] fileName;

  32.     private int[] fileOptions;

  33.     private long[] fileSize;

  34.     private final String[] cpUTF8;

  35.     private InputStream in;

  36.     /**
  37.      * @param segment TODO
  38.      */
  39.     public FileBands(final Segment segment) {
  40.         super(segment);
  41.         this.cpUTF8 = segment.getCpBands().getCpUTF8();
  42.     }

  43.     public byte[][] getFileBits() {
  44.         return fileBits;
  45.     }

  46.     public int[] getFileModtime() {
  47.         return fileModtime;
  48.     }

  49.     public String[] getFileName() {
  50.         return fileName;
  51.     }

  52.     public int[] getFileOptions() {
  53.         return fileOptions;
  54.     }

  55.     public long[] getFileSize() {
  56.         return fileSize;
  57.     }

  58.     // TODO: stream the file bits directly somehow
  59.     public void processFileBits() throws IOException {
  60.         // now read in the bytes
  61.         final int numberOfFiles = header.getNumberOfFiles();
  62.         fileBits = new byte[numberOfFiles][];
  63.         for (int i = 0; i < numberOfFiles; i++) {
  64.             final int size = (int) fileSize[i];
  65.             fileBits[i] = IOUtils.readRange(in, size);
  66.             final int read = fileBits[i].length;
  67.             if (size != 0 && read < size) {
  68.                 throw new IOException("Expected to read " + size + " bytes but read " + read);
  69.             }
  70.         }
  71.     }

  72.     /*
  73.      * (non-Javadoc)
  74.      *
  75.      * @see org.apache.commons.compress.harmony.unpack200.BandSet#unpack(java.io.InputStream)
  76.      */
  77.     @Override
  78.     public void read(final InputStream in) throws IOException, Pack200Exception {
  79.         final int numberOfFiles = header.getNumberOfFiles();
  80.         final SegmentOptions options = header.getOptions();

  81.         fileName = parseReferences("file_name", in, Codec.UNSIGNED5, numberOfFiles, cpUTF8);
  82.         fileSize = parseFlags("file_size", in, numberOfFiles, Codec.UNSIGNED5, options.hasFileSizeHi());
  83.         if (options.hasFileModtime()) {
  84.             fileModtime = decodeBandInt("file_modtime", in, Codec.DELTA5, numberOfFiles);
  85.         } else {
  86.             fileModtime = new int[numberOfFiles];
  87.         }
  88.         if (options.hasFileOptions()) {
  89.             fileOptions = decodeBandInt("file_options", in, Codec.UNSIGNED5, numberOfFiles);
  90.         } else {
  91.             fileOptions = new int[numberOfFiles];
  92.         }
  93.         this.in = in; // store for use by processFileBits(), which is called
  94.         // later
  95.     }

  96.     @Override
  97.     public void unpack() {

  98.     }

  99. }