diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationDirectoryPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationDirectoryPool.java index d91972ed..9e98c146 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationDirectoryPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationDirectoryPool.java @@ -49,6 +49,7 @@ public class AnnotationDirectoryPool { @Nonnull private final Map nonInternedAnnotationDirectoryOffsetMap = Maps.newHashMap(); @Nonnull private final List nonInternedAnnotationDirectoryItems = Lists.newArrayList(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public AnnotationDirectoryPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -101,10 +102,24 @@ public class AnnotationDirectoryPool { return offset; } + public int getNumItems() { + return internedAnnotationDirectoryItems.size() + nonInternedAnnotationDirectoryItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { // we'll write out the interned items first List directoryItems = Lists.newArrayList(internedAnnotationDirectoryItems.keySet()); Collections.sort(directoryItems); + + writer.align(); + sectionOffset = writer.getPosition(); for (Key key: directoryItems) { writer.align(); internedAnnotationDirectoryItems.put(key, writer.getPosition()); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationPool.java index f8be27e6..7ff1ebd0 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationPool.java @@ -49,6 +49,7 @@ import java.util.SortedSet; public class AnnotationPool { @Nonnull private final Map internedAnnotations = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public AnnotationPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -73,10 +74,22 @@ public class AnnotationPool { return offset; } + public int getNumItems() { + return internedAnnotations.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List annotations = Lists.newArrayList(internedAnnotations.keySet()); Collections.sort(annotations); + sectionOffset = writer.getPosition(); for (Annotation annotation: annotations) { internedAnnotations.put(annotation, writer.getPosition()); writer.writeUbyte(annotation.getVisibility()); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetPool.java index 63f70f17..c4a5c0b5 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetPool.java @@ -47,6 +47,7 @@ import java.util.*; public class AnnotationSetPool { @Nonnull private final Map, Integer> internedAnnotationSetItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public AnnotationSetPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -74,11 +75,24 @@ public class AnnotationSetPool { return offset; } + public int getNumItems() { + return internedAnnotationSetItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List> annotationSets = Lists.newArrayList(internedAnnotationSetItems.keySet()); Collections.sort(annotationSets, CollectionUtils.listComparator(Ordering.natural())); + writer.align(); + sectionOffset = writer.getPosition(); for (Set annotationSet: annotationSets) { SortedSet sortedAnnotationSet = ImmutableSortedSet.copyOf(BaseAnnotation.BY_TYPE, annotationSet); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetRefPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetRefPool.java index 223e0f65..c4bd9b20 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetRefPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/AnnotationSetRefPool.java @@ -51,6 +51,7 @@ import java.util.*; public class AnnotationSetRefPool { @Nonnull private final Map internedAnnotationSetRefItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public AnnotationSetRefPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -75,11 +76,24 @@ public class AnnotationSetRefPool { return offset; } + public int getNumItems() { + return internedAnnotationSetRefItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List annotationSetRefs = Lists.newArrayList(internedAnnotationSetRefItems.keySet()); Collections.sort(annotationSetRefs); + writer.align(); + sectionOffset = writer.getPosition(); for (Key key: annotationSetRefs) { writer.align(); internedAnnotationSetRefItems.put(key, writer.getPosition()); @@ -127,7 +141,7 @@ public class AnnotationSetRefPool { } Iterator> otherAnnotationSets = getAnnotationSets().iterator(); for (Set annotationSet: getAnnotationSets()) { - if (!annotationSet.equals(otherAnnotationSets)) { + if (!annotationSet.equals(otherAnnotationSets.next())) { return false; } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DebugInfoPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DebugInfoPool.java index 307f92cc..daf296e0 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DebugInfoPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DebugInfoPool.java @@ -49,6 +49,7 @@ import java.util.Map; public class DebugInfoPool { @Nonnull private final Map debugInfoOffsetMap = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public DebugInfoPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -96,9 +97,22 @@ public class DebugInfoPool { return offset; } + public int getNumItems() { + return debugInfoOffsetMap.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List methods = Lists.newArrayList(debugInfoOffsetMap.keySet()); Collections.sort(methods); + + sectionOffset = writer.getPosition(); for (Method method: methods) { debugInfoOffsetMap.put(method, writer.getPosition()); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexFile.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexFile.java index ebde92d8..97cccebe 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/DexFile.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/DexFile.java @@ -60,6 +60,7 @@ public class DexFile { @Nonnull final DebugInfoPool debugInfoPool = new DebugInfoPool(this); @Nonnull final CodeItemPool codeItemPool = new CodeItemPool(this); @Nonnull final ClassDefPool classDefPool = new ClassDefPool(this); + @Nonnull final MapItem mapItem = new MapItem(this); @Nonnull private final Set classes; @@ -205,6 +206,7 @@ public class DexFile { debugInfoPool.write(offsetWriter); codeItemPool.write(offsetWriter); classDefPool.write(indexWriter, offsetWriter); + mapItem.write(offsetWriter); } finally { indexWriter.close(); offsetWriter.close(); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/EncodedArrayPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/EncodedArrayPool.java index faea4480..60afc609 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/EncodedArrayPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/EncodedArrayPool.java @@ -55,6 +55,7 @@ import java.util.*; public class EncodedArrayPool { @Nonnull private final Map internedEncodedArrayItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public EncodedArrayPool(DexFile dexFile) { this.dexFile = dexFile; @@ -84,10 +85,22 @@ public class EncodedArrayPool { return 0; } + public int getNumItems() { + return internedEncodedArrayItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List encodedArrays = Lists.newArrayList(internedEncodedArrayItems.keySet()); Collections.sort(encodedArrays); + sectionOffset = writer.getPosition(); for (Key encodedArray: encodedArrays) { internedEncodedArrayItems.put(encodedArray, writer.getPosition()); writer.writeUleb128(encodedArray.getElementCount()); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/FieldPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/FieldPool.java index 0bc449b1..116fa69e 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/FieldPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/FieldPool.java @@ -44,9 +44,11 @@ import java.util.List; import java.util.Map; public class FieldPool { - private final static int FIELD_ID_ITEM_SIZE = 8; + public final static int FIELD_ID_ITEM_SIZE = 0x08; + @Nonnull private final Map internedFieldIdItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public FieldPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -73,10 +75,22 @@ public class FieldPool { return internedFieldIdItems.size() * FIELD_ID_ITEM_SIZE; } + public int getNumItems() { + return internedFieldIdItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List fields = Lists.newArrayList(internedFieldIdItems.keySet()); Collections.sort(fields); + sectionOffset = writer.getPosition(); int index = 0; for (FieldReference field: fields) { internedFieldIdItems.put(field, index++); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/MapItem.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/MapItem.java new file mode 100644 index 00000000..c5abcd19 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/MapItem.java @@ -0,0 +1,149 @@ +/* + * Copyright 2012, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.writer; + +import org.jf.util.ExceptionWithContext; + +import javax.annotation.Nonnull; +import java.io.IOException; + +public class MapItem { + DexFile dexFile; + private int sectionOffset = -1; + + public MapItem(DexFile dexFile) { + this.dexFile = dexFile; + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + + public void write(@Nonnull DexWriter writer) throws IOException { + writer.align(); + sectionOffset = writer.getPosition(); + int numItems = calcNumItems(); + + writer.writeInt(numItems); + + // index section + writeItem(writer, DexItemType.HEADER_ITEM, 1, 0); + writeItem(writer, DexItemType.STRING_ID_ITEM, dexFile.stringPool.getNumItems(), dexFile.stringPool.getIndexSectionOffset()); + writeItem(writer, DexItemType.TYPE_ID_ITEM, dexFile.typePool.getNumItems(), dexFile.typePool.getSectionOffset()); + writeItem(writer, DexItemType.PROTO_ID_ITEM, dexFile.protoPool.getNumItems(), dexFile.protoPool.getSectionOffset()); + writeItem(writer, DexItemType.FIELD_ID_ITEM, dexFile.fieldPool.getNumItems(), dexFile.fieldPool.getSectionOffset()); + writeItem(writer, DexItemType.METHOD_ID_ITEM, dexFile.methodPool.getNumItems(), dexFile.methodPool.getSectionOffset()); + writeItem(writer, DexItemType.CLASS_DEF_ITEM, dexFile.classDefPool.getNumClassDefItems(), dexFile.classDefPool.getIndexSectionOffset()); + + // data section + writeItem(writer, DexItemType.STRING_DATA_ITEM, dexFile.stringPool.getNumItems(), dexFile.stringPool.getDataSectionOffset()); + writeItem(writer, DexItemType.TYPE_LIST, dexFile.typeListPool.getNumItems(), dexFile.typeListPool.getSectionOffset()); + writeItem(writer, DexItemType.ENCODED_ARRAY_ITEM, dexFile.encodedArrayPool.getNumItems(), dexFile.encodedArrayPool.getSectionOffset()); + writeItem(writer, DexItemType.ANNOTATION_ITEM, dexFile.annotationPool.getNumItems(), dexFile.annotationPool.getSectionOffset()); + writeItem(writer, DexItemType.ANNOTATION_SET_ITEM, dexFile.annotationSetPool.getNumItems(), dexFile.annotationSetPool.getSectionOffset()); + writeItem(writer, DexItemType.ANNOTATION_SET_REF_LIST, dexFile.annotationSetRefPool.getNumItems(), dexFile.annotationSetRefPool.getSectionOffset()); + writeItem(writer, DexItemType.ANNOTATION_DIRECTORY_ITEM, dexFile.annotationDirectoryPool.getNumItems(), dexFile.annotationDirectoryPool.getSectionOffset()); + writeItem(writer, DexItemType.DEBUG_INFO_ITEM, dexFile.debugInfoPool.getNumItems(), dexFile.debugInfoPool.getSectionOffset()); + writeItem(writer, DexItemType.CODE_ITEM, dexFile.codeItemPool.getNumItems(), dexFile.codeItemPool.getSectionOffset()); + writeItem(writer, DexItemType.CLASS_DATA_ITEM, dexFile.classDefPool.getNumClassDataItems(), dexFile.classDefPool.getDataSectionOffset()); + writeItem(writer, DexItemType.MAP_LIST, numItems, sectionOffset); + } + + private int calcNumItems() { + int numItems = 0; + + // header item + numItems++; + + if (dexFile.stringPool.getNumItems() > 0) { + numItems += 2; // index and data + } + if (dexFile.typePool.getNumItems() > 0) { + numItems++; + } + if (dexFile.protoPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.fieldPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.methodPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.typeListPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.encodedArrayPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.annotationPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.annotationSetPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.annotationSetRefPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.annotationDirectoryPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.debugInfoPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.codeItemPool.getNumItems() > 0) { + numItems++; + } + if (dexFile.classDefPool.getNumClassDefItems() > 0) { + numItems++; + } + if (dexFile.classDefPool.getNumClassDataItems() > 0) { + numItems++; + } + // map item itself + numItems++; + + return numItems; + } + + private void writeItem(DexWriter writer, int type, int size, int offset) throws IOException { + if (size > 0) { + writer.writeUshort(type); + writer.writeUshort(0); + writer.writeInt(size); + writer.writeInt(offset); + } + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodPool.java index 70ee1f40..dff26ced 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/MethodPool.java @@ -43,9 +43,11 @@ import java.util.List; import java.util.Map; public class MethodPool { - private final static int METHOD_ID_ITEM_SIZE = 8; + public final static int METHOD_ID_ITEM_SIZE = 0x08; + @Nonnull private final Map internedMethodIdItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public MethodPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -72,9 +74,21 @@ public class MethodPool { return internedMethodIdItems.size() * METHOD_ID_ITEM_SIZE; } + public int getNumItems() { + return internedMethodIdItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List methods = Lists.newArrayList(internedMethodIdItems.keySet()); + sectionOffset = writer.getPosition(); int index = 0; for (MethodReference method: methods) { internedMethodIdItems.put(method, index++); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/ProtoPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/ProtoPool.java index 641b0d02..9e026c3e 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/ProtoPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/ProtoPool.java @@ -47,9 +47,11 @@ import java.util.List; import java.util.Map; public class ProtoPool { - private final static int PROTO_ID_ITEM_SIZE = 12; + public final static int PROTO_ID_ITEM_SIZE = 0x0C; + @Nonnull private final Map internedProtoIdItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public ProtoPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -80,10 +82,22 @@ public class ProtoPool { return internedProtoIdItems.size() * PROTO_ID_ITEM_SIZE; } + public int getNumItems() { + return internedProtoIdItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List prototypes = Lists.newArrayList(internedProtoIdItems.keySet()); Collections.sort(prototypes); + sectionOffset = writer.getPosition(); int index = 0; for (Key proto: prototypes) { internedProtoIdItems.put(proto, index++); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/StringPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/StringPool.java index 79c945dc..5af1a276 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/StringPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/StringPool.java @@ -44,8 +44,11 @@ import java.util.List; import java.util.Map; public class StringPool { - private final static int STRING_ID_ITEM_SIZE = 4; + public final static int STRING_ID_ITEM_SIZE = 0x04; + @Nonnull private final Map internedStringIdItems = Maps.newHashMap(); + private int indexSectionOffset = -1; + private int dataSectionOffset = -1; public void intern(@Nonnull CharSequence string) { internedStringIdItems.put(string.toString(), 0); @@ -77,10 +80,25 @@ public class StringPool { return internedStringIdItems.size() * STRING_ID_ITEM_SIZE; } + public int getNumItems() { + return internedStringIdItems.size(); + } + + public int getIndexSectionOffset() { + return indexSectionOffset; + } + + public int getDataSectionOffset() { + return dataSectionOffset; + } + public void write(@Nonnull DexWriter indexWriter, @Nonnull DexWriter offsetWriter) throws IOException { List strings = Lists.newArrayList(internedStringIdItems.keySet()); Collections.sort(strings); + indexSectionOffset = indexWriter.getPosition(); + dataSectionOffset = offsetWriter.getPosition(); + int index = 0; for (String string: strings) { internedStringIdItems.put(string, index++); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/TypeListPool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/TypeListPool.java index 29faf1bc..33c72995 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/TypeListPool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/TypeListPool.java @@ -42,6 +42,7 @@ import java.util.*; public class TypeListPool { @Nonnull private final Map internedTypeListItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public TypeListPool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -66,10 +67,23 @@ public class TypeListPool { return offset; } + public int getNumItems() { + return internedTypeListItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List typeLists = Lists.newArrayList(internedTypeListItems.keySet()); Collections.sort(typeLists); + writer.align(); + sectionOffset = writer.getPosition(); for (Key typeList: typeLists) { writer.align(); internedTypeListItems.put(typeList, writer.getPosition()); diff --git a/dexlib2/src/main/java/org/jf/dexlib2/writer/TypePool.java b/dexlib2/src/main/java/org/jf/dexlib2/writer/TypePool.java index dc41b303..88d5045d 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/writer/TypePool.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/writer/TypePool.java @@ -43,9 +43,11 @@ import java.util.List; import java.util.Map; public class TypePool { - private final static int TYPE_ID_ITEM_SIZE = 4; + public final static int TYPE_ID_ITEM_SIZE = 0x04; + @Nonnull private final Map internedTypeIdItems = Maps.newHashMap(); @Nonnull private final DexFile dexFile; + private int sectionOffset = -1; public TypePool(@Nonnull DexFile dexFile) { this.dexFile = dexFile; @@ -83,10 +85,22 @@ public class TypePool { return internedTypeIdItems.size() * TYPE_ID_ITEM_SIZE; } + public int getNumItems() { + return internedTypeIdItems.size(); + } + + public int getSectionOffset() { + if (sectionOffset < 0) { + throw new ExceptionWithContext("Section offset has not been set yet!"); + } + return sectionOffset; + } + public void write(@Nonnull DexWriter writer) throws IOException { List types = Lists.newArrayList(internedTypeIdItems.keySet()); Collections.sort(types); + sectionOffset = writer.getPosition(); int index = 0; for (String type: types) { internedTypeIdItems.put(type, index++);