Index: /Users/alex/Documents/HarmonyWorkspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java =================================================================== --- /Users/alex/Documents/HarmonyWorkspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java (revision 415821) +++ /Users/alex/Documents/HarmonyWorkspace/Pack200/src/main/java/org/apache/harmony/archive/internal/pack200/Segment.java (working copy) @@ -189,14 +189,24 @@ private int defaultClassMinorVersion; + private byte[][] file_bits; + + private int file_count; + + private long[] file_modtime; + + private String[] file_name; + + private long[] file_options; + + private long[] file_size; + private int innerClassCount; private int major; private int minor; - private int numberOfFiles; - private SegmentOptions options; private int segmentsRemaining; @@ -210,7 +220,7 @@ } public int getNumberOfFiles() { - return numberOfFiles; + return file_count; } private SegmentOptions getOptions() { @@ -269,6 +279,14 @@ throw new Error("No idea what the adc is for yet"); } + private void parseBcBands(InputStream in) { + System.err.println("Not yet implemented"); + } + + private void parseClassBands(InputStream in) { + System.err.println("Not yet implemented"); + } + private void parseClassCounts(InputStream in) throws IOException, Pack200Exception { setInnerClassCount(Codec.UNSIGNED5.decode(in)); @@ -584,6 +602,57 @@ } /** + * 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 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 stream the bytes out to the reconstituted Jar rather + * than caching them. + * + * @param in + * the input stream to read from + * @throws IOException + * if a problem occurs during reading from the underlying stream + * @throws Pack200Exception + * if a problem occurs with an unexpected value or unsupported + * codec + */ + private void parseFileBands(InputStream in) throws IOException, + Pack200Exception { + long last; + file_name = parseReferences(in, Codec.UNSIGNED5, file_count, cpUTF8); + file_size = new long[file_count]; + if (options.hasFileSizeHi()) { + last = 0; + for (int i = 0; i < file_count; i++) { + file_size[i] = (last = Codec.UNSIGNED5.decode(in, last)) << 32; + } + } + last = 0; + for (int i = 0; i < file_count; i++) { + file_size[i] |= (last = Codec.UNSIGNED5.decode(in, last)); + } + file_modtime = new long[file_count]; + if (options.hasFileModtime()) { + last = 0; + for (int i = 0; i < file_count; i++) { + file_modtime[i] |= (last = Codec.DELTA5.decode(in, last)); + } + } + file_options = new long[file_count]; + if (options.hasFileOptions()) { + last = 0; + for (int i = 0; i < file_count; i++) { + file_options[i] |= (last = Codec.UNSIGNED5.decode(in, last)); + } + } + } + + private void parseIcBands(InputStream in) { + System.err.println("Not yet implemented"); + } + + /** * Helper method to parse count references from in, * using codec to decode the values as indexes into * reference (which is populated prior to this call). An @@ -652,6 +721,12 @@ parseCpMethod(in); parseCpIMethod(in); parseAttributeDefinition(in); + parseIcBands(in); // Not yet implemented + parseClassBands(in); // Not yet implemented + parseBcBands(in); // Not yet implemented + parseFileBands(in); + processFileBits(in); // this just caches them in file_bits; it should + // probably start writing here? } private void parseSegmentHeader(InputStream in) throws IOException, @@ -668,6 +743,22 @@ parseClassCounts(in); } + private void processFileBits(InputStream in) throws IOException, + Pack200Exception { + // now read in the bytes + file_bits = new byte[file_count][]; + for (int i = 0; i < file_count; i++) { + int size = (int) file_size[i]; + // TODO This buggers up if file_size > 2^32. Probably an array is + // not the right choice, and + // we should just serialise the bugger here? + file_bits[i] = new byte[size]; + for (int j = 0; j < size; j++) { + file_bits[i][j] = (byte) Codec.BYTE1.decode(in); + } + } + } + public void setArchiveModtime(long archiveModtime) { this.archiveModtime = archiveModtime; } @@ -781,7 +872,7 @@ } public void setNumberOfFiles(long value) { - numberOfFiles = (int) value; + file_count = (int) value; } private void setOptions(SegmentOptions options) {