diff options
69 files changed, 530 insertions, 694 deletions
diff --git a/dx/src/com/android/dx/cf/attrib/AttSignature.java b/dx/src/com/android/dx/cf/attrib/AttSignature.java index f6023f3eb..52def9c8b 100644 --- a/dx/src/com/android/dx/cf/attrib/AttSignature.java +++ b/dx/src/com/android/dx/cf/attrib/AttSignature.java @@ -16,7 +16,7 @@ package com.android.dx.cf.attrib; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; /** * Attribute class for standards-track {@code Signature} attributes. @@ -26,14 +26,14 @@ public final class AttSignature extends BaseAttribute { public static final String ATTRIBUTE_NAME = "Signature"; /** {@code non-null;} the signature string */ - private final CstUtf8 signature; + private final CstString signature; /** * Constructs an instance. * * @param signature {@code non-null;} the signature string */ - public AttSignature(CstUtf8 signature) { + public AttSignature(CstString signature) { super(ATTRIBUTE_NAME); if (signature == null) { @@ -53,7 +53,7 @@ public final class AttSignature extends BaseAttribute { * * @return {@code non-null;} the signature string */ - public CstUtf8 getSignature() { + public CstString getSignature() { return signature; } } diff --git a/dx/src/com/android/dx/cf/attrib/AttSourceFile.java b/dx/src/com/android/dx/cf/attrib/AttSourceFile.java index b84ff4da8..cc19d2750 100644 --- a/dx/src/com/android/dx/cf/attrib/AttSourceFile.java +++ b/dx/src/com/android/dx/cf/attrib/AttSourceFile.java @@ -16,7 +16,7 @@ package com.android.dx.cf.attrib; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; /** * Attribute class for standard {@code SourceFile} attributes. @@ -26,14 +26,14 @@ public final class AttSourceFile extends BaseAttribute { public static final String ATTRIBUTE_NAME = "SourceFile"; /** {@code non-null;} name of the source file */ - private final CstUtf8 sourceFile; + private final CstString sourceFile; /** * Constructs an instance. * * @param sourceFile {@code non-null;} the name of the source file */ - public AttSourceFile(CstUtf8 sourceFile) { + public AttSourceFile(CstString sourceFile) { super(ATTRIBUTE_NAME); if (sourceFile == null) { @@ -53,7 +53,7 @@ public final class AttSourceFile extends BaseAttribute { * * @return {@code non-null;} the source file */ - public CstUtf8 getSourceFile() { + public CstString getSourceFile() { return sourceFile; } } diff --git a/dx/src/com/android/dx/cf/attrib/InnerClassList.java b/dx/src/com/android/dx/cf/attrib/InnerClassList.java index 96e1b60e2..830118c5a 100644 --- a/dx/src/com/android/dx/cf/attrib/InnerClassList.java +++ b/dx/src/com/android/dx/cf/attrib/InnerClassList.java @@ -16,8 +16,8 @@ package com.android.dx.cf.attrib; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.util.FixedSizeList; /** @@ -56,7 +56,7 @@ public final class InnerClassList extends FixedSizeList { * @param accessFlags original declared access flags */ public void set(int n, CstType innerClass, CstType outerClass, - CstUtf8 innerName, int accessFlags) { + CstString innerName, int accessFlags) { set0(n, new Item(innerClass, outerClass, innerName, accessFlags)); } @@ -71,7 +71,7 @@ public final class InnerClassList extends FixedSizeList { private final CstType outerClass; /** {@code null-ok;} original simple name of this class, if not anonymous */ - private final CstUtf8 innerName; + private final CstString innerName; /** original declared access flags */ private final int accessFlags; @@ -87,7 +87,7 @@ public final class InnerClassList extends FixedSizeList { * @param accessFlags original declared access flags */ public Item(CstType innerClass, CstType outerClass, - CstUtf8 innerName, int accessFlags) { + CstString innerName, int accessFlags) { if (innerClass == null) { throw new NullPointerException("innerClass == null"); } @@ -121,7 +121,7 @@ public final class InnerClassList extends FixedSizeList { * * @return {@code null-ok;} the name */ - public CstUtf8 getInnerName() { + public CstString getInnerName() { return innerName; } diff --git a/dx/src/com/android/dx/cf/code/BasicBlocker.java b/dx/src/com/android/dx/cf/code/BasicBlocker.java index 8fb9560f8..56d399111 100644 --- a/dx/src/com/android/dx/cf/code/BasicBlocker.java +++ b/dx/src/com/android/dx/cf/code/BasicBlocker.java @@ -18,8 +18,8 @@ package com.android.dx.cf.code; import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstMemberRef; -import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import com.android.dx.util.Bits; import com.android.dx.util.IntList; diff --git a/dx/src/com/android/dx/cf/code/ConcreteMethod.java b/dx/src/com/android/dx/cf/code/ConcreteMethod.java index 1e1bc21d0..39c23995e 100644 --- a/dx/src/com/android/dx/cf/code/ConcreteMethod.java +++ b/dx/src/com/android/dx/cf/code/ConcreteMethod.java @@ -20,15 +20,14 @@ import com.android.dx.cf.attrib.AttCode; import com.android.dx.cf.attrib.AttLineNumberTable; import com.android.dx.cf.attrib.AttLocalVariableTable; import com.android.dx.cf.attrib.AttLocalVariableTypeTable; -import com.android.dx.cf.attrib.AttSourceFile; import com.android.dx.cf.iface.AttributeList; import com.android.dx.cf.iface.ClassFile; import com.android.dx.cf.iface.Method; import com.android.dx.rop.code.AccessFlags; import com.android.dx.rop.code.SourcePosition; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.Prototype; /** @@ -45,7 +44,7 @@ public final class ConcreteMethod implements Method { * {@code null-ok;} the class's {@code SourceFile} attribute value, * if any */ - private final CstUtf8 sourceFile; + private final CstString sourceFile; /** * whether the class that this method is part of is defined with @@ -76,7 +75,7 @@ public final class ConcreteMethod implements Method { this(method, cf.getAccessFlags(), cf.getSourceFile(), keepLines, keepLocals); } - public ConcreteMethod(Method method, int accessFlags, CstUtf8 sourceFile, + public ConcreteMethod(Method method, int accessFlags, CstString sourceFile, boolean keepLines, boolean keepLocals) { this.method = method; this.accSuper = (accessFlags & AccessFlags.ACC_SUPER) != 0; @@ -151,12 +150,12 @@ public final class ConcreteMethod implements Method { } /** {@inheritDoc} */ - public CstUtf8 getName() { + public CstString getName() { return method.getName(); } /** {@inheritDoc} */ - public CstUtf8 getDescriptor() { + public CstString getDescriptor() { return method.getDescriptor(); } diff --git a/dx/src/com/android/dx/cf/code/LocalVariableList.java b/dx/src/com/android/dx/cf/code/LocalVariableList.java index dbf8ba2ad..2962698e5 100644 --- a/dx/src/com/android/dx/cf/code/LocalVariableList.java +++ b/dx/src/com/android/dx/cf/code/LocalVariableList.java @@ -16,7 +16,7 @@ package com.android.dx.cf.code; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import com.android.dx.rop.code.LocalItem; import com.android.dx.util.FixedSizeList; @@ -84,7 +84,7 @@ public final class LocalVariableList extends FixedSizeList { Item item = descriptorList.get(i); Item signatureItem = signatureList.itemToLocal(item); if (signatureItem != null) { - CstUtf8 signature = signatureItem.getSignature(); + CstString signature = signatureItem.getSignature(); item = item.withSignature(signature); } result.set(i, item); @@ -142,8 +142,8 @@ public final class LocalVariableList extends FixedSizeList { * @param signature {@code null-ok;} the variable's type signature * @param index {@code >= 0;} the variable's local index */ - public void set(int n, int startPc, int length, CstUtf8 name, - CstUtf8 descriptor, CstUtf8 signature, int index) { + public void set(int n, int startPc, int length, CstString name, + CstString descriptor, CstString signature, int index) { set0(n, new Item(startPc, length, name, descriptor, signature, index)); } @@ -207,13 +207,13 @@ public final class LocalVariableList extends FixedSizeList { private final int length; /** {@code non-null;} the variable's name */ - private final CstUtf8 name; + private final CstString name; /** {@code null-ok;} the variable's type descriptor */ - private final CstUtf8 descriptor; + private final CstString descriptor; /** {@code null-ok;} the variable's type signature */ - private final CstUtf8 signature; + private final CstString signature; /** {@code >= 0;} the variable's local index */ private final int index; @@ -232,8 +232,8 @@ public final class LocalVariableList extends FixedSizeList { * @param signature {@code null-ok;} the variable's type signature * @param index {@code >= 0;} the variable's local index */ - public Item(int startPc, int length, CstUtf8 name, - CstUtf8 descriptor, CstUtf8 signature, int index) { + public Item(int startPc, int length, CstString name, + CstString descriptor, CstString signature, int index) { if (startPc < 0) { throw new IllegalArgumentException("startPc < 0"); } @@ -286,7 +286,7 @@ public final class LocalVariableList extends FixedSizeList { * * @return {@code null-ok;} the variable's type descriptor */ - public CstUtf8 getDescriptor() { + public CstString getDescriptor() { return descriptor; } @@ -305,7 +305,7 @@ public final class LocalVariableList extends FixedSizeList { * * @return {@code null-ok;} the variable's type signature */ - private CstUtf8 getSignature() { + private CstString getSignature() { return signature; } @@ -335,7 +335,7 @@ public final class LocalVariableList extends FixedSizeList { * @param newSignature {@code non-null;} the new signature * @return {@code non-null;} an appropriately-constructed instance */ - public Item withSignature(CstUtf8 newSignature) { + public Item withSignature(CstString newSignature) { return new Item(startPc, length, name, descriptor, newSignature, index); } diff --git a/dx/src/com/android/dx/cf/code/RopperMachine.java b/dx/src/com/android/dx/cf/code/RopperMachine.java index 5da2588a2..f45bc1f42 100644 --- a/dx/src/com/android/dx/cf/code/RopperMachine.java +++ b/dx/src/com/android/dx/cf/code/RopperMachine.java @@ -35,8 +35,8 @@ import com.android.dx.rop.cst.CstFieldRef; import com.android.dx.rop.cst.CstInteger; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeBearer; import com.android.dx.rop.type.TypeList; @@ -58,8 +58,8 @@ import java.util.ArrayList; */ private static final CstMethodRef MULTIANEWARRAY_METHOD = new CstMethodRef(ARRAY_REFLECT_TYPE, - new CstNat(new CstUtf8("newInstance"), - new CstUtf8("(Ljava/lang/Class;[I)" + + new CstNat(new CstString("newInstance"), + new CstString("(Ljava/lang/Class;[I)" + "Ljava/lang/Object;"))); /** {@code non-null;} {@link Ropper} controlling this instance */ diff --git a/dx/src/com/android/dx/cf/code/Simulator.java b/dx/src/com/android/dx/cf/code/Simulator.java index eedc37990..c09783167 100644 --- a/dx/src/com/android/dx/cf/code/Simulator.java +++ b/dx/src/com/android/dx/cf/code/Simulator.java @@ -22,15 +22,11 @@ import com.android.dx.rop.cst.CstInteger; import com.android.dx.rop.cst.CstInterfaceMethodRef; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.Prototype; import com.android.dx.rop.type.Type; -import com.android.dx.rop.type.TypeBearer; import com.android.dx.rop.code.LocalItem; import com.android.dx.util.Hex; -import com.android.dx.util.IntList; -import java.util.List; import java.util.ArrayList; /** diff --git a/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java b/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java index 5eecfa648..7ec2fbac0 100644 --- a/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java +++ b/dx/src/com/android/dx/cf/cst/ConstantPoolParser.java @@ -16,6 +16,17 @@ package com.android.dx.cf.cst; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Class; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Double; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Fieldref; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Float; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Integer; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_InterfaceMethodref; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Long; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Methodref; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_NameAndType; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_String; +import static com.android.dx.cf.cst.ConstantTags.CONSTANT_Utf8; import com.android.dx.cf.iface.ParseException; import com.android.dx.cf.iface.ParseObserver; import com.android.dx.rop.cst.Constant; @@ -29,13 +40,11 @@ import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstNat; import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.cst.StdConstantPool; import com.android.dx.rop.type.Type; import com.android.dx.util.ByteArray; import com.android.dx.util.Hex; - -import static com.android.dx.cf.cst.ConstantTags.*; +import java.util.BitSet; /** * Parser for a constant pool embedded in a class file. @@ -126,10 +135,16 @@ public final class ConstantPoolParser { observer.changeIndent(1); } + /* + * Track the constant value's original string type. True if constants[i] was + * a CONSTANT_Utf8, false for any other type including CONSTANT_string. + */ + BitSet wasUtf8 = new BitSet(offsets.length); + for (int i = 1; i < offsets.length; i++) { int offset = offsets[i]; if ((offset != 0) && (pool.getOrNull(i) == null)) { - parse0(i); + parse0(i, wasUtf8); } } @@ -148,8 +163,10 @@ public final class ConstantPoolParser { break; } } - observer.parsed(bytes, offset, nextOffset - offset, - Hex.u2(i) + ": " + cst.toString()); + String human = wasUtf8.get(i) + ? Hex.u2(i) + ": utf8{\"" + cst.toHuman() + "\"}" + : Hex.u2(i) + ": " + cst.toString(); + observer.parsed(bytes, offset, nextOffset - offset, human); } observer.changeIndent(-1); @@ -217,7 +234,7 @@ public final class ConstantPoolParser { * @param idx which constant * @return {@code non-null;} the parsed constant */ - private Constant parse0(int idx) { + private Constant parse0(int idx, BitSet wasUtf8) { Constant cst = pool.getOrNull(idx); if (cst != null) { return cst; @@ -230,6 +247,7 @@ public final class ConstantPoolParser { switch (tag) { case CONSTANT_Utf8: { cst = parseUtf8(at); + wasUtf8.set(idx); break; } case CONSTANT_Integer: { @@ -254,45 +272,44 @@ public final class ConstantPoolParser { } case CONSTANT_Class: { int nameIndex = bytes.getUnsignedShort(at + 1); - CstUtf8 name = (CstUtf8) parse0(nameIndex); + CstString name = (CstString) parse0(nameIndex, wasUtf8); cst = new CstType(Type.internClassName(name.getString())); break; } case CONSTANT_String: { int stringIndex = bytes.getUnsignedShort(at + 1); - CstUtf8 string = (CstUtf8) parse0(stringIndex); - cst = new CstString(string); + cst = parse0(stringIndex, wasUtf8); break; } case CONSTANT_Fieldref: { int classIndex = bytes.getUnsignedShort(at + 1); - CstType type = (CstType) parse0(classIndex); + CstType type = (CstType) parse0(classIndex, wasUtf8); int natIndex = bytes.getUnsignedShort(at + 3); - CstNat nat = (CstNat) parse0(natIndex); + CstNat nat = (CstNat) parse0(natIndex, wasUtf8); cst = new CstFieldRef(type, nat); break; } case CONSTANT_Methodref: { int classIndex = bytes.getUnsignedShort(at + 1); - CstType type = (CstType) parse0(classIndex); + CstType type = (CstType) parse0(classIndex, wasUtf8); int natIndex = bytes.getUnsignedShort(at + 3); - CstNat nat = (CstNat) parse0(natIndex); + CstNat nat = (CstNat) parse0(natIndex, wasUtf8); cst = new CstMethodRef(type, nat); break; } case CONSTANT_InterfaceMethodref: { int classIndex = bytes.getUnsignedShort(at + 1); - CstType type = (CstType) parse0(classIndex); + CstType type = (CstType) parse0(classIndex, wasUtf8); int natIndex = bytes.getUnsignedShort(at + 3); - CstNat nat = (CstNat) parse0(natIndex); + CstNat nat = (CstNat) parse0(natIndex, wasUtf8); cst = new CstInterfaceMethodRef(type, nat); break; } case CONSTANT_NameAndType: { int nameIndex = bytes.getUnsignedShort(at + 1); - CstUtf8 name = (CstUtf8) parse0(nameIndex); + CstString name = (CstString) parse0(nameIndex, wasUtf8); int descriptorIndex = bytes.getUnsignedShort(at + 3); - CstUtf8 descriptor = (CstUtf8) parse0(descriptorIndex); + CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8); cst = new CstNat(name, descriptor); break; } @@ -318,7 +335,7 @@ public final class ConstantPoolParser { * @param at offset to the start of the constant (where the tag byte is) * @return {@code non-null;} the parsed value */ - private CstUtf8 parseUtf8(int at) { + private CstString parseUtf8(int at) { int length = bytes.getUnsignedShort(at + 1); at += 3; // Skip to the data. @@ -326,7 +343,7 @@ public final class ConstantPoolParser { ByteArray ubytes = bytes.slice(at, at + length); try { - return new CstUtf8(ubytes); + return new CstString(ubytes); } catch (IllegalArgumentException ex) { // Translate the exception throw new ParseException(ex); diff --git a/dx/src/com/android/dx/cf/direct/AnnotationParser.java b/dx/src/com/android/dx/cf/direct/AnnotationParser.java index ca38fc51d..fdbc99047 100644 --- a/dx/src/com/android/dx/cf/direct/AnnotationParser.java +++ b/dx/src/com/android/dx/cf/direct/AnnotationParser.java @@ -32,7 +32,6 @@ import com.android.dx.rop.cst.CstByte; import com.android.dx.rop.cst.CstChar; import com.android.dx.rop.cst.CstDouble; import com.android.dx.rop.cst.CstEnumRef; -import com.android.dx.rop.cst.CstFieldRef; import com.android.dx.rop.cst.CstFloat; import com.android.dx.rop.cst.CstInteger; import com.android.dx.rop.cst.CstLong; @@ -40,7 +39,6 @@ import com.android.dx.rop.cst.CstNat; import com.android.dx.rop.cst.CstShort; import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.Type; import com.android.dx.util.ByteArray; import com.android.dx.util.Hex; @@ -247,8 +245,8 @@ public final class AnnotationParser { int typeIndex = input.readUnsignedShort(); int numElements = input.readUnsignedShort(); - CstUtf8 typeUtf8 = (CstUtf8) pool.get(typeIndex); - CstType type = new CstType(Type.intern(typeUtf8.getString())); + CstString typeString = (CstString) pool.get(typeIndex); + CstType type = new CstType(Type.intern(typeString.getString())); if (observer != null) { parsed(2, "type: " + type.toHuman()); @@ -284,7 +282,7 @@ public final class AnnotationParser { requireLength(5); int elementNameIndex = input.readUnsignedShort(); - CstUtf8 elementName = (CstUtf8) pool.get(elementNameIndex); + CstString elementName = (CstString) pool.get(elementNameIndex); if (observer != null) { parsed(2, "element_name: " + elementName.toHuman()); @@ -310,7 +308,7 @@ public final class AnnotationParser { int tag = input.readUnsignedByte(); if (observer != null) { - CstUtf8 humanTag = new CstUtf8(Character.toString((char) tag)); + CstString humanTag = new CstString(Character.toString((char) tag)); parsed(1, "tag: " + humanTag.toQuoted()); } @@ -350,7 +348,7 @@ public final class AnnotationParser { } case 'c': { int classInfoIndex = input.readUnsignedShort(); - CstUtf8 value = (CstUtf8) pool.get(classInfoIndex); + CstString value = (CstString) pool.get(classInfoIndex); Type type = Type.internReturnType(value.getString()); if (observer != null) { @@ -360,16 +358,15 @@ public final class AnnotationParser { return new CstType(type); } case 's': { - CstString value = new CstString((CstUtf8) parseConstant()); - return value; + return parseConstant(); } case 'e': { requireLength(4); int typeNameIndex = input.readUnsignedShort(); int constNameIndex = input.readUnsignedShort(); - CstUtf8 typeName = (CstUtf8) pool.get(typeNameIndex); - CstUtf8 constName = (CstUtf8) pool.get(constNameIndex); + CstString typeName = (CstString) pool.get(typeNameIndex); + CstString constName = (CstString) pool.get(constNameIndex); if (observer != null) { parsed(2, "type_name: " + typeName.toHuman()); @@ -428,8 +425,8 @@ public final class AnnotationParser { Constant value = (Constant) pool.get(constValueIndex); if (observer != null) { - String human = (value instanceof CstUtf8) - ? ((CstUtf8) value).toQuoted() + String human = (value instanceof CstString) + ? ((CstString) value).toQuoted() : value.toHuman(); parsed(2, "constant_value: " + human); } diff --git a/dx/src/com/android/dx/cf/direct/AttributeFactory.java b/dx/src/com/android/dx/cf/direct/AttributeFactory.java index f98372c62..f7486eb9c 100644 --- a/dx/src/com/android/dx/cf/direct/AttributeFactory.java +++ b/dx/src/com/android/dx/cf/direct/AttributeFactory.java @@ -21,7 +21,7 @@ import com.android.dx.cf.iface.Attribute; import com.android.dx.cf.iface.ParseException; import com.android.dx.cf.iface.ParseObserver; import com.android.dx.rop.cst.ConstantPool; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.ByteArray; import com.android.dx.util.Hex; @@ -76,7 +76,7 @@ public class AttributeFactory { throw new IllegalArgumentException("bad context"); } - CstUtf8 name = null; + CstString name = null; try { ByteArray bytes = cf.getBytes(); @@ -84,7 +84,7 @@ public class AttributeFactory { int nameIdx = bytes.getUnsignedShort(offset); int length = bytes.getInt(offset + 2); - name = (CstUtf8) pool.get(nameIdx); + name = (CstString) pool.get(nameIdx); if (observer != null) { observer.parsed(bytes, offset, 2, diff --git a/dx/src/com/android/dx/cf/direct/DirectClassFile.java b/dx/src/com/android/dx/cf/direct/DirectClassFile.java index b194572d6..405f0e98a 100644 --- a/dx/src/com/android/dx/cf/direct/DirectClassFile.java +++ b/dx/src/com/android/dx/cf/direct/DirectClassFile.java @@ -29,7 +29,7 @@ import com.android.dx.cf.iface.StdAttributeList; import com.android.dx.rop.code.AccessFlags; import com.android.dx.rop.cst.ConstantPool; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.StdConstantPool; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.Type; @@ -300,7 +300,7 @@ public class DirectClassFile implements ClassFile { } /** {@inheritDoc} */ - public CstUtf8 getSourceFile() { + public CstString getSourceFile() { AttributeList attribs = getAttributes(); Attribute attSf = attribs.findFirst(AttSourceFile.ATTRIBUTE_NAME); diff --git a/dx/src/com/android/dx/cf/direct/MemberListParser.java b/dx/src/com/android/dx/cf/direct/MemberListParser.java index 91a5e1d3e..605bab896 100644 --- a/dx/src/com/android/dx/cf/direct/MemberListParser.java +++ b/dx/src/com/android/dx/cf/direct/MemberListParser.java @@ -23,8 +23,8 @@ import com.android.dx.cf.iface.ParseObserver; import com.android.dx.cf.iface.StdAttributeList; import com.android.dx.rop.cst.ConstantPool; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.util.ByteArray; import com.android.dx.util.Hex; @@ -187,8 +187,8 @@ abstract /*package*/ class MemberListParser { int accessFlags = bytes.getUnsignedShort(at); int nameIdx = bytes.getUnsignedShort(at + 2); int descIdx = bytes.getUnsignedShort(at + 4); - CstUtf8 name = (CstUtf8) pool.get(nameIdx); - CstUtf8 desc = (CstUtf8) pool.get(descIdx); + CstString name = (CstString) pool.get(nameIdx); + CstString desc = (CstString) pool.get(descIdx); if (observer != null) { observer.startParsingMember(bytes, at, name.getString(), diff --git a/dx/src/com/android/dx/cf/direct/StdAttributeFactory.java b/dx/src/com/android/dx/cf/direct/StdAttributeFactory.java index a6a97af33..ae04a1397 100644 --- a/dx/src/com/android/dx/cf/direct/StdAttributeFactory.java +++ b/dx/src/com/android/dx/cf/direct/StdAttributeFactory.java @@ -42,7 +42,6 @@ import com.android.dx.cf.iface.Attribute; import com.android.dx.cf.iface.ParseException; import com.android.dx.cf.iface.ParseObserver; import com.android.dx.cf.iface.StdAttributeList; -import com.android.dx.rop.annotation.Annotation; import com.android.dx.rop.annotation.AnnotationVisibility; import com.android.dx.rop.annotation.Annotations; import com.android.dx.rop.annotation.AnnotationsList; @@ -50,8 +49,8 @@ import com.android.dx.rop.code.AccessFlags; import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.ConstantPool; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.cst.TypedConstant; import com.android.dx.rop.type.TypeList; import com.android.dx.util.ByteArray; @@ -435,7 +434,7 @@ public class StdAttributeFactory int accessFlags = bytes.getUnsignedShort(offset + 6); CstType innerClass = (CstType) pool.get(innerClassIdx); CstType outerClass = (CstType) pool.get0Ok(outerClassIdx); - CstUtf8 name = (CstUtf8) pool.get0Ok(nameIdx); + CstString name = (CstString) pool.get0Ok(nameIdx); list.set(i, innerClass, outerClass, name, accessFlags); if (observer != null) { observer.parsed(bytes, offset, 2, @@ -574,10 +573,10 @@ public class StdAttributeFactory int nameIdx = in.readUnsignedShort(); int typeIdx = in.readUnsignedShort(); int index = in.readUnsignedShort(); - CstUtf8 name = (CstUtf8) pool.get(nameIdx); - CstUtf8 type = (CstUtf8) pool.get(typeIdx); - CstUtf8 descriptor = null; - CstUtf8 signature = null; + CstString name = (CstString) pool.get(nameIdx); + CstString type = (CstString) pool.get(typeIdx); + CstString descriptor = null; + CstString signature = null; if (typeTable) { signature = type; @@ -683,7 +682,7 @@ public class StdAttributeFactory ByteArray bytes = cf.getBytes(); ConstantPool pool = cf.getConstantPool(); int idx = bytes.getUnsignedShort(offset); - CstUtf8 cst = (CstUtf8) pool.get(idx); + CstString cst = (CstString) pool.get(idx); Attribute result = new AttSignature(cst); if (observer != null) { @@ -705,7 +704,7 @@ public class StdAttributeFactory ByteArray bytes = cf.getBytes(); ConstantPool pool = cf.getConstantPool(); int idx = bytes.getUnsignedShort(offset); - CstUtf8 cst = (CstUtf8) pool.get(idx); + CstString cst = (CstString) pool.get(idx); Attribute result = new AttSourceFile(cst); if (observer != null) { diff --git a/dx/src/com/android/dx/cf/iface/ClassFile.java b/dx/src/com/android/dx/cf/iface/ClassFile.java index 0f584ba65..cb5237a50 100644 --- a/dx/src/com/android/dx/cf/iface/ClassFile.java +++ b/dx/src/com/android/dx/cf/iface/ClassFile.java @@ -17,8 +17,8 @@ package com.android.dx.cf.iface; import com.android.dx.rop.cst.ConstantPool; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.TypeList; /** @@ -119,5 +119,5 @@ public interface ClassFile { * * @return {@code non-null;} the constant pool */ - public CstUtf8 getSourceFile(); + public CstString getSourceFile(); } diff --git a/dx/src/com/android/dx/cf/iface/Member.java b/dx/src/com/android/dx/cf/iface/Member.java index 0453a6f60..b346de447 100644 --- a/dx/src/com/android/dx/cf/iface/Member.java +++ b/dx/src/com/android/dx/cf/iface/Member.java @@ -17,8 +17,8 @@ package com.android.dx.cf.iface; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; /** * Interface representing members of class files (that is, fields and methods). @@ -44,7 +44,7 @@ public interface Member { * * @return {@code non-null;} the name */ - public CstUtf8 getName(); + public CstString getName(); /** * Get the field {@code descriptor_index} of the member. This is @@ -52,7 +52,7 @@ public interface Member { * * @return {@code non-null;} the descriptor */ - public CstUtf8 getDescriptor(); + public CstString getDescriptor(); /** * Get the name and type associated with this member. This is a diff --git a/dx/src/com/android/dx/cf/iface/StdMember.java b/dx/src/com/android/dx/cf/iface/StdMember.java index 9f15585d9..e67b216ec 100644 --- a/dx/src/com/android/dx/cf/iface/StdMember.java +++ b/dx/src/com/android/dx/cf/iface/StdMember.java @@ -17,8 +17,8 @@ package com.android.dx.cf.iface; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; /** * Standard implementation of {@link Member}, which directly stores @@ -94,12 +94,12 @@ public abstract class StdMember implements Member { } /** {@inheritDoc} */ - public final CstUtf8 getName() { + public final CstString getName() { return nat.getName(); } /** {@inheritDoc} */ - public final CstUtf8 getDescriptor() { + public final CstString getDescriptor() { return nat.getDescriptor(); } diff --git a/dx/src/com/android/dx/command/dexer/Main.java b/dx/src/com/android/dx/command/dexer/Main.java index e810bca08..bb6830d77 100644 --- a/dx/src/com/android/dx/command/dexer/Main.java +++ b/dx/src/com/android/dx/command/dexer/Main.java @@ -38,7 +38,7 @@ import com.android.dx.rop.annotation.Annotation; import com.android.dx.rop.annotation.Annotations; import com.android.dx.rop.annotation.AnnotationsList; import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.FileUtils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -829,7 +829,7 @@ public class Main { * The (default) source file is an attribute of the class, but * it's useful to see it in method dumps. */ - CstUtf8 sourceFile = clazz.getSourceFile(); + CstString sourceFile = clazz.getSourceFile(); if (sourceFile != null) { pw.println(" source file: " + sourceFile.toQuoted()); } diff --git a/dx/src/com/android/dx/dex/cf/AttributeTranslator.java b/dx/src/com/android/dx/dex/cf/AttributeTranslator.java index 2508a596a..8dc8b928d 100644 --- a/dx/src/com/android/dx/dex/cf/AttributeTranslator.java +++ b/dx/src/com/android/dx/dex/cf/AttributeTranslator.java @@ -27,7 +27,6 @@ import com.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations; import com.android.dx.cf.attrib.AttSignature; import com.android.dx.cf.attrib.InnerClassList; import com.android.dx.cf.direct.DirectClassFile; -import com.android.dx.cf.direct.StdAttributeFactory; import com.android.dx.cf.iface.AttributeList; import com.android.dx.cf.iface.Method; import com.android.dx.cf.iface.MethodList; @@ -41,7 +40,6 @@ import com.android.dx.rop.code.AccessFlags; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstNat; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeList; diff --git a/dx/src/com/android/dx/dex/cf/CfTranslator.java b/dx/src/com/android/dx/dex/cf/CfTranslator.java index 8bcfa3d89..8b94f9164 100644 --- a/dx/src/com/android/dx/dex/cf/CfTranslator.java +++ b/dx/src/com/android/dx/dex/cf/CfTranslator.java @@ -47,8 +47,8 @@ import com.android.dx.rop.cst.CstFieldRef; import com.android.dx.rop.cst.CstInteger; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstShort; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.cst.TypedConstant; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeList; @@ -118,7 +118,7 @@ public class CfTranslator { CstType thisClass = cf.getThisClass(); int classAccessFlags = cf.getAccessFlags() & ~AccessFlags.ACC_SUPER; - CstUtf8 sourceFile = (cfOptions.positionInfo == PositionList.NONE) ? null : + CstString sourceFile = (cfOptions.positionInfo == PositionList.NONE) ? null : cf.getSourceFile(); ClassDefItem out = new ClassDefItem(thisClass, classAccessFlags, diff --git a/dx/src/com/android/dx/dex/code/InsnFormat.java b/dx/src/com/android/dx/dex/code/InsnFormat.java index a86a00348..bf9f08e52 100644 --- a/dx/src/com/android/dx/dex/code/InsnFormat.java +++ b/dx/src/com/android/dx/dex/code/InsnFormat.java @@ -23,6 +23,7 @@ import com.android.dx.rop.cst.CstInteger; import com.android.dx.rop.cst.CstKnownNull; import com.android.dx.rop.cst.CstLiteral64; import com.android.dx.rop.cst.CstLiteralBits; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; @@ -336,7 +337,7 @@ public abstract class InsnFormat { CstInsn ci = (CstInsn) insn; Constant cst = ci.getConstant(); - return cst.toHuman(); + return cst instanceof CstString ? ((CstString) cst).toQuoted() : cst.toHuman(); } /** diff --git a/dx/src/com/android/dx/dex/code/LocalList.java b/dx/src/com/android/dx/dex/code/LocalList.java index 94ca66316..ab8343a1e 100644 --- a/dx/src/com/android/dx/dex/code/LocalList.java +++ b/dx/src/com/android/dx/dex/code/LocalList.java @@ -19,7 +19,7 @@ package com.android.dx.dex.code; import com.android.dx.rop.code.RegisterSpec; import com.android.dx.rop.code.RegisterSpecSet; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import com.android.dx.util.FixedSizeList; @@ -236,7 +236,7 @@ public final class LocalList extends FixedSizeList { * * @return {@code null-ok;} the variable name */ - public CstUtf8 getName() { + public CstString getName() { return spec.getLocalItem().getName(); } @@ -245,7 +245,7 @@ public final class LocalList extends FixedSizeList { * * @return {@code null-ok;} the variable signature */ - public CstUtf8 getSignature() { + public CstString getSignature() { return spec.getLocalItem().getSignature(); } diff --git a/dx/src/com/android/dx/dex/code/OutputFinisher.java b/dx/src/com/android/dx/dex/code/OutputFinisher.java index f28e0d3ba..ff0d75c2f 100644 --- a/dx/src/com/android/dx/dex/code/OutputFinisher.java +++ b/dx/src/com/android/dx/dex/code/OutputFinisher.java @@ -26,7 +26,7 @@ import com.android.dx.rop.code.SourcePosition; import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstMemberRef; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import java.util.ArrayList; @@ -196,8 +196,8 @@ public final class OutputFinisher { } LocalItem local = spec.getLocalItem(); - CstUtf8 name = local.getName(); - CstUtf8 signature = local.getSignature(); + CstString name = local.getName(); + CstString signature = local.getSignature(); Type type = spec.getType(); if (type != Type.KNOWN_NULL) { diff --git a/dx/src/com/android/dx/dex/code/RopToDop.java b/dx/src/com/android/dx/dex/code/RopToDop.java index 5292d3cd5..0330113b6 100644 --- a/dx/src/com/android/dx/dex/code/RopToDop.java +++ b/dx/src/com/android/dx/dex/code/RopToDop.java @@ -24,8 +24,8 @@ import com.android.dx.rop.code.ThrowingCstInsn; import com.android.dx.rop.code.RegisterSpec; import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstFieldRef; -import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import java.util.HashMap; diff --git a/dx/src/com/android/dx/dex/file/AnnotationItem.java b/dx/src/com/android/dx/dex/file/AnnotationItem.java index 1febd9e02..1d9224780 100644 --- a/dx/src/com/android/dx/dex/file/AnnotationItem.java +++ b/dx/src/com/android/dx/dex/file/AnnotationItem.java @@ -20,9 +20,7 @@ import com.android.dx.rop.annotation.Annotation; import com.android.dx.rop.annotation.AnnotationVisibility; import com.android.dx.rop.annotation.NameValuePair; import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstAnnotation; -import com.android.dx.rop.cst.CstArray; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.ByteArrayAnnotatedOutput; import com.android.dx.util.AnnotatedOutput; @@ -176,7 +174,7 @@ public final class AnnotationItem extends OffsettedItem { out.annotate(0, prefix + "type: " + annotation.getType().toHuman()); for (NameValuePair pair : annotation.getNameValuePairs()) { - CstUtf8 name = pair.getName(); + CstString name = pair.getName(); Constant value = pair.getValue(); out.annotate(0, prefix + name.toHuman() + ": " + diff --git a/dx/src/com/android/dx/dex/file/AnnotationUtils.java b/dx/src/com/android/dx/dex/file/AnnotationUtils.java index d500ec4a9..350ed9aea 100644 --- a/dx/src/com/android/dx/dex/file/AnnotationUtils.java +++ b/dx/src/com/android/dx/dex/file/AnnotationUtils.java @@ -26,7 +26,6 @@ import com.android.dx.rop.cst.CstKnownNull; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeList; @@ -67,13 +66,13 @@ public final class AnnotationUtils { CstType.intern(Type.intern("Ldalvik/annotation/Throws;")); /** {@code non-null;} the UTF-8 constant {@code "accessFlags"} */ - private static final CstUtf8 ACCESS_FLAGS_UTF = new CstUtf8("accessFlags"); + private static final CstString ACCESS_FLAGS_STRING = new CstString("accessFlags"); /** {@code non-null;} the UTF-8 constant {@code "name"} */ - private static final CstUtf8 NAME_UTF = new CstUtf8("name"); + private static final CstString NAME_STRING = new CstString("name"); /** {@code non-null;} the UTF-8 constant {@code "value"} */ - private static final CstUtf8 VALUE_UTF = new CstUtf8("value"); + private static final CstString VALUE_STRING = new CstString("value"); /** * This class is uninstantiable. @@ -91,7 +90,7 @@ public final class AnnotationUtils { public static Annotation makeAnnotationDefault(Annotation defaults) { Annotation result = new Annotation(ANNOTATION_DEFAULT_TYPE, SYSTEM); - result.put(new NameValuePair(VALUE_UTF, new CstAnnotation(defaults))); + result.put(new NameValuePair(VALUE_STRING, new CstAnnotation(defaults))); result.setImmutable(); return result; } @@ -105,7 +104,7 @@ public final class AnnotationUtils { public static Annotation makeEnclosingClass(CstType clazz) { Annotation result = new Annotation(ENCLOSING_CLASS_TYPE, SYSTEM); - result.put(new NameValuePair(VALUE_UTF, clazz)); + result.put(new NameValuePair(VALUE_STRING, clazz)); result.setImmutable(); return result; } @@ -119,7 +118,7 @@ public final class AnnotationUtils { public static Annotation makeEnclosingMethod(CstMethodRef method) { Annotation result = new Annotation(ENCLOSING_METHOD_TYPE, SYSTEM); - result.put(new NameValuePair(VALUE_UTF, method)); + result.put(new NameValuePair(VALUE_STRING, method)); result.setImmutable(); return result; } @@ -132,13 +131,12 @@ public final class AnnotationUtils { * @param accessFlags the original access flags * @return {@code non-null;} the annotation */ - public static Annotation makeInnerClass(CstUtf8 name, int accessFlags) { + public static Annotation makeInnerClass(CstString name, int accessFlags) { Annotation result = new Annotation(INNER_CLASS_TYPE, SYSTEM); - Constant nameCst = - (name != null) ? new CstString(name) : CstKnownNull.THE_ONE; + Constant nameCst = (name != null) ? name : CstKnownNull.THE_ONE; - result.put(new NameValuePair(NAME_UTF, nameCst)); - result.put(new NameValuePair(ACCESS_FLAGS_UTF, + result.put(new NameValuePair(NAME_STRING, nameCst)); + result.put(new NameValuePair(ACCESS_FLAGS_STRING, CstInteger.make(accessFlags))); result.setImmutable(); return result; @@ -153,7 +151,7 @@ public final class AnnotationUtils { public static Annotation makeMemberClasses(TypeList types) { CstArray array = makeCstArray(types); Annotation result = new Annotation(MEMBER_CLASSES_TYPE, SYSTEM); - result.put(new NameValuePair(VALUE_UTF, array)); + result.put(new NameValuePair(VALUE_STRING, array)); result.setImmutable(); return result; } @@ -164,7 +162,7 @@ public final class AnnotationUtils { * @param signature {@code non-null;} the signature string * @return {@code non-null;} the annotation */ - public static Annotation makeSignature(CstUtf8 signature) { + public static Annotation makeSignature(CstString signature) { Annotation result = new Annotation(SIGNATURE_TYPE, SYSTEM); /* @@ -215,7 +213,7 @@ public final class AnnotationUtils { list.setImmutable(); - result.put(new NameValuePair(VALUE_UTF, new CstArray(list))); + result.put(new NameValuePair(VALUE_STRING, new CstArray(list))); result.setImmutable(); return result; } @@ -229,7 +227,7 @@ public final class AnnotationUtils { public static Annotation makeThrows(TypeList types) { CstArray array = makeCstArray(types); Annotation result = new Annotation(THROWS_TYPE, SYSTEM); - result.put(new NameValuePair(VALUE_UTF, array)); + result.put(new NameValuePair(VALUE_STRING, array)); result.setImmutable(); return result; } diff --git a/dx/src/com/android/dx/dex/file/ClassDefItem.java b/dx/src/com/android/dx/dex/file/ClassDefItem.java index 4132fb98b..df3945af6 100644 --- a/dx/src/com/android/dx/dex/file/ClassDefItem.java +++ b/dx/src/com/android/dx/dex/file/ClassDefItem.java @@ -24,8 +24,8 @@ import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstArray; import com.android.dx.rop.cst.CstFieldRef; import com.android.dx.rop.cst.CstMethodRef; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.TypeList; import com.android.dx.util.AnnotatedOutput; @@ -59,7 +59,7 @@ public final class ClassDefItem extends IndexedItem { private TypeListItem interfaces; /** {@code null-ok;} source file name or {@code null} if unknown */ - private final CstUtf8 sourceFile; + private final CstString sourceFile; /** {@code non-null;} associated class data object */ private final ClassDataItem classData; @@ -86,7 +86,7 @@ public final class ClassDefItem extends IndexedItem { * {@code null} if unknown */ public ClassDefItem(CstType thisClass, int accessFlags, - CstType superclass, TypeList interfaces, CstUtf8 sourceFile) { + CstType superclass, TypeList interfaces, CstString sourceFile) { if (thisClass == null) { throw new NullPointerException("thisClass == null"); } @@ -264,7 +264,7 @@ public final class ClassDefItem extends IndexedItem { * * @return {@code null-ok;} the source file name or {@code null} if unknown */ - public CstUtf8 getSourceFile() { + public CstString getSourceFile() { return sourceFile; } diff --git a/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java b/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java index 781caec91..9fb484536 100644 --- a/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java +++ b/dx/src/com/android/dx/dex/file/DebugInfoDecoder.java @@ -21,7 +21,7 @@ import com.android.dx.dex.code.DalvInsnList; import com.android.dx.dex.code.LocalList; import com.android.dx.dex.code.PositionList; import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Prototype; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.Type; @@ -112,7 +112,7 @@ public class DebugInfoDecoder { int idx = -1; try { - idx = file.getStringIds().indexOf(new CstUtf8("this")); + idx = file.getStringIds().indexOf(new CstString("this")); } catch (IllegalArgumentException ex) { /* * Silently tolerate not finding "this". It just means that diff --git a/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java b/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java index d9d4ebcdc..ae87fc375 100644 --- a/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java +++ b/dx/src/com/android/dx/dex/file/DebugInfoEncoder.java @@ -22,7 +22,7 @@ import com.android.dx.rop.code.RegisterSpec; import com.android.dx.rop.code.SourcePosition; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Prototype; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.Type; @@ -470,7 +470,7 @@ public final class DebugInfoEncoder { continue; } - CstUtf8 signature = arg.getSignature(); + CstString signature = arg.getSignature(); if (signature != null) { emitLocalStartExtended(arg); @@ -576,7 +576,7 @@ public final class DebugInfoEncoder { sb.append(e.getRegister()); sb.append(' '); - CstUtf8 name = e.getName(); + CstString name = e.getName(); if (name == null) { sb.append("null"); } else { @@ -591,7 +591,7 @@ public final class DebugInfoEncoder { sb.append(type.toHuman()); } - CstUtf8 signature = e.getSignature(); + CstString signature = e.getSignature(); if (signature != null) { sb.append(' '); @@ -636,7 +636,7 @@ public final class DebugInfoEncoder { * @param string {@code null-ok;} string to emit * @throws IOException */ - private void emitStringIndex(CstUtf8 string) throws IOException { + private void emitStringIndex(CstString string) throws IOException { if ((string == null) || (file == null)) { output.writeUleb128(0); } else { diff --git a/dx/src/com/android/dx/dex/file/DebugInfoItem.java b/dx/src/com/android/dx/dex/file/DebugInfoItem.java index 6a41b18ea..09b27128e 100644 --- a/dx/src/com/android/dx/dex/file/DebugInfoItem.java +++ b/dx/src/com/android/dx/dex/file/DebugInfoItem.java @@ -21,8 +21,6 @@ import com.android.dx.dex.code.DalvInsnList; import com.android.dx.dex.code.LocalList; import com.android.dx.dex.code.PositionList; import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.ExceptionWithContext; diff --git a/dx/src/com/android/dx/dex/file/DexFile.java b/dx/src/com/android/dx/dex/file/DexFile.java index 73f08647a..dc004f471 100644 --- a/dx/src/com/android/dx/dex/file/DexFile.java +++ b/dx/src/com/android/dx/dex/file/DexFile.java @@ -22,7 +22,6 @@ import com.android.dx.rop.cst.CstEnumRef; import com.android.dx.rop.cst.CstFieldRef; import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.Type; import com.android.dx.util.ByteArrayAnnotatedOutput; import com.android.dx.util.ExceptionWithContext; @@ -430,8 +429,6 @@ public final class DexFile { /*package*/ void internIfAppropriate(Constant cst) { if (cst instanceof CstString) { stringIds.intern((CstString) cst); - } else if (cst instanceof CstUtf8) { - stringIds.intern((CstUtf8) cst); } else if (cst instanceof CstType) { typeIds.intern((CstType) cst); } else if (cst instanceof CstBaseMethodRef) { diff --git a/dx/src/com/android/dx/dex/file/EncodedArrayItem.java b/dx/src/com/android/dx/dex/file/EncodedArrayItem.java index 4d904e789..3d05ab3b6 100644 --- a/dx/src/com/android/dx/dex/file/EncodedArrayItem.java +++ b/dx/src/com/android/dx/dex/file/EncodedArrayItem.java @@ -16,19 +16,10 @@ package com.android.dx.dex.file; -import com.android.dx.rop.annotation.Annotation; -import com.android.dx.rop.annotation.AnnotationVisibility; -import com.android.dx.rop.annotation.NameValuePair; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstAnnotation; import com.android.dx.rop.cst.CstArray; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.util.ByteArrayAnnotatedOutput; import com.android.dx.util.AnnotatedOutput; -import java.util.Arrays; -import java.util.Comparator; - /** * Encoded array of constant values. */ diff --git a/dx/src/com/android/dx/dex/file/EncodedField.java b/dx/src/com/android/dx/dex/file/EncodedField.java index d9724791d..fdfa5d291 100644 --- a/dx/src/com/android/dx/dex/file/EncodedField.java +++ b/dx/src/com/android/dx/dex/file/EncodedField.java @@ -18,7 +18,7 @@ package com.android.dx.dex.file; import com.android.dx.rop.code.AccessFlags; import com.android.dx.rop.cst.CstFieldRef; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; import com.android.dx.util.Leb128Utils; @@ -103,7 +103,7 @@ public final class EncodedField extends EncodedMember /** {@inheritDoc} */ @Override - public CstUtf8 getName() { + public CstString getName() { return field.getNat().getName(); } diff --git a/dx/src/com/android/dx/dex/file/EncodedMember.java b/dx/src/com/android/dx/dex/file/EncodedMember.java index 509932531..627764697 100644 --- a/dx/src/com/android/dx/dex/file/EncodedMember.java +++ b/dx/src/com/android/dx/dex/file/EncodedMember.java @@ -16,7 +16,7 @@ package com.android.dx.dex.file; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.ToHuman; @@ -53,7 +53,7 @@ public abstract class EncodedMember implements ToHuman { * * @return {@code non-null;} the name */ - public abstract CstUtf8 getName(); + public abstract CstString getName(); /** * Does a human-friendly dump of this instance. diff --git a/dx/src/com/android/dx/dex/file/EncodedMethod.java b/dx/src/com/android/dx/dex/file/EncodedMethod.java index e707de48d..c3f71b7a4 100644 --- a/dx/src/com/android/dx/dex/file/EncodedMethod.java +++ b/dx/src/com/android/dx/dex/file/EncodedMethod.java @@ -19,7 +19,7 @@ package com.android.dx.dex.file; import com.android.dx.dex.code.DalvCode; import com.android.dx.rop.code.AccessFlags; import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.TypeList; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; @@ -131,7 +131,7 @@ public final class EncodedMethod extends EncodedMember /** {@inheritDoc} */ @Override - public final CstUtf8 getName() { + public final CstString getName() { return method.getNat().getName(); } diff --git a/dx/src/com/android/dx/dex/file/HeaderItem.java b/dx/src/com/android/dx/dex/file/HeaderItem.java index 98b938ded..d851ffde4 100644 --- a/dx/src/com/android/dx/dex/file/HeaderItem.java +++ b/dx/src/com/android/dx/dex/file/HeaderItem.java @@ -18,7 +18,7 @@ package com.android.dx.dex.file; import com.android.dx.dex.DexFormat; import com.android.dx.dex.SizeOf; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; @@ -62,7 +62,7 @@ public final class HeaderItem extends IndexedItem { lastDataSection.writeSize() - dataOff; if (out.annotates()) { - out.annotate(8, "magic: " + new CstUtf8(DexFormat.MAGIC).toQuoted()); + out.annotate(8, "magic: " + new CstString(DexFormat.MAGIC).toQuoted()); out.annotate(4, "checksum"); out.annotate(20, "signature"); out.annotate(4, "file_size: " + diff --git a/dx/src/com/android/dx/dex/file/ProtoIdItem.java b/dx/src/com/android/dx/dex/file/ProtoIdItem.java index ffb61670b..235a8c830 100644 --- a/dx/src/com/android/dx/dex/file/ProtoIdItem.java +++ b/dx/src/com/android/dx/dex/file/ProtoIdItem.java @@ -17,7 +17,7 @@ package com.android.dx.dex.file; import com.android.dx.dex.SizeOf; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Prototype; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.Type; @@ -32,7 +32,7 @@ public final class ProtoIdItem extends IndexedItem { private final Prototype prototype; /** {@code non-null;} the short-form of the prototype */ - private final CstUtf8 shortForm; + private final CstString shortForm; /** * {@code null-ok;} the list of parameter types or {@code null} if this @@ -64,7 +64,7 @@ public final class ProtoIdItem extends IndexedItem { * @param prototype {@code non-null;} the prototype * @return {@code non-null;} the short form */ - private static CstUtf8 makeShortForm(Prototype prototype) { + private static CstString makeShortForm(Prototype prototype) { StdTypeList parameters = prototype.getParameterTypes(); int size = parameters.size(); StringBuilder sb = new StringBuilder(size + 1); @@ -75,7 +75,7 @@ public final class ProtoIdItem extends IndexedItem { sb.append(shortFormCharFor(parameters.getType(i))); } - return new CstUtf8(sb.toString()); + return new CstString(sb.toString()); } /** diff --git a/dx/src/com/android/dx/dex/file/StringDataItem.java b/dx/src/com/android/dx/dex/file/StringDataItem.java index 3752cb283..e85a823bd 100644 --- a/dx/src/com/android/dx/dex/file/StringDataItem.java +++ b/dx/src/com/android/dx/dex/file/StringDataItem.java @@ -16,7 +16,7 @@ package com.android.dx.dex.file; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.ByteArray; import com.android.dx.util.Hex; @@ -27,14 +27,14 @@ import com.android.dx.util.Leb128Utils; */ public final class StringDataItem extends OffsettedItem { /** {@code non-null;} the string value */ - private final CstUtf8 value; + private final CstString value; /** * Constructs an instance. * * @param value {@code non-null;} the string value */ - public StringDataItem(CstUtf8 value) { + public StringDataItem(CstString value) { super(1, writeSize(value)); this.value = value; @@ -46,7 +46,7 @@ public final class StringDataItem extends OffsettedItem { * @param value {@code non-null;} the string value * @return {@code >= 2}; the write size, in bytes */ - private static int writeSize(CstUtf8 value) { + private static int writeSize(CstString value) { int utf16Size = value.getUtf16Size(); // The +1 is for the '\0' termination byte. diff --git a/dx/src/com/android/dx/dex/file/StringIdItem.java b/dx/src/com/android/dx/dex/file/StringIdItem.java index 8037df753..533427d5e 100644 --- a/dx/src/com/android/dx/dex/file/StringIdItem.java +++ b/dx/src/com/android/dx/dex/file/StringIdItem.java @@ -17,7 +17,7 @@ package com.android.dx.dex.file; import com.android.dx.dex.SizeOf; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; @@ -27,7 +27,7 @@ import com.android.dx.util.Hex; public final class StringIdItem extends IndexedItem implements Comparable { /** {@code non-null;} the string value */ - private final CstUtf8 value; + private final CstString value; /** {@code null-ok;} associated string data object, if known */ private StringDataItem data; @@ -37,7 +37,7 @@ public final class StringIdItem * * @param value {@code non-null;} the string value */ - public StringIdItem(CstUtf8 value) { + public StringIdItem(CstString value) { if (value == null) { throw new NullPointerException("value == null"); } @@ -110,7 +110,7 @@ public final class StringIdItem * * @return {@code non-null;} the value */ - public CstUtf8 getValue() { + public CstString getValue() { return value; } diff --git a/dx/src/com/android/dx/dex/file/StringIdsSection.java b/dx/src/com/android/dx/dex/file/StringIdsSection.java index 9039f434a..2f7c40b37 100644 --- a/dx/src/com/android/dx/dex/file/StringIdsSection.java +++ b/dx/src/com/android/dx/dex/file/StringIdsSection.java @@ -19,7 +19,6 @@ package com.android.dx.dex.file; import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstNat; import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; @@ -35,7 +34,7 @@ public final class StringIdsSection * {@code non-null;} map from string constants to {@link * StringIdItem} instances */ - private final TreeMap<CstUtf8, StringIdItem> strings; + private final TreeMap<CstString, StringIdItem> strings; /** * Constructs an instance. The file offset is initially unknown. @@ -45,7 +44,7 @@ public final class StringIdsSection public StringIdsSection(DexFile file) { super("string_ids", file, 4); - strings = new TreeMap<CstUtf8, StringIdItem>(); + strings = new TreeMap<CstString, StringIdItem>(); } /** {@inheritDoc} */ @@ -63,11 +62,7 @@ public final class StringIdsSection throwIfNotPrepared(); - if (cst instanceof CstString) { - cst = ((CstString) cst).getString(); - } - - IndexedItem result = strings.get((CstUtf8) cst); + IndexedItem result = strings.get((CstString) cst); if (result == null) { throw new IllegalArgumentException("not found"); @@ -104,19 +99,7 @@ public final class StringIdsSection * @return {@code non-null;} the interned string */ public StringIdItem intern(String string) { - CstUtf8 utf8 = new CstUtf8(string); - return intern(new StringIdItem(utf8)); - } - - /** - * Interns an element into this instance. - * - * @param string {@code non-null;} the string to intern, as a {@link CstString} - * @return {@code non-null;} the interned string - */ - public StringIdItem intern(CstString string) { - CstUtf8 utf8 = string.getString(); - return intern(new StringIdItem(utf8)); + return intern(new StringIdItem(new CstString(string))); } /** @@ -125,7 +108,7 @@ public final class StringIdsSection * @param string {@code non-null;} the string to intern, as a constant * @return {@code non-null;} the interned string */ - public StringIdItem intern(CstUtf8 string) { + public StringIdItem intern(CstString string) { return intern(new StringIdItem(string)); } @@ -142,7 +125,7 @@ public final class StringIdsSection throwIfPrepared(); - CstUtf8 value = string.getValue(); + CstString value = string.getValue(); StringIdItem already = strings.get(value); if (already != null) { @@ -170,7 +153,7 @@ public final class StringIdsSection * @param string {@code non-null;} the string to look up * @return {@code >= 0;} the string's index */ - public int indexOf(CstUtf8 string) { + public int indexOf(CstString string) { if (string == null) { throw new NullPointerException("string == null"); } @@ -186,17 +169,6 @@ public final class StringIdsSection return s.getIndex(); } - /** - * Gets the index of the given string, which must have been added - * to this instance. - * - * @param string {@code non-null;} the string to look up - * @return {@code >= 0;} the string's index - */ - public int indexOf(CstString string) { - return indexOf(string.getString()); - } - /** {@inheritDoc} */ @Override protected void orderItems() { diff --git a/dx/src/com/android/dx/dex/file/TypeIdItem.java b/dx/src/com/android/dx/dex/file/TypeIdItem.java index 6ace661f8..04be2a1a6 100644 --- a/dx/src/com/android/dx/dex/file/TypeIdItem.java +++ b/dx/src/com/android/dx/dex/file/TypeIdItem.java @@ -18,7 +18,7 @@ package com.android.dx.dex.file; import com.android.dx.dex.SizeOf; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; @@ -57,7 +57,7 @@ public final class TypeIdItem extends IdItem { @Override public void writeTo(DexFile file, AnnotatedOutput out) { CstType type = getDefiningClass(); - CstUtf8 descriptor = type.getDescriptor(); + CstString descriptor = type.getDescriptor(); int idx = file.getStringIds().indexOf(descriptor); if (out.annotates()) { diff --git a/dx/src/com/android/dx/dex/file/ValueEncoder.java b/dx/src/com/android/dx/dex/file/ValueEncoder.java index 7a608e075..9c433a3de 100644 --- a/dx/src/com/android/dx/dex/file/ValueEncoder.java +++ b/dx/src/com/android/dx/dex/file/ValueEncoder.java @@ -36,10 +36,8 @@ import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstShort; import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.util.AnnotatedOutput; import com.android.dx.util.Hex; - import java.util.Collection; /** @@ -332,7 +330,7 @@ public final class ValueEncoder { int at = 0; for (NameValuePair pair : pairs) { - CstUtf8 name = pair.getName(); + CstString name = pair.getName(); int nameIdx = stringIds.indexOf(name); Constant value = pair.getValue(); diff --git a/dx/src/com/android/dx/gen/DexGenerator.java b/dx/src/com/android/dx/gen/DexGenerator.java index 464133580..9445be84a 100644 --- a/dx/src/com/android/dx/gen/DexGenerator.java +++ b/dx/src/com/android/dx/gen/DexGenerator.java @@ -26,13 +26,11 @@ import com.android.dx.dex.file.DexFile; import com.android.dx.dex.file.EncodedField; import com.android.dx.dex.file.EncodedMethod; import com.android.dx.rop.code.AccessFlags; -import static com.android.dx.rop.code.AccessFlags.ACC_CONSTRUCTOR; -import static com.android.dx.rop.code.AccessFlags.ACC_PRIVATE; -import static com.android.dx.rop.code.AccessFlags.ACC_STATIC; +import static com.android.dx.rop.code.AccessFlags.*; import com.android.dx.rop.code.LocalVariableInfo; import com.android.dx.rop.code.RopMethod; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.type.StdTypeList; import java.io.File; import java.io.FileOutputStream; @@ -185,7 +183,7 @@ public final class DexGenerator { CstType thisType = type.constant; ClassDefItem out = new ClassDefItem(thisType, flags, supertype.constant, - interfaces.ropTypes, new CstUtf8(sourceFile)); + interfaces.ropTypes, new CstString(sourceFile)); for (MethodDeclaration method : methods.values()) { EncodedMethod encoded = method.toEncodedMethod(dexOptions); diff --git a/dx/src/com/android/dx/gen/FieldId.java b/dx/src/com/android/dx/gen/FieldId.java index 76dc15101..62ef73bdd 100644 --- a/dx/src/com/android/dx/gen/FieldId.java +++ b/dx/src/com/android/dx/gen/FieldId.java @@ -18,7 +18,7 @@ package com.android.dx.gen; import com.android.dx.rop.cst.CstFieldRef; import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; /** * A field. @@ -39,7 +39,7 @@ public final class FieldId<D, V> { this.declaringType = declaringType; this.type = type; this.name = name; - this.nat = new CstNat(new CstUtf8(name), new CstUtf8(type.name)); + this.nat = new CstNat(new CstString(name), new CstString(type.name)); this.constant = new CstFieldRef(declaringType.constant, nat); } diff --git a/dx/src/com/android/dx/gen/MethodId.java b/dx/src/com/android/dx/gen/MethodId.java index ecfae7825..29d088ab4 100644 --- a/dx/src/com/android/dx/gen/MethodId.java +++ b/dx/src/com/android/dx/gen/MethodId.java @@ -18,7 +18,7 @@ package com.android.dx.gen; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstNat; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Prototype; import java.util.List; @@ -43,7 +43,7 @@ public final class MethodId<D, R> { this.returnType = returnType; this.name = name; this.parameters = parameters; - this.nat = new CstNat(new CstUtf8(name), new CstUtf8(descriptor(false))); + this.nat = new CstNat(new CstString(name), new CstString(descriptor(false))); this.constant = new CstMethodRef(declaringType.constant, nat); } diff --git a/dx/src/com/android/dx/rop/annotation/Annotation.java b/dx/src/com/android/dx/rop/annotation/Annotation.java index ad6d67e77..8f9e9767e 100644 --- a/dx/src/com/android/dx/rop/annotation/Annotation.java +++ b/dx/src/com/android/dx/rop/annotation/Annotation.java @@ -16,16 +16,8 @@ package com.android.dx.rop.annotation; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstAnnotation; -import com.android.dx.rop.cst.CstFieldRef; -import com.android.dx.rop.cst.CstLiteralBits; -import com.android.dx.rop.cst.CstMethodRef; -import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; -import com.android.dx.rop.cst.TypedConstant; -import com.android.dx.util.Hex; import com.android.dx.util.MutabilityControl; import com.android.dx.util.ToHuman; @@ -48,7 +40,7 @@ public final class Annotation extends MutabilityControl private final AnnotationVisibility visibility; /** {@code non-null;} map from names to {@link NameValuePair} instances */ - private final TreeMap<CstUtf8, NameValuePair> elements; + private final TreeMap<CstString, NameValuePair> elements; /** * Construct an instance. It initially contains no elements. @@ -67,7 +59,7 @@ public final class Annotation extends MutabilityControl this.type = type; this.visibility = visibility; - this.elements = new TreeMap<CstUtf8, NameValuePair>(); + this.elements = new TreeMap<CstString, NameValuePair>(); } /** {@inheritDoc} */ @@ -211,7 +203,7 @@ public final class Annotation extends MutabilityControl throw new NullPointerException("pair == null"); } - CstUtf8 name = pair.getName(); + CstString name = pair.getName(); if (elements.get(name) != null) { throw new IllegalArgumentException("name already added: " + name); diff --git a/dx/src/com/android/dx/rop/annotation/NameValuePair.java b/dx/src/com/android/dx/rop/annotation/NameValuePair.java index 39a9dfd8f..56c49365e 100644 --- a/dx/src/com/android/dx/rop/annotation/NameValuePair.java +++ b/dx/src/com/android/dx/rop/annotation/NameValuePair.java @@ -18,14 +18,13 @@ package com.android.dx.rop.annotation; import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstString; -import com.android.dx.rop.cst.CstUtf8; /** * A (name, value) pair. These are used as the contents of an annotation. */ public final class NameValuePair implements Comparable<NameValuePair> { /** {@code non-null;} the name */ - private final CstUtf8 name; + private final CstString name; /** {@code non-null;} the value */ private final Constant value; @@ -36,7 +35,7 @@ public final class NameValuePair implements Comparable<NameValuePair> { * @param name {@code non-null;} the name * @param value {@code non-null;} the value */ - public NameValuePair(CstUtf8 name, Constant value) { + public NameValuePair(CstString name, Constant value) { if (name == null) { throw new NullPointerException("name == null"); } @@ -45,11 +44,6 @@ public final class NameValuePair implements Comparable<NameValuePair> { throw new NullPointerException("value == null"); } - // Reject CstUtf8 values. (They should be CstStrings.) - if (value instanceof CstUtf8) { - throw new IllegalArgumentException("bad value: " + value); - } - this.name = name; this.value = value; } @@ -97,7 +91,7 @@ public final class NameValuePair implements Comparable<NameValuePair> { * * @return {@code non-null;} the name */ - public CstUtf8 getName() { + public CstString getName() { return name; } diff --git a/dx/src/com/android/dx/rop/code/Insn.java b/dx/src/com/android/dx/rop/code/Insn.java index 7b79422f4..5031f8920 100644 --- a/dx/src/com/android/dx/rop/code/Insn.java +++ b/dx/src/com/android/dx/rop/code/Insn.java @@ -16,8 +16,6 @@ package com.android.dx.rop.code; -import com.android.dx.rop.cst.CstUtf8; -import com.android.dx.rop.cst.Constant; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeList; diff --git a/dx/src/com/android/dx/rop/code/LocalItem.java b/dx/src/com/android/dx/rop/code/LocalItem.java index 82b227cd9..d238f216b 100644 --- a/dx/src/com/android/dx/rop/code/LocalItem.java +++ b/dx/src/com/android/dx/rop/code/LocalItem.java @@ -16,17 +16,17 @@ package com.android.dx.rop.code; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; /** * A local variable item: either a name or a signature or both. */ public class LocalItem implements Comparable<LocalItem> { /** {@code null-ok;} local variable name */ - private final CstUtf8 name; + private final CstString name; /** {@code null-ok;} local variable signature */ - private final CstUtf8 signature; + private final CstString signature; /** * Make a new item. If both name and signature are null, null is returned. @@ -37,7 +37,7 @@ public class LocalItem implements Comparable<LocalItem> { * @param signature {@code null-ok;} local variable signature * @return {@code non-null;} appropriate instance. */ - public static LocalItem make(CstUtf8 name, CstUtf8 signature) { + public static LocalItem make(CstString name, CstString signature) { if (name == null && signature == null) { return null; } @@ -51,7 +51,7 @@ public class LocalItem implements Comparable<LocalItem> { * @param name {@code null-ok;} local variable name * @param signature {@code null-ok;} local variable signature */ - private LocalItem(CstUtf8 name, CstUtf8 signature) { + private LocalItem(CstString name, CstString signature) { this.name = name; this.signature = signature; } @@ -75,7 +75,7 @@ public class LocalItem implements Comparable<LocalItem> { * @return negative integer, zero, or positive integer in accordance * with Comparable.compareTo() */ - private static int compareHandlesNulls(CstUtf8 a, CstUtf8 b) { + private static int compareHandlesNulls(CstString a, CstString b) { if (a == b) { return 0; } else if (a == null) { @@ -128,7 +128,7 @@ public class LocalItem implements Comparable<LocalItem> { * * @return {@code null-ok;} name */ - public CstUtf8 getName() { + public CstString getName() { return name; } @@ -137,7 +137,7 @@ public class LocalItem implements Comparable<LocalItem> { * * @return {@code null-ok;} signature */ - public CstUtf8 getSignature() { + public CstString getSignature() { return signature; } } diff --git a/dx/src/com/android/dx/rop/code/RegisterSpec.java b/dx/src/com/android/dx/rop/code/RegisterSpec.java index 0042cf299..e5f908b43 100644 --- a/dx/src/com/android/dx/rop/code/RegisterSpec.java +++ b/dx/src/com/android/dx/rop/code/RegisterSpec.java @@ -17,7 +17,7 @@ package com.android.dx.rop.code; import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeBearer; import com.android.dx.util.ToHuman; @@ -581,8 +581,10 @@ public final class RegisterSpec if (justType != type) { sb.append("="); - if (human && (type instanceof Constant)) { - sb.append(((Constant) type).toHuman()); + if (human && (type instanceof CstString)) { + sb.append(((CstString) type).toQuoted()); + } else if (human && (type instanceof Constant)) { + sb.append(type.toHuman()); } else { sb.append(type); } diff --git a/dx/src/com/android/dx/rop/code/RegisterSpecSet.java b/dx/src/com/android/dx/rop/code/RegisterSpecSet.java index d16a82a11..14ef778d1 100644 --- a/dx/src/com/android/dx/rop/code/RegisterSpecSet.java +++ b/dx/src/com/android/dx/rop/code/RegisterSpecSet.java @@ -17,7 +17,6 @@ package com.android.dx.rop.code; import com.android.dx.util.MutabilityControl; -import com.android.dx.rop.cst.CstUtf8; /** * Set of {@link RegisterSpec} instances, where a given register number diff --git a/dx/src/com/android/dx/rop/code/SourcePosition.java b/dx/src/com/android/dx/rop/code/SourcePosition.java index f7a7961d7..11ac99250 100644 --- a/dx/src/com/android/dx/rop/code/SourcePosition.java +++ b/dx/src/com/android/dx/rop/code/SourcePosition.java @@ -16,7 +16,7 @@ package com.android.dx.rop.code; -import com.android.dx.rop.cst.CstUtf8; +import com.android.dx.rop.cst.CstString; import com.android.dx.util.Hex; /** @@ -29,7 +29,7 @@ public final class SourcePosition { new SourcePosition(null, -1, -1); /** {@code null-ok;} name of the file of origin or {@code null} if unknown */ - private final CstUtf8 sourceFile; + private final CstString sourceFile; /** * {@code >= -1;} the bytecode address, or {@code -1} if that @@ -53,7 +53,7 @@ public final class SourcePosition { * @param line {@code >= -1;} original line number or {@code -1} if * unknown */ - public SourcePosition(CstUtf8 sourceFile, int address, int line) { + public SourcePosition(CstString sourceFile, int address, int line) { if (address < -1) { throw new IllegalArgumentException("address < -1"); } @@ -143,7 +143,7 @@ public final class SourcePosition { * * @return {@code null-ok;} the source file or {@code null} if unknown */ - public CstUtf8 getSourceFile() { + public CstString getSourceFile() { return sourceFile; } diff --git a/dx/src/com/android/dx/rop/code/ThrowingCstInsn.java b/dx/src/com/android/dx/rop/code/ThrowingCstInsn.java index cdd21d12e..dee01b580 100644 --- a/dx/src/com/android/dx/rop/code/ThrowingCstInsn.java +++ b/dx/src/com/android/dx/rop/code/ThrowingCstInsn.java @@ -17,6 +17,7 @@ package com.android.dx.rop.code; import com.android.dx.rop.cst.Constant; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.type.Type; import com.android.dx.rop.type.TypeList; @@ -57,8 +58,12 @@ public final class ThrowingCstInsn /** {@inheritDoc} */ @Override public String getInlineString() { - return getConstant().toHuman() + " " + - ThrowingInsn.toCatchString(catches); + Constant cst = getConstant(); + String constantString = cst.toHuman(); + if (cst instanceof CstString) { + constantString = ((CstString) cst).toQuoted(); + } + return constantString + " " + ThrowingInsn.toCatchString(catches); } /** {@inheritDoc} */ diff --git a/dx/src/com/android/dx/rop/cst/CstArray.java b/dx/src/com/android/dx/rop/cst/CstArray.java index cb7d54de8..2766b5f1e 100644 --- a/dx/src/com/android/dx/rop/cst/CstArray.java +++ b/dx/src/com/android/dx/rop/cst/CstArray.java @@ -20,8 +20,7 @@ import com.android.dx.rop.type.Type; import com.android.dx.util.FixedSizeList; /** - * Constant type to represent a fixed array of other constants. The contents - * may be of any type <i>other</i> than {@link CstUtf8}. + * Constant type to represent a fixed array of other constants. */ public final class CstArray extends Constant { /** {@code non-null;} the actual list of contents */ @@ -154,10 +153,6 @@ public final class CstArray extends Constant { * @param a {@code null-ok;} the element to set at {@code n} */ public void set(int n, Constant a) { - if (a instanceof CstUtf8) { - throw new IllegalArgumentException("bad value: " + a); - } - set0(n, a); } } diff --git a/dx/src/com/android/dx/rop/cst/CstFieldRef.java b/dx/src/com/android/dx/rop/cst/CstFieldRef.java index 06f0b1501..a4d718031 100644 --- a/dx/src/com/android/dx/rop/cst/CstFieldRef.java +++ b/dx/src/com/android/dx/rop/cst/CstFieldRef.java @@ -72,8 +72,8 @@ public final class CstFieldRef extends CstMemberRef { } CstFieldRef otherField = (CstFieldRef) other; - CstUtf8 thisDescriptor = getNat().getDescriptor(); - CstUtf8 otherDescriptor = otherField.getNat().getDescriptor(); + CstString thisDescriptor = getNat().getDescriptor(); + CstString otherDescriptor = otherField.getNat().getDescriptor(); return thisDescriptor.compareTo(otherDescriptor); } } diff --git a/dx/src/com/android/dx/rop/cst/CstMemberRef.java b/dx/src/com/android/dx/rop/cst/CstMemberRef.java index 0791087cc..1775398ed 100644 --- a/dx/src/com/android/dx/rop/cst/CstMemberRef.java +++ b/dx/src/com/android/dx/rop/cst/CstMemberRef.java @@ -79,8 +79,8 @@ public abstract class CstMemberRef extends TypedConstant { return cmp; } - CstUtf8 thisName = nat.getName(); - CstUtf8 otherName = otherMember.nat.getName(); + CstString thisName = nat.getName(); + CstString otherName = otherMember.nat.getName(); return thisName.compareTo(otherName); } diff --git a/dx/src/com/android/dx/rop/cst/CstNat.java b/dx/src/com/android/dx/rop/cst/CstNat.java index 8a2c59141..cd067e9ef 100644 --- a/dx/src/com/android/dx/rop/cst/CstNat.java +++ b/dx/src/com/android/dx/rop/cst/CstNat.java @@ -28,14 +28,14 @@ public final class CstNat extends Constant { * wrapped primitives */ public static final CstNat PRIMITIVE_TYPE_NAT = - new CstNat(new CstUtf8("TYPE"), - new CstUtf8("Ljava/lang/Class;")); + new CstNat(new CstString("TYPE"), + new CstString("Ljava/lang/Class;")); /** {@code non-null;} the name */ - private final CstUtf8 name; + private final CstString name; /** {@code non-null;} the descriptor (type) */ - private final CstUtf8 descriptor; + private final CstString descriptor; /** * Constructs an instance. @@ -43,7 +43,7 @@ public final class CstNat extends Constant { * @param name {@code non-null;} the name * @param descriptor {@code non-null;} the descriptor */ - public CstNat(CstUtf8 name, CstUtf8 descriptor) { + public CstNat(CstString name, CstString descriptor) { if (name == null) { throw new NullPointerException("name == null"); } @@ -110,7 +110,7 @@ public final class CstNat extends Constant { * * @return {@code non-null;} the name */ - public CstUtf8 getName() { + public CstString getName() { return name; } @@ -119,7 +119,7 @@ public final class CstNat extends Constant { * * @return {@code non-null;} the descriptor */ - public CstUtf8 getDescriptor() { + public CstString getDescriptor() { return descriptor; } diff --git a/dx/src/com/android/dx/rop/cst/CstString.java b/dx/src/com/android/dx/rop/cst/CstString.java index 7dbfa0231..a778e976d 100644 --- a/dx/src/com/android/dx/rop/cst/CstString.java +++ b/dx/src/com/android/dx/rop/cst/CstString.java @@ -17,35 +17,187 @@ package com.android.dx.rop.cst; import com.android.dx.rop.type.Type; +import com.android.dx.util.ByteArray; +import com.android.dx.util.Hex; /** - * Constants of type {@code CONSTANT_String_info}. + * Constants of type {@code CONSTANT_Utf8_info} or {@code CONSTANT_String_info}. */ -public final class CstString - extends TypedConstant { - /** {@code non-null;} the string value */ - private final CstUtf8 string; +public final class CstString extends TypedConstant { + /** + * {@code non-null;} instance representing {@code ""}, that is, the + * empty string + */ + public static final CstString EMPTY_STRING = new CstString(""); + + /** {@code non-null;} the UTF-8 value as a string */ + private final String string; + + /** {@code non-null;} the UTF-8 value as bytes */ + private final ByteArray bytes; + + /** + * Converts a string into its MUTF-8 form. MUTF-8 differs from normal UTF-8 + * in the handling of character '\0' and surrogate pairs. + * + * @param string {@code non-null;} the string to convert + * @return {@code non-null;} the UTF-8 bytes for it + */ + public static byte[] stringToUtf8Bytes(String string) { + int len = string.length(); + byte[] bytes = new byte[len * 3]; // Avoid having to reallocate. + int outAt = 0; + + for (int i = 0; i < len; i++) { + char c = string.charAt(i); + if ((c != 0) && (c < 0x80)) { + bytes[outAt] = (byte) c; + outAt++; + } else if (c < 0x800) { + bytes[outAt] = (byte) (((c >> 6) & 0x1f) | 0xc0); + bytes[outAt + 1] = (byte) ((c & 0x3f) | 0x80); + outAt += 2; + } else { + bytes[outAt] = (byte) (((c >> 12) & 0x0f) | 0xe0); + bytes[outAt + 1] = (byte) (((c >> 6) & 0x3f) | 0x80); + bytes[outAt + 2] = (byte) ((c & 0x3f) | 0x80); + outAt += 3; + } + } + + byte[] result = new byte[outAt]; + System.arraycopy(bytes, 0, result, 0, outAt); + return result; + } /** - * Constructs an instance. + * Converts an array of UTF-8 bytes into a string. * - * @param string {@code non-null;} the string value + * @param bytes {@code non-null;} the bytes to convert + * @return {@code non-null;} the converted string */ - public CstString(CstUtf8 string) { + public static String utf8BytesToString(ByteArray bytes) { + int length = bytes.size(); + char[] chars = new char[length]; // This is sized to avoid a realloc. + int outAt = 0; + + for (int at = 0; length > 0; /*at*/) { + int v0 = bytes.getUnsignedByte(at); + char out; + switch (v0 >> 4) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: { + // 0XXXXXXX -- single-byte encoding + length--; + if (v0 == 0) { + // A single zero byte is illegal. + return throwBadUtf8(v0, at); + } + out = (char) v0; + at++; + break; + } + case 0x0c: case 0x0d: { + // 110XXXXX -- two-byte encoding + length -= 2; + if (length < 0) { + return throwBadUtf8(v0, at); + } + int v1 = bytes.getUnsignedByte(at + 1); + if ((v1 & 0xc0) != 0x80) { + return throwBadUtf8(v1, at + 1); + } + int value = ((v0 & 0x1f) << 6) | (v1 & 0x3f); + if ((value != 0) && (value < 0x80)) { + /* + * This should have been represented with + * one-byte encoding. + */ + return throwBadUtf8(v1, at + 1); + } + out = (char) value; + at += 2; + break; + } + case 0x0e: { + // 1110XXXX -- three-byte encoding + length -= 3; + if (length < 0) { + return throwBadUtf8(v0, at); + } + int v1 = bytes.getUnsignedByte(at + 1); + if ((v1 & 0xc0) != 0x80) { + return throwBadUtf8(v1, at + 1); + } + int v2 = bytes.getUnsignedByte(at + 2); + if ((v1 & 0xc0) != 0x80) { + return throwBadUtf8(v2, at + 2); + } + int value = ((v0 & 0x0f) << 12) | ((v1 & 0x3f) << 6) | + (v2 & 0x3f); + if (value < 0x800) { + /* + * This should have been represented with one- or + * two-byte encoding. + */ + return throwBadUtf8(v2, at + 2); + } + out = (char) value; + at += 3; + break; + } + default: { + // 10XXXXXX, 1111XXXX -- illegal + return throwBadUtf8(v0, at); + } + } + chars[outAt] = out; + outAt++; + } + + return new String(chars, 0, outAt); + } + + /** + * Helper for {@link #utf8BytesToString}, which throws the right + * exception for a bogus utf-8 byte. + * + * @param value the byte value + * @param offset the file offset + * @return never + * @throws IllegalArgumentException always thrown + */ + private static String throwBadUtf8(int value, int offset) { + throw new IllegalArgumentException("bad utf-8 byte " + Hex.u1(value) + + " at offset " + Hex.u4(offset)); + } + + /** + * Constructs an instance from a {@code String}. + * + * @param string {@code non-null;} the UTF-8 value as a string + */ + public CstString(String string) { if (string == null) { throw new NullPointerException("string == null"); } - this.string = string; + this.string = string.intern(); + this.bytes = new ByteArray(stringToUtf8Bytes(string)); } /** - * Constructs an instance. + * Constructs an instance from some UTF-8 bytes. * - * @param string {@code non-null;} the string value + * @param bytes {@code non-null;} array of the UTF-8 bytes */ - public CstString(String string) { - this(new CstUtf8(string)); + public CstString(ByteArray bytes) { + if (bytes == null) { + throw new NullPointerException("bytes == null"); + } + + this.bytes = bytes; + this.string = utf8BytesToString(bytes).intern(); } /** {@inheritDoc} */ @@ -73,18 +225,13 @@ public final class CstString /** {@inheritDoc} */ @Override public String toString() { - return "string{" + toHuman() + '}'; - } - - /** {@inheritDoc} */ - public Type getType() { - return Type.STRING; + return "string{\"" + toHuman() + "\"}"; } /** {@inheritDoc} */ @Override public String typeName() { - return "string"; + return "utf8"; } /** {@inheritDoc} */ @@ -95,15 +242,134 @@ public final class CstString /** {@inheritDoc} */ public String toHuman() { - return string.toQuoted(); + int len = string.length(); + StringBuilder sb = new StringBuilder(len * 3 / 2); + + for (int i = 0; i < len; i++) { + char c = string.charAt(i); + if ((c >= ' ') && (c < 0x7f)) { + if ((c == '\'') || (c == '\"') || (c == '\\')) { + sb.append('\\'); + } + sb.append(c); + } else if (c <= 0x7f) { + switch (c) { + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + default: { + /* + * Represent the character as an octal escape. + * If the next character is a valid octal + * digit, disambiguate by using the + * three-digit form. + */ + char nextChar = + (i < (len - 1)) ? string.charAt(i + 1) : 0; + boolean displayZero = + (nextChar >= '0') && (nextChar <= '7'); + sb.append('\\'); + for (int shift = 6; shift >= 0; shift -= 3) { + char outChar = (char) (((c >> shift) & 7) + '0'); + if ((outChar != '0') || displayZero) { + sb.append(outChar); + displayZero = true; + } + } + if (! displayZero) { + // Ironic edge case: The original value was 0. + sb.append('0'); + } + break; + } + } + } else { + sb.append("\\u"); + sb.append(Character.forDigit(c >> 12, 16)); + sb.append(Character.forDigit((c >> 8) & 0x0f, 16)); + sb.append(Character.forDigit((c >> 4) & 0x0f, 16)); + sb.append(Character.forDigit(c & 0x0f, 16)); + } + } + + return sb.toString(); } /** - * Gets the string value. + * Gets the value as a human-oriented string, surrounded by double + * quotes. * - * @return {@code non-null;} the string value + * @return {@code non-null;} the quoted string */ - public CstUtf8 getString() { + public String toQuoted() { + return '\"' + toHuman() + '\"'; + } + + /** + * Gets the value as a human-oriented string, surrounded by double + * quotes, but ellipsizes the result if it is longer than the given + * maximum length + * + * @param maxLength {@code >= 5;} the maximum length of the string to return + * @return {@code non-null;} the quoted string + */ + public String toQuoted(int maxLength) { + String string = toHuman(); + int length = string.length(); + String ellipses; + + if (length <= (maxLength - 2)) { + ellipses = ""; + } else { + string = string.substring(0, maxLength - 5); + ellipses = "..."; + } + + return '\"' + string + ellipses + '\"'; + } + + /** + * Gets the UTF-8 value as a string. + * The returned string is always already interned. + * + * @return {@code non-null;} the UTF-8 value as a string + */ + public String getString() { return string; } + + /** + * Gets the UTF-8 value as UTF-8 encoded bytes. + * + * @return {@code non-null;} an array of the UTF-8 bytes + */ + public ByteArray getBytes() { + return bytes; + } + + /** + * Gets the size of this instance as UTF-8 code points. That is, + * get the number of bytes in the UTF-8 encoding of this instance. + * + * @return {@code >= 0;} the UTF-8 size + */ + public int getUtf8Size() { + return bytes.size(); + } + + /** + * Gets the size of this instance as UTF-16 code points. That is, + * get the number of 16-bit chars in the UTF-16 encoding of this + * instance. This is the same as the {@code length} of the + * Java {@code String} representation of this instance. + * + * @return {@code >= 0;} the UTF-16 size + */ + public int getUtf16Size() { + return string.length(); + } + + public Type getType() { + return Type.STRING; + } } diff --git a/dx/src/com/android/dx/rop/cst/CstType.java b/dx/src/com/android/dx/rop/cst/CstType.java index 077ad0637..8624028aa 100644 --- a/dx/src/com/android/dx/rop/cst/CstType.java +++ b/dx/src/com/android/dx/rop/cst/CstType.java @@ -89,7 +89,7 @@ public final class CstType extends TypedConstant { * {@code null-ok;} the type descriptor corresponding to this instance, if * calculated */ - private CstUtf8 descriptor; + private CstString descriptor; /** * Returns an instance of this class that represents the wrapper @@ -222,9 +222,9 @@ public final class CstType extends TypedConstant { * * @return {@code non-null;} the descriptor */ - public CstUtf8 getDescriptor() { + public CstString getDescriptor() { if (descriptor == null) { - descriptor = new CstUtf8(type.getDescriptor()); + descriptor = new CstString(type.getDescriptor()); } return descriptor; diff --git a/dx/src/com/android/dx/rop/cst/CstUtf8.java b/dx/src/com/android/dx/rop/cst/CstUtf8.java deleted file mode 100644 index 5cfc1f3fb..000000000 --- a/dx/src/com/android/dx/rop/cst/CstUtf8.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.rop.cst; - -import com.android.dx.util.ByteArray; -import com.android.dx.util.Hex; - -/** - * Constants of type {@code CONSTANT_Utf8_info}. - */ -public final class CstUtf8 extends Constant { - /** - * {@code non-null;} instance representing {@code ""}, that is, the - * empty string - */ - public static final CstUtf8 EMPTY_STRING = new CstUtf8(""); - - /** {@code non-null;} the UTF-8 value as a string */ - private final String string; - - /** {@code non-null;} the UTF-8 value as bytes */ - private final ByteArray bytes; - - /** - * Converts a string into its Java-style UTF-8 form. Java-style UTF-8 - * differs from normal UTF-8 in the handling of character '\0' and - * surrogate pairs. - * - * @param string {@code non-null;} the string to convert - * @return {@code non-null;} the UTF-8 bytes for it - */ - public static byte[] stringToUtf8Bytes(String string) { - int len = string.length(); - byte[] bytes = new byte[len * 3]; // Avoid having to reallocate. - int outAt = 0; - - for (int i = 0; i < len; i++) { - char c = string.charAt(i); - if ((c != 0) && (c < 0x80)) { - bytes[outAt] = (byte) c; - outAt++; - } else if (c < 0x800) { - bytes[outAt] = (byte) (((c >> 6) & 0x1f) | 0xc0); - bytes[outAt + 1] = (byte) ((c & 0x3f) | 0x80); - outAt += 2; - } else { - bytes[outAt] = (byte) (((c >> 12) & 0x0f) | 0xe0); - bytes[outAt + 1] = (byte) (((c >> 6) & 0x3f) | 0x80); - bytes[outAt + 2] = (byte) ((c & 0x3f) | 0x80); - outAt += 3; - } - } - - byte[] result = new byte[outAt]; - System.arraycopy(bytes, 0, result, 0, outAt); - return result; - } - - /** - * Converts an array of UTF-8 bytes into a string. - * - * @param bytes {@code non-null;} the bytes to convert - * @return {@code non-null;} the converted string - */ - public static String utf8BytesToString(ByteArray bytes) { - int length = bytes.size(); - char[] chars = new char[length]; // This is sized to avoid a realloc. - int outAt = 0; - - for (int at = 0; length > 0; /*at*/) { - int v0 = bytes.getUnsignedByte(at); - char out; - switch (v0 >> 4) { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x04: case 0x05: case 0x06: case 0x07: { - // 0XXXXXXX -- single-byte encoding - length--; - if (v0 == 0) { - // A single zero byte is illegal. - return throwBadUtf8(v0, at); - } - out = (char) v0; - at++; - break; - } - case 0x0c: case 0x0d: { - // 110XXXXX -- two-byte encoding - length -= 2; - if (length < 0) { - return throwBadUtf8(v0, at); - } - int v1 = bytes.getUnsignedByte(at + 1); - if ((v1 & 0xc0) != 0x80) { - return throwBadUtf8(v1, at + 1); - } - int value = ((v0 & 0x1f) << 6) | (v1 & 0x3f); - if ((value != 0) && (value < 0x80)) { - /* - * This should have been represented with - * one-byte encoding. - */ - return throwBadUtf8(v1, at + 1); - } - out = (char) value; - at += 2; - break; - } - case 0x0e: { - // 1110XXXX -- three-byte encoding - length -= 3; - if (length < 0) { - return throwBadUtf8(v0, at); - } - int v1 = bytes.getUnsignedByte(at + 1); - if ((v1 & 0xc0) != 0x80) { - return throwBadUtf8(v1, at + 1); - } - int v2 = bytes.getUnsignedByte(at + 2); - if ((v1 & 0xc0) != 0x80) { - return throwBadUtf8(v2, at + 2); - } - int value = ((v0 & 0x0f) << 12) | ((v1 & 0x3f) << 6) | - (v2 & 0x3f); - if (value < 0x800) { - /* - * This should have been represented with one- or - * two-byte encoding. - */ - return throwBadUtf8(v2, at + 2); - } - out = (char) value; - at += 3; - break; - } - default: { - // 10XXXXXX, 1111XXXX -- illegal - return throwBadUtf8(v0, at); - } - } - chars[outAt] = out; - outAt++; - } - - return new String(chars, 0, outAt); - } - - /** - * Helper for {@link #utf8BytesToString}, which throws the right - * exception for a bogus utf-8 byte. - * - * @param value the byte value - * @param offset the file offset - * @return never - * @throws IllegalArgumentException always thrown - */ - private static String throwBadUtf8(int value, int offset) { - throw new IllegalArgumentException("bad utf-8 byte " + Hex.u1(value) + - " at offset " + Hex.u4(offset)); - } - - /** - * Constructs an instance from a {@code String}. - * - * @param string {@code non-null;} the UTF-8 value as a string - */ - public CstUtf8(String string) { - if (string == null) { - throw new NullPointerException("string == null"); - } - - this.string = string.intern(); - this.bytes = new ByteArray(stringToUtf8Bytes(string)); - } - - /** - * Constructs an instance from some UTF-8 bytes. - * - * @param bytes {@code non-null;} array of the UTF-8 bytes - */ - public CstUtf8(ByteArray bytes) { - if (bytes == null) { - throw new NullPointerException("bytes == null"); - } - - this.bytes = bytes; - this.string = utf8BytesToString(bytes).intern(); - } - - /** {@inheritDoc} */ - @Override - public boolean equals(Object other) { - if (!(other instanceof CstUtf8)) { - return false; - } - - return string.equals(((CstUtf8) other).string); - } - - /** {@inheritDoc} */ - @Override - public int hashCode() { - return string.hashCode(); - } - - /** {@inheritDoc} */ - @Override - protected int compareTo0(Constant other) { - return string.compareTo(((CstUtf8) other).string); - } - - /** {@inheritDoc} */ - @Override - public String toString() { - return "utf8{\"" + toHuman() + "\"}"; - } - - /** {@inheritDoc} */ - @Override - public String typeName() { - return "utf8"; - } - - /** {@inheritDoc} */ - @Override - public boolean isCategory2() { - return false; - } - - /** {@inheritDoc} */ - public String toHuman() { - int len = string.length(); - StringBuilder sb = new StringBuilder(len * 3 / 2); - - for (int i = 0; i < len; i++) { - char c = string.charAt(i); - if ((c >= ' ') && (c < 0x7f)) { - if ((c == '\'') || (c == '\"') || (c == '\\')) { - sb.append('\\'); - } - sb.append(c); - } else if (c <= 0x7f) { - switch (c) { - case '\n': sb.append("\\n"); break; - case '\r': sb.append("\\r"); break; - case '\t': sb.append("\\t"); break; - default: { - /* - * Represent the character as an octal escape. - * If the next character is a valid octal - * digit, disambiguate by using the - * three-digit form. - */ - char nextChar = - (i < (len - 1)) ? string.charAt(i + 1) : 0; - boolean displayZero = - (nextChar >= '0') && (nextChar <= '7'); - sb.append('\\'); - for (int shift = 6; shift >= 0; shift -= 3) { - char outChar = (char) (((c >> shift) & 7) + '0'); - if ((outChar != '0') || displayZero) { - sb.append(outChar); - displayZero = true; - } - } - if (! displayZero) { - // Ironic edge case: The original value was 0. - sb.append('0'); - } - break; - } - } - } else { - sb.append("\\u"); - sb.append(Character.forDigit(c >> 12, 16)); - sb.append(Character.forDigit((c >> 8) & 0x0f, 16)); - sb.append(Character.forDigit((c >> 4) & 0x0f, 16)); - sb.append(Character.forDigit(c & 0x0f, 16)); - } - } - - return sb.toString(); - } - - /** - * Gets the value as a human-oriented string, surrounded by double - * quotes. - * - * @return {@code non-null;} the quoted string - */ - public String toQuoted() { - return '\"' + toHuman() + '\"'; - } - - /** - * Gets the value as a human-oriented string, surrounded by double - * quotes, but ellipsizes the result if it is longer than the given - * maximum length - * - * @param maxLength {@code >= 5;} the maximum length of the string to return - * @return {@code non-null;} the quoted string - */ - public String toQuoted(int maxLength) { - String string = toHuman(); - int length = string.length(); - String ellipses; - - if (length <= (maxLength - 2)) { - ellipses = ""; - } else { - string = string.substring(0, maxLength - 5); - ellipses = "..."; - } - - return '\"' + string + ellipses + '\"'; - } - - /** - * Gets the UTF-8 value as a string. - * The returned string is always already interned. - * - * @return {@code non-null;} the UTF-8 value as a string - */ - public String getString() { - return string; - } - - /** - * Gets the UTF-8 value as UTF-8 encoded bytes. - * - * @return {@code non-null;} an array of the UTF-8 bytes - */ - public ByteArray getBytes() { - return bytes; - } - - /** - * Gets the size of this instance as UTF-8 code points. That is, - * get the number of bytes in the UTF-8 encoding of this instance. - * - * @return {@code >= 0;} the UTF-8 size - */ - public int getUtf8Size() { - return bytes.size(); - } - - /** - * Gets the size of this instance as UTF-16 code points. That is, - * get the number of 16-bit chars in the UTF-16 encoding of this - * instance. This is the same as the {@code length} of the - * Java {@code String} representation of this instance. - * - * @return {@code >= 0;} the UTF-16 size - */ - public int getUtf16Size() { - return string.length(); - } -} diff --git a/dx/src/com/android/dx/rop/cst/TypedConstant.java b/dx/src/com/android/dx/rop/cst/TypedConstant.java index c250c462f..1c738ee43 100644 --- a/dx/src/com/android/dx/rop/cst/TypedConstant.java +++ b/dx/src/com/android/dx/rop/cst/TypedConstant.java @@ -26,7 +26,7 @@ public abstract class TypedConstant /** * {@inheritDoc} * - * This implentation always returns {@code this}. + * This implementation always returns {@code this}. */ public final TypeBearer getFrameType() { return this; diff --git a/dx/src/com/android/dx/ssa/ConstCollector.java b/dx/src/com/android/dx/ssa/ConstCollector.java index cf6c019a4..62d629f89 100644 --- a/dx/src/com/android/dx/ssa/ConstCollector.java +++ b/dx/src/com/android/dx/ssa/ConstCollector.java @@ -31,7 +31,6 @@ import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.TypedConstant; import com.android.dx.rop.type.StdTypeList; import com.android.dx.rop.type.TypeBearer; - import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; diff --git a/dx/src/com/android/dx/ssa/EscapeAnalysis.java b/dx/src/com/android/dx/ssa/EscapeAnalysis.java index d2708570f..b02c9297f 100644 --- a/dx/src/com/android/dx/ssa/EscapeAnalysis.java +++ b/dx/src/com/android/dx/ssa/EscapeAnalysis.java @@ -32,8 +32,8 @@ import com.android.dx.rop.cst.Constant; import com.android.dx.rop.cst.CstLiteralBits; import com.android.dx.rop.cst.CstMethodRef; import com.android.dx.rop.cst.CstNat; +import com.android.dx.rop.cst.CstString; import com.android.dx.rop.cst.CstType; -import com.android.dx.rop.cst.CstUtf8; import com.android.dx.rop.cst.TypedConstant; import com.android.dx.rop.cst.Zeroes; import com.android.dx.rop.type.StdTypeList; @@ -754,7 +754,7 @@ public class EscapeAnalysis { SsaBasicBlock newBlock2 = newBlock.insertNewSuccessor(newBlock.getPrimarySuccessor()); SsaInsn newInsn2 = newBlock2.getInsns().get(0); - CstNat newNat = new CstNat(new CstUtf8("<init>"), new CstUtf8("(I)V")); + CstNat newNat = new CstNat(new CstString("<init>"), new CstString("(I)V")); CstMethodRef newRef = new CstMethodRef(exception, newNat); insertThrowingInsnBefore(newInsn2, RegisterSpecList.make(newReg, index), null, RegOps.INVOKE_DIRECT, newRef); diff --git a/dx/tests/010-class-attrib-InnerClasses/expected.txt b/dx/tests/010-class-attrib-InnerClasses/expected.txt index 590ed2eab..f58819001 100644 --- a/dx/tests/010-class-attrib-InnerClasses/expected.txt +++ b/dx/tests/010-class-attrib-InnerClasses/expected.txt @@ -32,7 +32,7 @@ attributes[0]: access_flags: public inner_class: type{Small} outer_class: (none) - name: utf8{"Small"} + name: string{"Small"} access_flags: private inner_class: type{Small} outer_class: type{Zorch} @@ -40,7 +40,7 @@ attributes[0]: access_flags: protected inner_class: type{Zorch} outer_class: type{Small} - name: utf8{"Zorch"} + name: string{"Zorch"} access_flags: public|private|protected|static|final|interface|abstract|synthetic|annotation|enum|89e0 end attributes[0] end classfile diff --git a/dx/tests/012-class-attrib-SourceFile/expected.txt b/dx/tests/012-class-attrib-SourceFile/expected.txt index c795cdeb8..e6079001a 100644 --- a/dx/tests/012-class-attrib-SourceFile/expected.txt +++ b/dx/tests/012-class-attrib-SourceFile/expected.txt @@ -24,6 +24,6 @@ attributes_count: 0001 attributes[0]: name: SourceFile length: 00000002 - source: utf8{"Blort.java"} + source: string{"Blort.java"} end attributes[0] end classfile diff --git a/dx/tests/025-class-attrib-Signature/expected.txt b/dx/tests/025-class-attrib-Signature/expected.txt index 5ff56ed58..e3f7233a2 100644 --- a/dx/tests/025-class-attrib-Signature/expected.txt +++ b/dx/tests/025-class-attrib-Signature/expected.txt @@ -24,6 +24,6 @@ attributes_count: 0001 attributes[0]: name: Signature length: 00000002 - signature: utf8{"LYo;"} + signature: string{"LYo;"} end attributes[0] end classfile diff --git a/dx/tests/026-field-attrib-Signature/expected.txt b/dx/tests/026-field-attrib-Signature/expected.txt index c2e840efb..228989a77 100644 --- a/dx/tests/026-field-attrib-Signature/expected.txt +++ b/dx/tests/026-field-attrib-Signature/expected.txt @@ -30,7 +30,7 @@ fields[0]: attributes[0]: name: Signature length: 00000002 - signature: utf8{"LYo;"} + signature: string{"LYo;"} end attributes[0] end fields[0] methods_count: 0000 diff --git a/dx/tests/027-method-attrib-Signature/expected.txt b/dx/tests/027-method-attrib-Signature/expected.txt index abc97c0e9..c3610e90d 100644 --- a/dx/tests/027-method-attrib-Signature/expected.txt +++ b/dx/tests/027-method-attrib-Signature/expected.txt @@ -31,7 +31,7 @@ methods[0]: attributes[0]: name: Signature length: 00000002 - signature: utf8{"LYo;"} + signature: string{"LYo;"} end attributes[0] end methods[0] attributes_count: 0000 diff --git a/dx/tests/108-string-annotation/expected.txt b/dx/tests/108-string-annotation/expected.txt index 57da807fe..a4c4af4da 100644 --- a/dx/tests/108-string-annotation/expected.txt +++ b/dx/tests/108-string-annotation/expected.txt @@ -1,12 +1,12 @@ elements[0]: name - value: string "grue" + value: utf8 grue elements[0]: names - value: array {"gruesome"} + value: array {gruesome} elements[0]: names - value: array {"awful", "awesome"} + value: array {awful, awesome} |