You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2008/03/04 09:02:45 UTC
svn commit: r633384 [13/15] - in /harmony/enhanced/classlib/branches/java6:
depends/build/platform/ depends/files/ depends/files/bcprov/ doc/
doc/classlib/ make/ make/linux.ia64/ make/linux.ppc32/ make/linux.ppc64/
make/linux.x86.libstdc++6/ make/linux...
Modified: harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java Tue Mar 4 00:02:13 2008
@@ -65,7 +65,7 @@
* The two errors can be handled in three ways, the default one is to report the
* error to the invoker by a {@link CoderResult CoderResult} instance, and the
* alternatives are to ignore it or to replace the erroneous input with the
- * replacement string. The replacement string is "\uFFFD" by default and can be
+ * replacement string. The replacement string is "\uFFFD" by default and can be
* changed by invoking {@link #replaceWith(String) replaceWith} method. The
* invoker of this decoder can choose one way by specifying a
* {@link CodingErrorAction CodingErrorAction} instance for each error type via
@@ -138,7 +138,7 @@
* Construct a new <code>CharsetDecoder</code> using given
* <code>Charset</code>, average number and maximum number of characters
* created by this decoder for one input byte, and the default replacement
- * string "\uFFFD".
+ * string "\uFFFD".
*
* @param charset
* this decoder's <code>Charset</code>, which create this
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java Tue Mar 4 00:02:13 2008
@@ -17,12 +17,15 @@
package org.apache.harmony.pack200;
import java.io.BufferedInputStream;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.GZIPInputStream;
@@ -54,18 +57,41 @@
private boolean deflateHint;
+ private String inputFileName;
+
+ /**
+ * Creates an Archive with the given input and output file names.
+ * @param inputFile
+ * @param outputFile
+ * @throws FileNotFoundException if the input file does not exist
+ * @throws IOException
+ */
public Archive(String inputFile, String outputFile)
throws FileNotFoundException, IOException {
+ this.inputFileName = inputFile;
inputStream = new FileInputStream(inputFile);
outputStream = new JarOutputStream(new FileOutputStream(outputFile));
}
+ /**
+ * Creates an Archive with streams for the input and output files.
+ * Note: If you use this method then calling {@link #setRemovePackFile(boolean)}
+ * will have no effect.
+ * @param inputStream
+ * @param outputStream
+ * @throws IOException
+ */
public Archive(InputStream inputStream, JarOutputStream outputStream)
- throws FileNotFoundException, IOException {
+ throws IOException {
this.inputStream = inputStream;
this.outputStream = outputStream;
}
+ /**
+ * Unpacks the Archive from the input file to the output file
+ * @throws Pack200Exception
+ * @throws IOException
+ */
public void unpack() throws Pack200Exception, IOException {
outputStream.setComment("PACK200");
try {
@@ -83,25 +109,33 @@
inputStream.reset();
}
inputStream.mark(4);
- int[] jarMagic = { 0xCA, 0xFE, 0xBA, 0xBE }; // Magic word for a Jar file
- byte word[] = new byte[4];
- inputStream.read(word);
- boolean compressedWithE0 = true;
- for (int m = 0; m < jarMagic.length; m++) {
- if (word[m] != jarMagic[m]) {
- compressedWithE0 = false;
+ int[] magic = { 0xCA, 0xFE, 0xD0, 0x0D }; // Magic word for pack200
+ int word[] = new int[4];
+ for (int i = 0; i < word.length; i++) {
+ word[i] = inputStream.read();
+ }
+ boolean compressedWithE0 = false;
+ for (int m = 0; m < magic.length; m++) {
+ if (word[m] != magic[m]) {
+ compressedWithE0 = true;
}
}
inputStream.reset();
if(compressedWithE0) { // The original Jar was not packed, so just copy it across
- byte[] bytes = new byte[16384];
- int bytesRead = 0;
- while(bytesRead != -1) {
- bytesRead = inputStream.read(bytes);
- outputStream.write(bytes, 0, bytesRead);
+ JarInputStream jarInputStream = new JarInputStream(inputStream);
+ JarEntry jarEntry;
+ while((jarEntry = jarInputStream.getNextJarEntry()) != null) {
+ outputStream.putNextEntry(jarEntry);
+ byte[] bytes = new byte[16384];
+ int bytesRead = jarInputStream.read(bytes);
+ while(bytesRead != -1) {
+ outputStream.write(bytes, 0, bytesRead);
+ bytesRead = jarInputStream.read(bytes);
+ }
+ outputStream.closeEntry();
}
} else {
- while (inputStream.available() > 0) {
+ while (available(inputStream)) {
Segment segment = new Segment();
segment.setLogLevel(logLevel);
segment.setLogStream(logFile != null ? (OutputStream) logFile
@@ -110,20 +144,36 @@
segment.overrideDeflateHint(deflateHint);
}
segment.unpack(inputStream, outputStream);
+ outputStream.flush();
}
}
- } catch (IOException e) {
+ } finally {
try {
inputStream.close();
- } finally {
+ } catch (Exception e2) {}
+ try {
outputStream.close();
- }
+ } catch (Exception e2) {}
}
if (removePackFile) {
-
+ File file = new File(inputFileName);
+ file.delete();
}
}
+ private boolean available(InputStream inputStream) throws IOException {
+ inputStream.mark(1);
+ int check = inputStream.read();
+ inputStream.reset();
+ return check != -1;
+ }
+
+ /**
+ * If removePackFile is set to true, the input file is deleted after
+ * unpacking
+ *
+ * @param removePackFile
+ */
public void setRemovePackFile(boolean removePackFile) {
this.removePackFile = removePackFile;
}
@@ -142,7 +192,6 @@
} else if (logLevel == LOG_LEVEL_QUIET) {
logLevel = LOG_LEVEL_QUIET;
}
- ;
}
public void setLogFile(String logFileName) throws FileNotFoundException {
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Tue Mar 4 00:02:13 2008
@@ -68,17 +68,99 @@
* invalid
*/
public int[] decodeBandInt(String name, InputStream in,
- BHSDCodec defaultCodec, int count) throws IOException,
+ BHSDCodec codec, int count) throws IOException,
Pack200Exception {
- // TODO Might be able to improve this directly.
- int[] result = new int[count];
- long[] longResult = decodeBandLong(name, in, defaultCodec, count);
- for (int i = 0; i < count; i++) {
- result[i] = (int) longResult[i];
+ return decodeBandInt(name, in, codec, count, true);
+ }
+
+ /**
+ * Decode a band and return an array of <code>int</code> values
+ *
+ * @param name
+ * the name of the band (primarily for logging/debugging
+ * purposes)
+ * @param in
+ * the InputStream to decode from
+ * @param defaultCodec
+ * the default codec for this band
+ * @param count
+ * the number of elements to read
+ * @return an array of decoded <code>int</code> values
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if there is a problem decoding the value or that the value is
+ * invalid
+ */
+ public int[] decodeBandInt(String name, InputStream in,
+ BHSDCodec codec, int count, boolean negativesAllowed) throws IOException,
+ Pack200Exception {
+ int[] band;
+ Codec codecUsed = codec;
+ if (codec.getB() == 1 || count == 0) {
+ return codec.decodeInts(count, in);
}
- return result;
+ int[] getFirst = codec.decodeInts(1, in);
+ if (getFirst.length == 0) {
+ return getFirst;
+ }
+ int first = getFirst[0];
+ if (codec.isSigned() && first >= -256 && first <= -1) {
+ // Non-default codec should be used
+ codecUsed = CodecEncoding.getCodec((-1 - first),
+ header.getBandHeadersInputStream(), codec);
+ band = codecUsed.decodeInts(count, in);
+ } else if (!codec.isSigned() && first >= codec.getL()
+ && first <= codec.getL() + 255) {
+ // Non-default codec should be used
+ codecUsed = CodecEncoding.getCodec(first
+ - codec.getL(), header.getBandHeadersInputStream(), codec);
+ band = codecUsed.decodeInts(count, in);
+ } else {
+ // First element should not be discarded
+ band = codec.decodeInts(count - 1, in, first);
+ }
+ if(!negativesAllowed && codec != codecUsed) {
+ if(codecUsed instanceof BHSDCodec && ((BHSDCodec)codecUsed).isSigned()) {
+ for (int i = 0; i < band.length; i++) {
+ while(band[i] < 0) {
+ band[i] += ((BHSDCodec)codecUsed).cardinality();
+ }
+ }
+ }
+ }
+ return band;
+ }
+
+ /**
+ * Decode a band and return an array of <code>int[]</code> values
+ *
+ * @param name
+ * the name of the band (primarily for logging/debugging
+ * purposes)
+ * @param in
+ * the InputStream to decode from
+ * @param defaultCodec
+ * the default codec for this band
+ * @param counts
+ * the numbers of elements to read for each int array within the
+ * array to be returned
+ * @return an array of decoded <code>int[]</code> values
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if there is a problem decoding the value or that the value is
+ * invalid
+ */
+ public int[][] decodeBandInt(String name, InputStream in,
+ BHSDCodec defaultCodec, int[] counts)
+ throws IOException, Pack200Exception {
+ return decodeBandInt(name, in, defaultCodec, counts, true);
}
+ // TODO: Use this version for all bands that shouldn't have negatives.
/**
* Decode a band and return an array of <code>int[]</code> values
*
@@ -100,13 +182,15 @@
* if there is a problem decoding the value or that the value is
* invalid
*/
- public int[][] decodeBandInt(String name, InputStream in, BHSDCodec defaultCodec, int[] counts) throws IOException, Pack200Exception {
+ public int[][] decodeBandInt(String name, InputStream in,
+ BHSDCodec defaultCodec, int[] counts, boolean negativesAllowed)
+ throws IOException, Pack200Exception {
int[][] result = new int[counts.length][];
int totalCount = 0;
for (int i = 0; i < counts.length; i++) {
totalCount += counts[i];
}
- int[] twoDResult = decodeBandInt(name, in, defaultCodec, totalCount);
+ int[] twoDResult = decodeBandInt(name, in, defaultCodec, totalCount, negativesAllowed);
int index = 0;
for (int i = 0; i < result.length; i++) {
result[i] = new int[counts[i]];
@@ -325,37 +409,33 @@
}
private int[] decodeBandInt(String name, InputStream in, BHSDCodec codec, int count, int maxValue) throws IOException, Pack200Exception {
- long[] band;
+ int[] band;
Codec codecUsed = codec;
if (codec.getB() == 1 || count == 0) {
- band = codec.decode(count, in);
+ band = codec.decodeInts(count, in);
} else {
- long[] getFirst = codec.decode(1, in);
+ int[] getFirst = codec.decodeInts(1, in);
if (getFirst.length == 0) {
return new int[0];
}
- long first = getFirst[0];
+ int first = getFirst[0];
if (codec.isSigned() && first >= -256 && first <= -1) {
// Non-default codec should be used
- codecUsed = CodecEncoding.getCodec((int) (-1 - first),
+ codecUsed = CodecEncoding.getCodec((-1 - first),
header.getBandHeadersInputStream(), codec);
- band = codecUsed.decode(count, in);
+ band = codecUsed.decodeInts(count, in);
} else if (!codec.isSigned() && first >= codec.getL()
&& first <= codec.getL() + 255) {
// Non-default codec should be used
- codecUsed = CodecEncoding.getCodec((int) first
+ codecUsed = CodecEncoding.getCodec(first
- codec.getL(), header.getBandHeadersInputStream(), codec);
- band = codecUsed.decode(count, in);
+ band = codecUsed.decodeInts(count, in);
} else {
// First element should not be discarded
- band = codec.decode(count - 1, in, first);
+ band = codec.decodeInts(count - 1, in, first);
}
}
- int[] returnBand = new int[band.length];
- for (int i = 0; i < returnBand.length; i++) {
- returnBand[i] = (int)band[i];
- }
/*
* Note - this is not in the spec, but seems to be used as an
@@ -365,35 +445,34 @@
* inside the range anyway.
*/
if (codecUsed instanceof BHSDCodec) {
- for (int i = 0; i < returnBand.length; i++) {
- while (returnBand[i] < 0) {
- returnBand[i] += ((BHSDCodec) codecUsed).cardinality();
+ for (int i = 0; i < band.length; i++) {
+ while (band[i] < 0) {
+ band[i] += ((BHSDCodec) codecUsed).cardinality();
}
- while (returnBand[i] > maxValue) {
- returnBand[i] -= ((BHSDCodec) codecUsed).cardinality();
+ while (band[i] > maxValue) {
+ band[i] -= ((BHSDCodec) codecUsed).cardinality();
}
}
} else if (codecUsed instanceof PopulationCodec) {
PopulationCodec popCodec = (PopulationCodec)codecUsed;
long[] favoured = (long[]) popCodec.getFavoured().clone();
Arrays.sort(favoured);
- for (int i = 0; i < returnBand.length; i++) {
- if(returnBand[i] < 0 || returnBand[i] > maxValue) {
- boolean favouredValue = Arrays.binarySearch(favoured, returnBand[i]) > -1;
+ for (int i = 0; i < band.length; i++) {
+ if(band[i] < 0 || band[i] > maxValue) {
+ boolean favouredValue = Arrays.binarySearch(favoured, band[i]) > -1;
Codec theCodec = favouredValue ? popCodec.getFavouredCodec(): popCodec.getUnvafouredCodec();
if(theCodec instanceof BHSDCodec) {
- while (returnBand[i] < 0) {
- returnBand[i] += ((BHSDCodec) theCodec).cardinality();
+ while (band[i] < 0) {
+ band[i] += ((BHSDCodec) theCodec).cardinality();
}
- while (returnBand[i] > maxValue) {
- returnBand[i] -= ((BHSDCodec) theCodec).cardinality();
+ while (band[i] > maxValue) {
+ band[i] -= ((BHSDCodec) theCodec).cardinality();
}
}
}
}
}
-
- return returnBand;
+ return band;
}
/**
@@ -418,7 +497,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPInteger(new Integer(reference[index]));
+ result[i1] = segment.getCpBands().cpIntegerValue(new Integer(reference[index]));
}
return result;
}
@@ -432,7 +511,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPDouble(new Double(reference[index]));
+ result[i1] = segment.getCpBands().cpDoubleValue(new Double(reference[index]));
}
return result;
}
@@ -446,7 +525,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPFloat(new Float(reference[index]));
+ result[i1] = segment.getCpBands().cpFloatValue(new Float(reference[index]));
}
return result;
}
@@ -460,7 +539,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPLong(new Long(reference[index]));
+ result[i1] = segment.getCpBands().cpLongValue(new Long(reference[index]));
}
return result;
}
@@ -474,7 +553,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
+ result[i1] = segment.getCpBands().cpUTF8Value(reference[index], ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
return result;
}
@@ -495,7 +574,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result1[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
+ result1[i1] = segment.getCpBands().cpUTF8Value(reference[index], ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
CPUTF8[] refs = result1;
int pos = 0;
@@ -517,58 +596,69 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPString(reference[index]);
+ result[i1] = segment.getCpBands().cpStringValue(reference[index]);
}
return result;
}
public CPInterfaceMethodRef[] parseCPInterfaceMethodRefReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
- String[] reference = segment.getCpBands().getCpIMethodClass();
- String[] descriptors = segment.getCpBands().getCpIMethodDescriptor();
+ CpBands cpBands = segment.getCpBands();
+ String[] reference = cpBands.getCpIMethodClass();
+ String[] descriptors = cpBands.getCpIMethodDescriptor();
int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
CPInterfaceMethodRef[] result = new CPInterfaceMethodRef[indices.length];
for (int i1 = 0; i1 < count; i1++) {
int index = indices[i1];
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
- "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPInterfaceMethodRef(reference[index], descriptors[index]);
+ "Something has gone wrong during parsing references, index = "
+ + index + ", array size = " + reference.length);
+ result[i1] = new CPInterfaceMethodRef(cpBands
+ .cpClassValue(reference[index]), cpBands
+ .cpNameAndTypeValue(descriptors[index]));
}
return result;
}
public CPMethodRef[] parseCPMethodRefReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
- String[] reference = segment.getCpBands().getCpMethodClass();
- String[] descriptors = segment.getCpBands().getCpMethodDescriptor();
+ CpBands cpBands = segment.getCpBands();
+ String[] reference = cpBands.getCpMethodClass();
+ String[] descriptors = cpBands.getCpMethodDescriptor();
int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
CPMethodRef[] result = new CPMethodRef[indices.length];
for (int i1 = 0; i1 < count; i1++) {
int index = indices[i1];
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
- "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPMethodRef(reference[index], descriptors[index]);
+ "Something has gone wrong during parsing references, index = "
+ + index + ", array size = " + reference.length);
+ result[i1] = new CPMethodRef(cpBands.cpClassValue(reference[index]),
+ cpBands.cpNameAndTypeValue(descriptors[index]));
}
return result;
}
public CPFieldRef[] parseCPFieldRefReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
- String[] reference = segment.getCpBands().getCpFieldClass();
- String[] descriptors = segment.getCpBands().getCpFieldDescriptor();
+ CpBands cpBands = segment.getCpBands();
+ String[] reference = cpBands.getCpFieldClass();
+ String[] descriptors = cpBands.getCpFieldDescriptor();
int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
CPFieldRef[] result = new CPFieldRef[indices.length];
for (int i1 = 0; i1 < count; i1++) {
int index = indices[i1];
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
- "Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPFieldRef(reference[index], descriptors[index]);
+ "Something has gone wrong during parsing references, index = "
+ + index + ", array size = " + reference.length);
+ result[i1] = new CPFieldRef(cpBands.cpClassValue(reference[index]),
+ cpBands.cpNameAndTypeValue(descriptors[index]));
}
return result;
}
public CPNameAndType[] parseCPDescriptorReferences(String name, InputStream in, BHSDCodec codec, int count) throws IOException, Pack200Exception {
- String[] reference = segment.getCpBands().getCpDescriptor();
+ CpBands cpBands = segment.getCpBands();
+ String[] reference = cpBands.getCpDescriptor();
int[] indices = decodeBandInt(name, in, codec, count, reference.length - 1);
CPNameAndType[] result = new CPNameAndType[indices.length];
for (int i1 = 0; i1 < count; i1++) {
@@ -576,7 +666,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPNameAndType(reference[index]);
+ result[i1] = cpBands.cpNameAndTypeValue(reference[index]);
}
return result;
}
@@ -590,7 +680,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPUTF8(reference[index], ClassConstantPool.DOMAIN_UNDEFINED);
+ result[i1] = segment.getCpBands().cpUTF8Value(reference[index], ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
}
return result;
}
@@ -604,7 +694,7 @@
if (index < 0 || index >= reference.length)
throw new Pack200Exception(
"Something has gone wrong during parsing references, index = " + index + ", array size = " + reference.length);
- result[i1] = new CPClass(reference[index]);
+ result[i1] = segment.getCpBands().cpClassValue(reference[index]);
}
return result;
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Tue Mar 4 00:02:13 2008
@@ -141,14 +141,6 @@
}
for (int i = 0; i < methodByteCodePacked[c][m].length; i++) {
int codePacked = 0xff & methodByteCodePacked[c][m][i];
- // TODO a lot of this needs to be encapsulated in the
- // place that
- // calculates what the arguments are, since (a) it will
- // need
- // to know where to get them, and (b) what to do with
- // them
- // once they've been gotten. But that's for another
- // time.
switch (codePacked) {
case 16: // bipush
case 188: // newarray
@@ -263,12 +255,12 @@
int nextInstruction = 0xff & methodByteCodePacked[c][m][i+1];
wideByteCodes.add(new Integer(nextInstruction));
if (nextInstruction == 132) { // iinc
- bcLocalCount += 2;
+ bcLocalCount ++;
bcShortCount++;
} else if (endsWithLoad(nextInstruction)
|| endsWithStore(nextInstruction)
|| nextInstruction == 169) {
- bcLocalCount += 2;
+ bcLocalCount ++;
} else {
debug("Found unhandled " + ByteCode.getByteCode(nextInstruction));
}
@@ -394,7 +386,7 @@
if(handlerCount != null) {
for (int j = 0; j < handlerCount[i]; j++) {
String handlerClass = handlerClassTypes[i][j];
- CPClass cpHandlerClass = new CPClass(handlerClass);
+ CPClass cpHandlerClass = segment.getCpBands().cpClassValue(handlerClass);
ExceptionTableEntry entry = new ExceptionTableEntry(
handlerStartPCs[i][j], handlerEndPCs[i][j],
handlerCatchPCs[i][j], cpHandlerClass);
@@ -406,7 +398,6 @@
operandManager, exceptionTable);
methodAttributes[c][m].add(codeAttr);
codeAttr.renumber(codeAttr.byteCodeOffsets);
- // Should I add all the attributes in here?
ArrayList currentAttributes = (ArrayList)orderedCodeAttributes.get(i);
for(int index=0;index < currentAttributes.size(); index++) {
Attribute currentAttribute = (Attribute)currentAttributes.get(index);
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java Tue Mar 4 00:02:13 2008
@@ -24,9 +24,15 @@
import org.apache.harmony.pack200.bytecode.Attribute;
import org.apache.harmony.pack200.bytecode.CPClass;
+import org.apache.harmony.pack200.bytecode.CPDouble;
+import org.apache.harmony.pack200.bytecode.CPFloat;
+import org.apache.harmony.pack200.bytecode.CPInteger;
+import org.apache.harmony.pack200.bytecode.CPLong;
import org.apache.harmony.pack200.bytecode.CPNameAndType;
+import org.apache.harmony.pack200.bytecode.CPString;
import org.apache.harmony.pack200.bytecode.CPUTF8;
import org.apache.harmony.pack200.bytecode.ClassConstantPool;
+import org.apache.harmony.pack200.bytecode.ClassFileEntry;
import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
import org.apache.harmony.pack200.bytecode.EnclosingMethodAttribute;
import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
@@ -228,8 +234,8 @@
type = "I";
Object value = constantValueLayout.getValue(result, type,
cpBands.getConstantPool());
- fieldAttributes[i][j]
- .add(new ConstantValueAttribute(value));
+ fieldAttributes[i][j].add(new ConstantValueAttribute(
+ getClassFileEntry(value)));
constantValueIndex++;
}
if (signatureLayout.matches(flag)) {
@@ -238,7 +244,7 @@
String desc = fieldDescr[i][j];
int colon = desc.indexOf(':');
String type = desc.substring(colon + 1);
- CPUTF8 value = new CPUTF8((String) signatureLayout.getValue(result, type,
+ CPUTF8 value = cpBands.cpUTF8Value((String) signatureLayout.getValue(result, type,
cpBands.getConstantPool()), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
fieldAttributes[i][j]
.add(new SignatureAttribute(value));
@@ -256,6 +262,24 @@
}
}
+ private ClassFileEntry getClassFileEntry(Object value) {
+ ClassFileEntry entry = null;
+ if (value instanceof ClassFileEntry) {
+ entry = (ClassFileEntry)value;
+ } else if (value instanceof java.lang.Integer) {
+ entry = cpBands.cpIntegerValue((Integer) value);
+ } else if (value instanceof java.lang.Long) {
+ entry = cpBands.cpLongValue((Long) value);
+ } else if (value instanceof java.lang.Float) {
+ entry = cpBands.cpFloatValue((Float) value);
+ } else if (value instanceof java.lang.Double) {
+ entry = cpBands.cpDoubleValue((Double) value);
+ } else if (value instanceof java.lang.String) {
+ entry = cpBands.cpStringValue((String) value);
+ }
+ return entry;
+ }
+
private void parseMethodBands(InputStream in) throws IOException,
Pack200Exception {
methodDescr = parseReferences("method_descr", in, Codec.MDELTA5,
@@ -344,7 +368,7 @@
String[] exceptions = methodExceptionsRS[methodExceptionsIndex];
CPClass[] exceptionClasses = new CPClass[n];
for (int k = 0; k < n; k++) {
- exceptionClasses[k] = new CPClass(exceptions[k]);
+ exceptionClasses[k] = cpBands.cpClassValue(exceptions[k]);
}
methodAttributes[i][j].add(new ExceptionsAttribute(
exceptionClasses));
@@ -362,8 +386,8 @@
type = "I";
Object value = methodSignatureLayout.getValue(result, type, cpBands
.getConstantPool());
- methodAttributes[i][j]
- .add(new ConstantValueAttribute(value));
+ methodAttributes[i][j].add(new ConstantValueAttribute(
+ getClassFileEntry(value)));
methodSignatureIndex++;
}
// Non-predefined attributes
@@ -561,12 +585,12 @@
// Add .java to the end
value = className + ".java";
}
- classAttributes[i].add(new SourceFileAttribute(value));
+ classAttributes[i].add(new SourceFileAttribute(cpBands.cpUTF8Value(value, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ)));
sourceFileIndex++;
}
if (enclosingMethodLayout.matches(flag)) {
- CPClass theClass = new CPClass(enclosingMethodRC[enclosingMethodIndex]);
- CPNameAndType theMethod = new CPNameAndType(enclosingMethodRDN[enclosingMethodIndex]);
+ CPClass theClass = cpBands.cpClassValue(enclosingMethodRC[enclosingMethodIndex]);
+ CPNameAndType theMethod = cpBands.cpNameAndTypeValue(enclosingMethodRDN[enclosingMethodIndex]);
classAttributes[i].add(new EnclosingMethodAttribute(theClass, theMethod));
enclosingMethodIndex++;
}
@@ -574,7 +598,8 @@
long result = classSignature[signatureIndex];
Object value = signatureLayout.getValue(result, cpBands
.getConstantPool());
- classAttributes[i].add(new ConstantValueAttribute(value));
+ classAttributes[i].add(new ConstantValueAttribute(
+ getClassFileEntry(value)));
signatureIndex++;
}
if (innerClassLayout.matches(flag)) {
@@ -760,7 +785,7 @@
localVariableTableN);
int[][] localVariableTableSpanO = decodeBandInt(
"code_LocalVariableTable_span_O", in, Codec.BRANCH5,
- localVariableTableN);
+ localVariableTableN, false);
CPUTF8[][] localVariableTableNameRU = stringsToCPUTF8(parseReferences(
"code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
localVariableTableN, cpBands.getCpUTF8()));
@@ -887,7 +912,7 @@
for (int i = 0; i < strings.length; i++) {
cpUTF8s[i] = new CPUTF8[strings[i].length];
for (int j = 0; j < strings[i].length; j++) {
- cpUTF8s[i][j] = new CPUTF8(strings[i][j], ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ cpUTF8s[i][j] = cpBands.cpUTF8Value(strings[i][j], ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
}
return cpUTF8s;
@@ -898,7 +923,7 @@
private CPUTF8[] stringsToCPUTF8(String[] strings) {
CPUTF8[] cpUTF8s = new CPUTF8[strings.length];
for (int i = 0; i < strings.length; i++) {
- cpUTF8s[i] = new CPUTF8(strings[i], ClassConstantPool.DOMAIN_UNDEFINED);
+ cpUTF8s[i] = cpBands.cpUTF8Value(strings[i], ClassConstantPool.DOMAIN_NORMALASCIIZ);
}
return cpUTF8s;
}
@@ -950,7 +975,7 @@
int[] backwardsCallCounts, String contextName) throws IOException, Pack200Exception {
MetadataBandGroup[] mbg = new MetadataBandGroup[RxA.length];
for (int i = 0; i < RxA.length; i++) {
- mbg[i] = new MetadataBandGroup(RxA[i]);
+ mbg[i] = new MetadataBandGroup(RxA[i], cpBands);
String rxa = RxA[i];
if (rxa.indexOf("P") >= 0) {
mbg[i].param_NB = decodeBandInt(contextName + "_" + rxa
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java Tue Mar 4 00:02:13 2008
@@ -94,133 +94,162 @@
* canonical number. {@link CodecEncoding#canonicalCodec})
*/
public abstract class Codec {
- /**
- * BCI5 = (5,4): Used for storing branching information in bytecode.
- */
- public static final BHSDCodec BCI5 = new BHSDCodec(5, 4);
-
- /**
- * BRANCH5 = (5,4,2): Used for storing branching information in bytecode.
- */
- public static final BHSDCodec BRANCH5 = new BHSDCodec(5, 4, 2);
-
- /**
- * BYTE1 = (1,256): Used for storing plain bytes.
- */
- public static final BHSDCodec BYTE1 = new BHSDCodec(1, 256);
-
- /**
- * CHAR3 = (3,128): Used for storing text (UTF-8) strings. NB This isn't
- * quite the same as UTF-8, but has similar properties; ASCII characters
- * < 127 are stored in a single byte.
- */
- public static final BHSDCodec CHAR3 = new BHSDCodec(3, 128);
-
- /**
- * DELTA5 = (5,64,1,1): Used for the majority of numerical codings where
- * there is a correlated sequence of signed values.
- */
- public static final BHSDCodec DELTA5 = new BHSDCodec(5, 64, 1, 1);
-
- /**
- * MDELTA5 = (5,64,2,1): Used for the majority of numerical codings where
- * there is a correlated sequence of signed values, but where most of them
- * are expected to be non-negative.
- */
- public static final BHSDCodec MDELTA5 = new BHSDCodec(5, 64, 2, 1);
-
- /**
- * SIGNED5 = (5,64,1): Used for small signed values.
- */
- public static final BHSDCodec SIGNED5 = new BHSDCodec(5, 64, 1);
-
- /**
- * UDELTA5 = (5,64,0,1): Used for the majority of numerical codings where
- * there is a correlated sequence of unsigned values.
- */
- public static final BHSDCodec UDELTA5 = new BHSDCodec(5, 64, 0, 1);
-
- /**
- * UNSIGNED5 = (5,64): Used for small unsigned values.
- */
- public static final BHSDCodec UNSIGNED5 = new BHSDCodec(5, 64);
-
- /**
- * Decode a sequence of bytes from the given input stream, returning the
- * value as a long. Note that this method can only be applied for non-delta
- * encodings.
- *
- * @param in
- * the input stream to read from
- * @return the value as a long
- * @throws IOException
- * if there is a problem reading from the underlying input
- * stream
- * @throws Pack200Exception
- * if the encoding is a delta encoding
- */
- public abstract long decode(InputStream in) throws IOException,
- Pack200Exception;
-
- /**
- * Decode a sequence of bytes from the given input stream, returning the
- * value as a long. If this encoding is a delta encoding (d=1) then the
- * previous value must be passed in as a parameter. If it is a non-delta
- * encoding, then it does not matter what value is passed in, so it makes
- * sense for the value to be passed in by default using code similar to:
- *
- * <pre>
- * long last = 0;
- * while (condition) {
- * last = codec.decode(in, last);
- * // do something with last
- * }
- * </pre>
- *
- * @param in
- * the input stream to read from
- * @param last
- * the previous value read, which must be supplied if the codec
- * is a delta encoding
- * @return the value as a long
- * @throws IOException
- * if there is a problem reading from the underlying input
- * stream
- * @throws Pack200Exception
- * if there is a problem decoding the value or that the value is
- * invalid
- */
- public abstract long decode(InputStream in, long last) throws IOException,
- Pack200Exception;
-
- /**
- * Decodes a sequence of <code>n</code> values from <code>in</code>.
- * This should probably be used in most cases, since some codecs
- * (such as @{link PopCodec}) only work when the number of values
- * to be read is known.
- *
- * @param n
- * the number of values to decode
- * @param in
- * the input stream to read from
- * @return an array of <code>long</code> values corresponding to values
- * decoded
- * @throws IOException
- * if there is a problem reading from the underlying input
- * stream
- * @throws Pack200Exception
- * if there is a problem decoding the value or that the value is
- * invalid
- */
- public long[] decode(int n, InputStream in) throws IOException,
- Pack200Exception {
- long result[] = new long[n];
- long last = 0;
- for(int i=0;i<n;i++) {
- result[i] = last = decode(in,last);
- }
- return result;
- }
+ /**
+ * BCI5 = (5,4): Used for storing branching information in bytecode.
+ */
+ public static final BHSDCodec BCI5 = new BHSDCodec(5, 4);
+
+ /**
+ * BRANCH5 = (5,4,2): Used for storing branching information in bytecode.
+ */
+ public static final BHSDCodec BRANCH5 = new BHSDCodec(5, 4, 2);
+
+ /**
+ * BYTE1 = (1,256): Used for storing plain bytes.
+ */
+ public static final BHSDCodec BYTE1 = new BHSDCodec(1, 256);
+
+ /**
+ * CHAR3 = (3,128): Used for storing text (UTF-8) strings. NB This isn't
+ * quite the same as UTF-8, but has similar properties; ASCII characters
+ * < 127 are stored in a single byte.
+ */
+ public static final BHSDCodec CHAR3 = new BHSDCodec(3, 128);
+
+ /**
+ * DELTA5 = (5,64,1,1): Used for the majority of numerical codings where
+ * there is a correlated sequence of signed values.
+ */
+ public static final BHSDCodec DELTA5 = new BHSDCodec(5, 64, 1, 1);
+
+ /**
+ * MDELTA5 = (5,64,2,1): Used for the majority of numerical codings where
+ * there is a correlated sequence of signed values, but where most of them
+ * are expected to be non-negative.
+ */
+ public static final BHSDCodec MDELTA5 = new BHSDCodec(5, 64, 2, 1);
+
+ /**
+ * SIGNED5 = (5,64,1): Used for small signed values.
+ */
+ public static final BHSDCodec SIGNED5 = new BHSDCodec(5, 64, 1);
+
+ /**
+ * UDELTA5 = (5,64,0,1): Used for the majority of numerical codings where
+ * there is a correlated sequence of unsigned values.
+ */
+ public static final BHSDCodec UDELTA5 = new BHSDCodec(5, 64, 0, 1);
+
+ /**
+ * UNSIGNED5 = (5,64): Used for small unsigned values.
+ */
+ public static final BHSDCodec UNSIGNED5 = new BHSDCodec(5, 64);
+
+ /**
+ * Decode a sequence of bytes from the given input stream, returning the
+ * value as a long. Note that this method can only be applied for non-delta
+ * encodings.
+ *
+ * @param in
+ * the input stream to read from
+ * @return the value as a long
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if the encoding is a delta encoding
+ */
+ public abstract long decode(InputStream in) throws IOException,
+ Pack200Exception;
+
+ /**
+ * Decode a sequence of bytes from the given input stream, returning the
+ * value as a long. If this encoding is a delta encoding (d=1) then the
+ * previous value must be passed in as a parameter. If it is a non-delta
+ * encoding, then it does not matter what value is passed in, so it makes
+ * sense for the value to be passed in by default using code similar to:
+ *
+ * <pre>
+ * long last = 0;
+ * while (condition) {
+ * last = codec.decode(in, last);
+ * // do something with last
+ * }
+ * </pre>
+ *
+ * @param in
+ * the input stream to read from
+ * @param last
+ * the previous value read, which must be supplied if the codec
+ * is a delta encoding
+ * @return the value as a long
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if there is a problem decoding the value or that the value is
+ * invalid
+ */
+ public abstract long decode(InputStream in, long last) throws IOException,
+ Pack200Exception;
+
+ /**
+ * Decodes a sequence of <code>n</code> values from <code>in</code>.
+ * This should probably be used in most cases, since some codecs
+ * (such as @{link PopCodec}) only work when the number of values
+ * to be read is known.
+ *
+ * @param n
+ * the number of values to decode
+ * @param in
+ * the input stream to read from
+ * @return an array of <code>long</code> values corresponding to values
+ * decoded
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if there is a problem decoding the value or that the value is
+ * invalid
+ */
+ public long[] decode(int n, InputStream in) throws IOException,
+ Pack200Exception {
+ long result[] = new long[n];
+ long last = 0;
+ for(int i=0;i<n;i++) {
+ result[i] = last = decode(in,last);
+ }
+ return result;
+ }
+
+ /**
+ * Decodes a sequence of <code>n</code> values from <code>in</code>.
+ * This should probably be used in most cases, since some codecs
+ * (such as @{link PopCodec}) only work when the number of values
+ * to be read is known.
+ *
+ * @param n
+ * the number of values to decode
+ * @param in
+ * the input stream to read from
+ * @return an array of <code>int</code> values corresponding to values
+ * decoded
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if there is a problem decoding the value or that the value is
+ * invalid
+ */
+ public int[] decodeInts(int n, InputStream in) throws IOException,
+ Pack200Exception {
+ int result[] = new int[n];
+ int last = 0;
+ for(int i=0;i<n;i++) {
+ result[i] = last = (int) decode(in,last);
+ }
+ return result;
+ }
/**
* Decodes a sequence of <code>n</code> values from <code>in</code>.
@@ -247,6 +276,35 @@
long last = firstValue;
for(int i=1;i<n+1;i++) {
result[i] = last = decode(in,last);
+ }
+ return result;
+ }
+
+ /**
+ * Decodes a sequence of <code>n</code> values from <code>in</code>.
+ *
+ * @param n
+ * the number of values to decode
+ * @param in
+ * the input stream to read from
+ * @param firstValue
+ * the first value in the band if it has already been read
+ * @return an array of <code>int</code> values corresponding to values
+ * decoded, with firstValue as the first value in the array.
+ * @throws IOException
+ * if there is a problem reading from the underlying input
+ * stream
+ * @throws Pack200Exception
+ * if there is a problem decoding the value or that the value is
+ * invalid
+ */
+ public int[] decodeInts(int n, InputStream in, int firstValue) throws IOException,
+ Pack200Exception {
+ int result[] = new int[n + 1];
+ result[0] = firstValue;
+ int last = firstValue;
+ for(int i=1;i<n+1;i++) {
+ result[i] = last = (int) decode(in,last);
}
return result;
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Tue Mar 4 00:02:13 2008
@@ -19,6 +19,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.harmony.pack200.bytecode.CPClass;
+import org.apache.harmony.pack200.bytecode.CPDouble;
+import org.apache.harmony.pack200.bytecode.CPFloat;
+import org.apache.harmony.pack200.bytecode.CPInteger;
+import org.apache.harmony.pack200.bytecode.CPLong;
+import org.apache.harmony.pack200.bytecode.CPNameAndType;
+import org.apache.harmony.pack200.bytecode.CPString;
+import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
public class CpBands extends BandSet {
@@ -26,39 +37,33 @@
return pool;
}
-
private final SegmentConstantPool pool = new SegmentConstantPool(this);
private String[] cpClass;
-
private String[] cpDescriptor;
-
private double[] cpDouble;
-
private String[] cpFieldClass;
-
private String[] cpFieldDescriptor;
-
private float[] cpFloat;
-
private String[] cpIMethodClass;
-
private String[] cpIMethodDescriptor;
-
private int[] cpInt;
-
private long[] cpLong;
-
private String[] cpMethodClass;
-
private String[] cpMethodDescriptor;
-
private String[] cpSignature;
-
private String[] cpString;
-
private String[] cpUTF8;
+ private HashMap[] stringsToCPUTF8 = new HashMap[ClassConstantPool.NUM_DOMAINS];
+ private HashMap stringsToCPStrings = new HashMap();
+ private HashMap longsToCPLongs = new HashMap();
+ private HashMap integersToCPIntegers = new HashMap();
+ private HashMap floatsToCPFloats = new HashMap();
+ private HashMap stringsToCPClass = new HashMap();
+ private HashMap doublesToCPDoubles = new HashMap();
+ private HashMap descriptorsToCPNameAndTypes = new HashMap();
+
public CpBands(Segment segment) {
super(segment);
@@ -419,4 +424,107 @@
return cpUTF8;
}
-}
+ public CPUTF8 cpUTF8Value(String string, int domain) {
+ if(stringsToCPUTF8[domain] == null) {
+ stringsToCPUTF8[domain] = new HashMap();
+ }
+ CPUTF8 cputf8 = (CPUTF8) stringsToCPUTF8[domain].get(string);
+ if(cputf8 == null) {
+ cputf8 = new CPUTF8(string, domain);
+ stringsToCPUTF8[domain].put(string, cputf8);
+ }
+ return cputf8;
+ }
+
+ public CPString cpStringValue(String string) {
+ CPString cpString = (CPString) stringsToCPStrings.get(string);
+ if(cpString == null) {
+ cpString = new CPString(cpUTF8Value(string, ClassConstantPool.DOMAIN_NORMALASCIIZ));
+ stringsToCPStrings.put(string, cpString);
+ }
+ return cpString;
+ }
+
+ public CPLong cpLongValue(Long l) {
+ CPLong cpLong = (CPLong) longsToCPLongs.get(l);
+ if(cpLong == null) {
+ cpLong = new CPLong(l);
+ longsToCPLongs.put(l, cpLong);
+ }
+ return cpLong;
+ }
+
+ public CPInteger cpIntegerValue(Integer i) {
+ CPInteger cpInteger = (CPInteger) integersToCPIntegers.get(i);
+ if(cpInteger == null) {
+ cpInteger = new CPInteger(i);
+ integersToCPIntegers.put(i, cpInteger);
+ }
+ return cpInteger;
+ }
+
+ public CPFloat cpFloatValue(Float f) {
+ CPFloat cpFloat = (CPFloat) floatsToCPFloats.get(f);
+ if(cpFloat == null) {
+ cpFloat = new CPFloat(f);
+ floatsToCPFloats.put(f, cpFloat);
+ }
+ return cpFloat;
+ }
+
+ public CPClass cpClassValue(String string) {
+ CPClass cpString = (CPClass) stringsToCPClass.get(string);
+ if(cpString == null) {
+ cpString = new CPClass(cpUTF8Value(string, ClassConstantPool.DOMAIN_NORMALASCIIZ));
+ stringsToCPClass.put(string, cpString);
+ }
+ return cpString;
+ }
+
+ public CPDouble cpDoubleValue(Double dbl) {
+ CPDouble cpDouble = (CPDouble) doublesToCPDoubles.get(dbl);
+ if(cpDouble == null) {
+ cpDouble = new CPDouble(dbl);
+ doublesToCPDoubles.put(dbl, cpDouble);
+ }
+ return cpDouble;
+ }
+
+ public CPNameAndType cpNameAndTypeValue(String descriptor) {
+ CPNameAndType cpNameAndType = (CPNameAndType) descriptorsToCPNameAndTypes.get(descriptor);
+ if(cpNameAndType == null) {
+ int descriptorDomain = ClassConstantPool.DOMAIN_UNDEFINED;
+ int colon = descriptor.indexOf(':');
+ String nameString = descriptor.substring(0,colon);
+ String descriptorString = descriptor.substring(colon+1);
+ // For some reason, descriptors which have just plain
+ // native types are stored in DOMAIN_NORMALASCIIZ rather
+ // than in DOMAIN_SIGNATUREASCIIZ. This might indicate
+ // that DOMAIN_SIGNATUREASCIIZ is poorly named.
+ boolean nativeDescriptor = true;
+ for(int index=0; index < descriptorString.length(); index++) {
+ char currentChar = descriptorString.charAt(index);
+ if(Character.isLetter(currentChar)) {
+ if(currentChar == 'L') {
+ nativeDescriptor = false;
+ }
+ break;
+ }
+ }
+ int domain = ClassConstantPool.DOMAIN_NAMEANDTYPE;
+ CPUTF8 name = cpUTF8Value(nameString, ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ if( nativeDescriptor ) {
+ // Native signatures are stored in DOMAIN_NORMALASCIIZ, not
+ // DOMAIN_SIGNATUREASCIIZ for some reason.
+ descriptorDomain = ClassConstantPool.DOMAIN_NORMALASCIIZ;
+ } else {
+ descriptorDomain = ClassConstantPool.DOMAIN_SIGNATUREASCIIZ;
+ }
+ CPUTF8 descriptorU = cpUTF8Value(descriptorString, descriptorDomain);
+ cpNameAndType = new CPNameAndType(name, descriptorU, domain);
+ descriptorsToCPNameAndTypes.put(descriptor, cpNameAndType);
+ }
+ return cpNameAndType;
+ }
+
+}
\ No newline at end of file
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java Tue Mar 4 00:02:13 2008
@@ -29,8 +29,6 @@
* Pack200 Inner Class Bands
*/
public class IcBands extends BandSet {
-
-
private IcTuple[] icAll;
private String[] cpUTF8;
@@ -92,14 +90,12 @@
List relevantTuples = new ArrayList();
IcTuple[] allTuples = getIcTuples();
int allTuplesSize = allTuples.length;
- SegmentUtils.debug("-------\nRelevant() " + className);
for(int index=0; index < allTuplesSize; index++) {
if(allTuples[index].outerClassString().equals(className)) {
relevantTuples.add(allTuples[index]);
}
}
- SegmentUtils.debug("self halt");
List classPoolClasses = cp.allClasses();
boolean changed = true;
// For every class in both ic_this_class and cp,
@@ -109,26 +105,12 @@
changed = false;
for(int allTupleIndex=0; allTupleIndex < allTuplesSize; allTupleIndex++) {
Iterator it = classPoolClasses.iterator();
- SegmentUtils.debug("\n\n----\nLooking through class pool for: " + allTuples[allTupleIndex].thisClassString());
while(it.hasNext()) {
CPClass classInPool = (CPClass)it.next();
String poolClassName = classInPool.name;
- SegmentUtils.debug(" " + poolClassName);
if(poolClassName.equals(allTuples[allTupleIndex].thisClassString())) {
// If the tuple isn't already in there, then add it
- SegmentUtils.debug(" -> match");
if(relevantTuples.indexOf(allTuples[allTupleIndex]) == -1) {
- SegmentUtils.debug(" -> added");
- relevantTuples.add(allTuples[allTupleIndex]);
- changed = true;
- }
- }
- // TODO: is this right?
- if(poolClassName.equals(allTuples[allTupleIndex].outerClassString())) {
- // If the tuple isn't already in there, then add it
- SegmentUtils.debug(" -> omatch");
- if(relevantTuples.indexOf(allTuples[allTupleIndex]) == -1) {
- SegmentUtils.debug(" -> oadded");
relevantTuples.add(allTuples[allTupleIndex]);
changed = true;
}
@@ -137,12 +119,21 @@
}
}
- IcTuple[] result = new IcTuple[relevantTuples.size()];
- for(int index=0; index < result.length; index++) {
- result[index] = (IcTuple)relevantTuples.get(index);
- SegmentUtils.debug("Returning relevantTuple: " + result[index].thisClassString());
+ // Now order the result as a subsequence of ic_all
+ IcTuple[] orderedRelevantTuples = new IcTuple[relevantTuples.size()];
+ int orderedRelevantIndex = 0;
+ for(int index=0; index < allTuplesSize; index++) {
+ if(relevantTuples.contains(allTuples[index])) {
+ orderedRelevantTuples[orderedRelevantIndex] = allTuples[index];
+ orderedRelevantIndex++;
+ }
+ }
+ if(orderedRelevantIndex != orderedRelevantTuples.length) {
+ // This should never happen. If it does, we have a
+ // logic error in the ordering code.
+ throw new Error("Missing a tuple when ordering them");
}
- return result;
+ return orderedRelevantTuples;
}
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/IcTuple.java Tue Mar 4 00:02:13 2008
@@ -102,7 +102,8 @@
if(predicted()) {
return C;
} else {
- // TODO: this may not be right.
+ // TODO: this may not be right. What if I
+ // get a class like Foo#Bar$Baz$Bug?
return C2 + "$" + N;
}
}
@@ -146,26 +147,15 @@
member = false;
}
if(index + 1 != lastPosition) {
+ // TODO: might need more logic to handle
+ // classes with separators of non-$ characters
+ // (ie Foo#Bar)
cachedOuterClassString += '$';
}
}
- // Now special-case: if the last part of the outer
- // class name is all digits, then the cachedOuterClassString
- // is null (an anonymous outer class). If the cachedInnerClassString
- // is all digits, then the cachedInnerClassString is null (an
- // anonymous inner class).
- // TODO: Don't know about this - we might need to
- // do this later on (after we've determined what's
- // anonymous and what isn't) so we point to the right
- // class file entries.
-// if(isAllDigits(nameComponents[lastPosition - 1])) {
-// cachedOuterClassString = null;
-// anonymous = false;
-// }
if(isAllDigits(cachedSimpleClassName)) {
anonymous = true;
member = false;
-// cachedSimpleClassName = C;
}
}
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java Tue Mar 4 00:02:13 2008
@@ -29,6 +29,7 @@
import org.apache.harmony.pack200.bytecode.CPLong;
import org.apache.harmony.pack200.bytecode.CPNameAndType;
import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleAnnotationsAttribute;
import org.apache.harmony.pack200.bytecode.RuntimeVisibleorInvisibleParameterAnnotationsAttribute;
import org.apache.harmony.pack200.bytecode.AnnotationsAttribute.Annotation;
@@ -41,9 +42,11 @@
public class MetadataBandGroup {
private String type;
+ private CpBands cpBands;
- public MetadataBandGroup(String type) {
+ public MetadataBandGroup(String type, CpBands cpBands) {
this.type = type;
+ this.cpBands = cpBands;
}
private List attributes;
@@ -148,9 +151,10 @@
annotations[i] = getAnnotation(types[i], pairCounts[i], namesIterator);
}
return new RuntimeVisibleorInvisibleAnnotationsAttribute(type
- .equals("RVA") ? "RuntimeVisibleAnnotations"
- : "RuntimeInvisibleAnnotations",
- annotations);
+ .equals("RVA") ? cpBands.cpUTF8Value("RuntimeVisibleAnnotations",
+ ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ) : cpBands.cpUTF8Value(
+ "RuntimeInvisibleAnnotations",
+ ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ), annotations);
}
private Attribute getParameterAttribute(int numParameters, Iterator namesIterator ) {
@@ -165,8 +169,11 @@
parameter_annotations[i] = new ParameterAnnotation(annotations);
}
return new RuntimeVisibleorInvisibleParameterAnnotationsAttribute(type
- .equals("RVA") ? "RuntimeVisibleParameterAnnotations"
- : "RuntimeInvisibleParameterAnnotations",
+ .equals("RVA") ? cpBands.cpUTF8Value(
+ "RuntimeVisibleParameterAnnotations",
+ ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ) : cpBands.cpUTF8Value(
+ "RuntimeInvisibleParameterAnnotations",
+ ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ),
parameter_annotations);
}
@@ -201,7 +208,7 @@
case 'e':
// TODO: check this - it may not work if the first string already has a colon in it
String enumString = caseet_Iterator.next() + ":" + caseec_Iterator.next();
- return new CPNameAndType(enumString);
+ return cpBands.cpNameAndTypeValue(enumString);
case 's':
return cases_Iterator.next();
case '[':
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/NewAttributeBands.java Tue Mar 4 00:02:13 2008
@@ -35,6 +35,7 @@
import org.apache.harmony.pack200.bytecode.CPNameAndType;
import org.apache.harmony.pack200.bytecode.CPString;
import org.apache.harmony.pack200.bytecode.CPUTF8;
+import org.apache.harmony.pack200.bytecode.ClassConstantPool;
import org.apache.harmony.pack200.bytecode.NewAttribute;
/**
@@ -102,7 +103,9 @@
* @return
*/
private Attribute getOneAttribute(int index, List elements) {
- NewAttribute attribute = new NewAttribute(attributeLayout.getName());
+ NewAttribute attribute = new NewAttribute(segment.getCpBands()
+ .cpUTF8Value(attributeLayout.getName(),
+ ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ));
for (Iterator iter = elements.iterator(); iter.hasNext();) {
AttributeLayoutElement element = (AttributeLayoutElement) iter.next();
element.addToAttribute(index, attribute);
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java Tue Mar 4 00:02:13 2008
@@ -20,77 +20,77 @@
import java.io.InputStream;
public class PopulationCodec extends Codec {
- private Codec favouredCodec;
- private Codec tokenCodec;
- private Codec unvafouredCodec;
- private int l;
+ private final Codec favouredCodec;
+ private Codec tokenCodec;
+ private final Codec unvafouredCodec;
+ private int l;
private long[] favoured;
- public PopulationCodec(Codec favouredCodec, Codec tableCodec, Codec unvafouredCodec) {
- this.favouredCodec = favouredCodec;
- this.tokenCodec = tableCodec;
- this.unvafouredCodec = unvafouredCodec;
- }
-
- public PopulationCodec(Codec favouredCodec, int l, Codec unvafouredCodec) {
- if (l >= 256 || l <=0)
- throw new IllegalArgumentException("L must be between 1..255");
- this.favouredCodec = favouredCodec;
- this.l = l;
- this.unvafouredCodec = unvafouredCodec;
- }
-
-
- public long decode(InputStream in) throws IOException, Pack200Exception {
- throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
- }
-
-
- public long decode(InputStream in, long last) throws IOException,
- Pack200Exception {
- throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
- }
-
-
- public long[] decode(int n, InputStream in) throws IOException, Pack200Exception {
- favoured = new long[n]; // there must be <= n values, but probably a lot less
- long result[];
- // read table of favorites first
- long smallest = Long.MAX_VALUE;
- long last = 0;
- long value = 0; // TODO Are these sensible starting points?
- int k = -1;
- while( true ) {
- last = value;
- value = favouredCodec.decode(in,last);
- if ( value == smallest || value == last)
- break;
- favoured[++k] = value;
- if (Math.abs(smallest) > Math.abs(value)) {
- smallest = value;
- } else if (Math.abs(smallest) == Math.abs(value) ) {
- // ensure that -X and +X -> +X
- smallest = Math.abs(smallest);
- }
- }
- // if tokenCodec needs to be derived from the T, L and K values
- if (tokenCodec == null) {
- if (k < 256) {
- tokenCodec = Codec.BYTE1;
- } else {
- // if k >= 256, b >= 2
- int b = 1;
- while(++b < 5 && tokenCodec == null) {
- BHSDCodec codec = new BHSDCodec(b,256-l,0);
- if (codec.encodes(k))
- tokenCodec = codec;
- }
- if (tokenCodec == null)
- throw new Pack200Exception("Cannot calculate token codec from " + k + " and " + l);
- }
- }
- // read favorites
- result = tokenCodec.decode(n, in);
+ public PopulationCodec(Codec favouredCodec, Codec tableCodec, Codec unvafouredCodec) {
+ this.favouredCodec = favouredCodec;
+ this.tokenCodec = tableCodec;
+ this.unvafouredCodec = unvafouredCodec;
+ }
+
+ public PopulationCodec(Codec favouredCodec, int l, Codec unvafouredCodec) {
+ if (l >= 256 || l <=0)
+ throw new IllegalArgumentException("L must be between 1..255");
+ this.favouredCodec = favouredCodec;
+ this.l = l;
+ this.unvafouredCodec = unvafouredCodec;
+ }
+
+
+ public long decode(InputStream in) throws IOException, Pack200Exception {
+ throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
+ }
+
+
+ public long decode(InputStream in, long last) throws IOException,
+ Pack200Exception {
+ throw new Pack200Exception("Population encoding does not work unless the number of elements are known");
+ }
+
+
+ public long[] decode(int n, InputStream in) throws IOException, Pack200Exception {
+ favoured = new long[n]; // there must be <= n values, but probably a lot less
+ long result[];
+ // read table of favorites first
+ long smallest = Long.MAX_VALUE;
+ long last = 0;
+ long value = 0; // TODO Are these sensible starting points?
+ int k = -1;
+ while( true ) {
+ last = value;
+ value = favouredCodec.decode(in,last);
+ if ( value == smallest || value == last)
+ break;
+ favoured[++k] = value;
+ if (Math.abs(smallest) > Math.abs(value)) {
+ smallest = value;
+ } else if (Math.abs(smallest) == Math.abs(value) ) {
+ // ensure that -X and +X -> +X
+ smallest = Math.abs(smallest);
+ }
+ }
+ // if tokenCodec needs to be derived from the T, L and K values
+ if (tokenCodec == null) {
+ if (k < 256) {
+ tokenCodec = Codec.BYTE1;
+ } else {
+ // if k >= 256, b >= 2
+ int b = 1;
+ while(++b < 5 && tokenCodec == null) {
+ BHSDCodec codec = new BHSDCodec(b,256-l,0);
+ if (codec.encodes(k))
+ tokenCodec = codec;
+ }
+ if (tokenCodec == null)
+ throw new Pack200Exception("Cannot calculate token codec from " + k + " and " + l);
+ }
+ }
+ // read favorites
+ result = tokenCodec.decode(n, in);
// read unfavorites
last = 0;
for(int i = 0; i < n; i++) {
@@ -101,7 +101,17 @@
result[i] = favoured[index-1];
}
}
- return result;
+ return result;
+ }
+
+
+ public int[] decodeInts(int n, InputStream in) throws IOException, Pack200Exception {
+ long[] result = decode(n, in);
+ int[] intRes = new int[result.length];
+ for (int i = 0; i < intRes.length; i++) {
+ intRes[i] = (int)result[i];
+ }
+ return intRes;
}
public long[] getFavoured() {
Modified: harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=633384&r1=633383&r2=633384&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Tue Mar 4 00:02:13 2008
@@ -21,6 +21,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.GZIPInputStream;
@@ -128,68 +131,98 @@
.getAttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE,
AttributeLayout.CONTEXT_CLASS);
if (SOURCE_FILE.matches(classBands.getClassFlags()[classNum])) {
- String fileName = fullName.substring(i) + ".java";
+ int firstDollar = SegmentUtils.indexOfFirstDollar(fullName);
+ String fileName = null;
+
+ if(firstDollar > -1 && (i <= firstDollar)) {
+ fileName = fullName.substring(i, firstDollar) + ".java";
+ } else {
+ fileName = fullName.substring(i) + ".java";
+ }
classFile.attributes = new Attribute[] { (Attribute) cp
- .add(new SourceFileAttribute(fileName)) };
+ .add(new SourceFileAttribute(cpBands.cpUTF8Value(fileName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ))) };
} else {
classFile.attributes = new Attribute[] {};
}
// this/superclass
- ClassFileEntry cfThis = cp.add(new CPClass(fullName));
- ClassFileEntry cfSuper = cp.add(new CPClass(classBands.getClassSuper()[classNum]));
+ ClassFileEntry cfThis = cp.add(cpBands.cpClassValue(fullName));
+ ClassFileEntry cfSuper = cp.add(cpBands.cpClassValue(classBands.getClassSuper()[classNum]));
// add interfaces
ClassFileEntry cfInterfaces[] = new ClassFileEntry[classBands.getClassInterfaces()[classNum].length];
for (i = 0; i < cfInterfaces.length; i++) {
- cfInterfaces[i] = cp.add(new CPClass(classBands.getClassInterfaces()[classNum][i]));
+ cfInterfaces[i] = cp.add(cpBands.cpClassValue(classBands.getClassInterfaces()[classNum][i]));
}
// add fields
ClassFileEntry cfFields[] = new ClassFileEntry[classBands.getClassFieldCount()[classNum]];
// fieldDescr and fieldFlags used to create this
for (i = 0; i < cfFields.length; i++) {
- cfFields[i] = cp.add(new CPField(classBands.getFieldDescr()[classNum][i],
+ String descriptorStr = classBands.getFieldDescr()[classNum][i];
+ int colon = descriptorStr.indexOf(':');
+ CPUTF8 name = cpBands.cpUTF8Value(descriptorStr.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ CPUTF8 descriptor = cpBands.cpUTF8Value(descriptorStr.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
+ cfFields[i] = cp.add(new CPField(name, descriptor,
classBands.getFieldFlags()[classNum][i], classBands.getFieldAttributes()[classNum][i]));
}
// add methods
ClassFileEntry cfMethods[] = new ClassFileEntry[classBands.getClassMethodCount()[classNum]];
// fieldDescr and fieldFlags used to create this
for (i = 0; i < cfMethods.length; i++) {
- cfMethods[i] = cp.add(new CPMethod(classBands.getMethodDescr()[classNum][i],
- classBands.getMethodFlags()[classNum][i], classBands.getMethodAttributes()[classNum][i]));
+ String descriptorStr = classBands.getMethodDescr()[classNum][i];
+ int colon = descriptorStr.indexOf(':');
+ CPUTF8 name = cpBands.cpUTF8Value(descriptorStr.substring(0,colon), ClassConstantPool.DOMAIN_NORMALASCIIZ);
+ CPUTF8 descriptor = cpBands.cpUTF8Value(descriptorStr.substring(colon+1), ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
+ cfMethods[i] = cp.add(new CPMethod(name, descriptor, classBands
+ .getMethodFlags()[classNum][i], classBands
+ .getMethodAttributes()[classNum][i]));
+ }
+
+ // add inner class attribute (if required)
+ boolean addInnerClassesAttr = false;
+ IcTuple[] ic_local = getClassBands().getIcLocal()[classNum];
+ boolean ic_local_sent = false;
+ if(ic_local != null) {
+ ic_local_sent = true;
}
- // TODO: maybe this is a better place to add ic_relevant?
- // This seems like the right thing to do.
- boolean addedClasses = false;
InnerClassesAttribute innerClassesAttribute = new InnerClassesAttribute("InnerClasses");
IcTuple[] ic_relevant = getIcBands().getRelevantIcTuples(fullName, cp);
-
- for(int index = 0; index < ic_relevant.length; index++) {
- String innerClassString = ic_relevant[index].thisClassString();
- String outerClassString = ic_relevant[index].outerClassString();
- String simpleClassName = ic_relevant[index].simpleClassName();
+ IcTuple[] ic_stored = computeIcStored(ic_local, ic_relevant);
+ for(int index = 0; index < ic_stored.length; index++) {
+ String innerClassString = ic_stored[index].thisClassString();
+ String outerClassString = ic_stored[index].outerClassString();
+ String simpleClassName = ic_stored[index].simpleClassName();
CPClass innerClass = null;
CPUTF8 innerName = null;
CPClass outerClass = null;
- if(ic_relevant[index].isAnonymous()) {
- innerClass = new CPClass(innerClassString);
+ if(ic_stored[index].isAnonymous()) {
+ innerClass = cpBands.cpClassValue(innerClassString);
} else {
- innerClass = new CPClass(innerClassString);
- innerName = new CPUTF8(simpleClassName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
+ innerClass = cpBands.cpClassValue(innerClassString);
+ innerName = cpBands.cpUTF8Value(simpleClassName, ClassConstantPool.DOMAIN_ATTRIBUTEASCIIZ);
}
- // TODO: I think we need to worry about if the
- // OUTER class is a member or not - not the
- // ic_relevant itself.
-// if(ic_relevant[index].isMember()) {
- outerClass = new CPClass(outerClassString);
-// }
+ if(ic_stored[index].isMember()) {
+ outerClass = cpBands.cpClassValue(outerClassString);
+ }
- int flags = ic_relevant[index].F;
+ int flags = ic_stored[index].F;
innerClassesAttribute.addInnerClassesEntry(innerClass, outerClass, innerName, flags);
- addedClasses = true;
+ addInnerClassesAttr = true;
+ }
+ // If ic_local is sent and it's empty, don't add
+ // the inner classes attribute.
+ if(ic_local_sent && (ic_local.length == 0)) {
+ addInnerClassesAttr = false;
}
- if(addedClasses) {
+
+ // If ic_local is not sent and ic_relevant is empty,
+ // don't add the inner class attribute.
+ if(!ic_local_sent && (ic_relevant.length == 0)) {
+ addInnerClassesAttr = false;
+ }
+
+ if(addInnerClassesAttr) {
// Need to add the InnerClasses attribute to the
// existing classFile attributes.
Attribute[] originalAttrs = classFile.attributes;
@@ -225,6 +258,54 @@
/**
+ * Given an ic_local and an ic_relevant, use them to
+ * calculate what should be added as ic_stored.
+ * @param ic_local IcTuple[] array of local transmitted tuples
+ * @param ic_relevant IcTuple[] array of relevant tuples
+ * @return IcTuple[] array of tuples to be stored. If ic_local
+ * is null or empty, the values returned may not be correct.
+ * The caller will have to determine if this is the case.
+ */
+ private IcTuple[] computeIcStored(IcTuple[] ic_local, IcTuple[] ic_relevant) {
+ List result = new ArrayList();
+ List resultCopy = new ArrayList();
+ List localList = new ArrayList();
+ List relevantList = new ArrayList();
+ if(ic_local != null) {
+ // If ic_local is null, this code doesn't get
+ // executed - which means the list ends up being
+ // ic_relevant.
+ for(int index=0; index < ic_local.length; index++) {
+ result.add(ic_local[index]);
+ resultCopy.add(ic_local[index]);
+ localList.add(ic_local[index]);
+ }
+ }
+ for(int index=0; index < ic_relevant.length; index++) {
+ result.add(ic_relevant[index]);
+ resultCopy.add(ic_relevant[index]);
+ relevantList.add(ic_relevant[index]);
+ }
+
+ // Since we're removing while iterating, iterate over
+ // a copy.
+ Iterator it = resultCopy.iterator();
+
+ while(it.hasNext()) {
+ IcTuple tuple = (IcTuple)it.next();
+ if(localList.contains(tuple) && relevantList.contains(tuple)) {
+ while(result.remove(tuple)) {};
+ }
+ }
+ IcTuple[] resultArray = new IcTuple[result.size()];
+ for(int index=0; index < resultArray.length; index++) {
+ resultArray[index] = (IcTuple)result.get(index);
+ }
+ return resultArray;
+ }
+
+
+ /**
* This performs the actual work of parsing against a non-static instance of
* Segment.
*
@@ -267,7 +348,7 @@
public void unpack(InputStream in, JarOutputStream out) throws IOException,
Pack200Exception {
if (!in.markSupported())
- in = new BufferedInputStream(in);
+ in = new BufferedInputStream(in);
parseSegment(in);
writeJar(out);
}
@@ -357,7 +438,6 @@
}
}
dos.flush();
- out.finish();
out.flush();
}