mirror of
https://github.com/revanced/smali.git
synced 2025-05-31 21:00:11 +02:00
Add support for writing map_item
This commit is contained in:
parent
e68daf22aa
commit
085cfce948
@ -49,6 +49,7 @@ public class AnnotationDirectoryPool {
|
|||||||
@Nonnull private final Map<String, Integer> nonInternedAnnotationDirectoryOffsetMap = Maps.newHashMap();
|
@Nonnull private final Map<String, Integer> nonInternedAnnotationDirectoryOffsetMap = Maps.newHashMap();
|
||||||
@Nonnull private final List<Key> nonInternedAnnotationDirectoryItems = Lists.newArrayList();
|
@Nonnull private final List<Key> nonInternedAnnotationDirectoryItems = Lists.newArrayList();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public AnnotationDirectoryPool(@Nonnull DexFile dexFile) {
|
public AnnotationDirectoryPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -101,10 +102,24 @@ public class AnnotationDirectoryPool {
|
|||||||
return offset;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
// we'll write out the interned items first
|
// we'll write out the interned items first
|
||||||
List<Key> directoryItems = Lists.newArrayList(internedAnnotationDirectoryItems.keySet());
|
List<Key> directoryItems = Lists.newArrayList(internedAnnotationDirectoryItems.keySet());
|
||||||
Collections.sort(directoryItems);
|
Collections.sort(directoryItems);
|
||||||
|
|
||||||
|
writer.align();
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Key key: directoryItems) {
|
for (Key key: directoryItems) {
|
||||||
writer.align();
|
writer.align();
|
||||||
internedAnnotationDirectoryItems.put(key, writer.getPosition());
|
internedAnnotationDirectoryItems.put(key, writer.getPosition());
|
||||||
|
@ -49,6 +49,7 @@ import java.util.SortedSet;
|
|||||||
public class AnnotationPool {
|
public class AnnotationPool {
|
||||||
@Nonnull private final Map<Annotation, Integer> internedAnnotations = Maps.newHashMap();
|
@Nonnull private final Map<Annotation, Integer> internedAnnotations = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public AnnotationPool(@Nonnull DexFile dexFile) {
|
public AnnotationPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -73,10 +74,22 @@ public class AnnotationPool {
|
|||||||
return offset;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Annotation> annotations = Lists.newArrayList(internedAnnotations.keySet());
|
List<Annotation> annotations = Lists.newArrayList(internedAnnotations.keySet());
|
||||||
Collections.sort(annotations);
|
Collections.sort(annotations);
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Annotation annotation: annotations) {
|
for (Annotation annotation: annotations) {
|
||||||
internedAnnotations.put(annotation, writer.getPosition());
|
internedAnnotations.put(annotation, writer.getPosition());
|
||||||
writer.writeUbyte(annotation.getVisibility());
|
writer.writeUbyte(annotation.getVisibility());
|
||||||
|
@ -47,6 +47,7 @@ import java.util.*;
|
|||||||
public class AnnotationSetPool {
|
public class AnnotationSetPool {
|
||||||
@Nonnull private final Map<Set<? extends Annotation>, Integer> internedAnnotationSetItems = Maps.newHashMap();
|
@Nonnull private final Map<Set<? extends Annotation>, Integer> internedAnnotationSetItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public AnnotationSetPool(@Nonnull DexFile dexFile) {
|
public AnnotationSetPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -74,11 +75,24 @@ public class AnnotationSetPool {
|
|||||||
return offset;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Set<? extends Annotation>> annotationSets =
|
List<Set<? extends Annotation>> annotationSets =
|
||||||
Lists.newArrayList(internedAnnotationSetItems.keySet());
|
Lists.newArrayList(internedAnnotationSetItems.keySet());
|
||||||
Collections.sort(annotationSets, CollectionUtils.listComparator(Ordering.natural()));
|
Collections.sort(annotationSets, CollectionUtils.listComparator(Ordering.natural()));
|
||||||
|
|
||||||
|
writer.align();
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Set<? extends Annotation> annotationSet: annotationSets) {
|
for (Set<? extends Annotation> annotationSet: annotationSets) {
|
||||||
SortedSet<? extends Annotation> sortedAnnotationSet = ImmutableSortedSet.copyOf(BaseAnnotation.BY_TYPE,
|
SortedSet<? extends Annotation> sortedAnnotationSet = ImmutableSortedSet.copyOf(BaseAnnotation.BY_TYPE,
|
||||||
annotationSet);
|
annotationSet);
|
||||||
|
@ -51,6 +51,7 @@ import java.util.*;
|
|||||||
public class AnnotationSetRefPool {
|
public class AnnotationSetRefPool {
|
||||||
@Nonnull private final Map<Key, Integer> internedAnnotationSetRefItems = Maps.newHashMap();
|
@Nonnull private final Map<Key, Integer> internedAnnotationSetRefItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public AnnotationSetRefPool(@Nonnull DexFile dexFile) {
|
public AnnotationSetRefPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -75,11 +76,24 @@ public class AnnotationSetRefPool {
|
|||||||
return offset;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Key> annotationSetRefs =
|
List<Key> annotationSetRefs =
|
||||||
Lists.newArrayList(internedAnnotationSetRefItems.keySet());
|
Lists.newArrayList(internedAnnotationSetRefItems.keySet());
|
||||||
Collections.sort(annotationSetRefs);
|
Collections.sort(annotationSetRefs);
|
||||||
|
|
||||||
|
writer.align();
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Key key: annotationSetRefs) {
|
for (Key key: annotationSetRefs) {
|
||||||
writer.align();
|
writer.align();
|
||||||
internedAnnotationSetRefItems.put(key, writer.getPosition());
|
internedAnnotationSetRefItems.put(key, writer.getPosition());
|
||||||
@ -127,7 +141,7 @@ public class AnnotationSetRefPool {
|
|||||||
}
|
}
|
||||||
Iterator<Set<? extends Annotation>> otherAnnotationSets = getAnnotationSets().iterator();
|
Iterator<Set<? extends Annotation>> otherAnnotationSets = getAnnotationSets().iterator();
|
||||||
for (Set<? extends Annotation> annotationSet: getAnnotationSets()) {
|
for (Set<? extends Annotation> annotationSet: getAnnotationSets()) {
|
||||||
if (!annotationSet.equals(otherAnnotationSets)) {
|
if (!annotationSet.equals(otherAnnotationSets.next())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ import java.util.Map;
|
|||||||
public class DebugInfoPool {
|
public class DebugInfoPool {
|
||||||
@Nonnull private final Map<Method, Integer> debugInfoOffsetMap = Maps.newHashMap();
|
@Nonnull private final Map<Method, Integer> debugInfoOffsetMap = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public DebugInfoPool(@Nonnull DexFile dexFile) {
|
public DebugInfoPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -96,9 +97,22 @@ public class DebugInfoPool {
|
|||||||
return offset;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Method> methods = Lists.newArrayList(debugInfoOffsetMap.keySet());
|
List<Method> methods = Lists.newArrayList(debugInfoOffsetMap.keySet());
|
||||||
Collections.sort(methods);
|
Collections.sort(methods);
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Method method: methods) {
|
for (Method method: methods) {
|
||||||
debugInfoOffsetMap.put(method, writer.getPosition());
|
debugInfoOffsetMap.put(method, writer.getPosition());
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ public class DexFile {
|
|||||||
@Nonnull final DebugInfoPool debugInfoPool = new DebugInfoPool(this);
|
@Nonnull final DebugInfoPool debugInfoPool = new DebugInfoPool(this);
|
||||||
@Nonnull final CodeItemPool codeItemPool = new CodeItemPool(this);
|
@Nonnull final CodeItemPool codeItemPool = new CodeItemPool(this);
|
||||||
@Nonnull final ClassDefPool classDefPool = new ClassDefPool(this);
|
@Nonnull final ClassDefPool classDefPool = new ClassDefPool(this);
|
||||||
|
@Nonnull final MapItem mapItem = new MapItem(this);
|
||||||
|
|
||||||
@Nonnull private final Set<? extends ClassDef> classes;
|
@Nonnull private final Set<? extends ClassDef> classes;
|
||||||
|
|
||||||
@ -205,6 +206,7 @@ public class DexFile {
|
|||||||
debugInfoPool.write(offsetWriter);
|
debugInfoPool.write(offsetWriter);
|
||||||
codeItemPool.write(offsetWriter);
|
codeItemPool.write(offsetWriter);
|
||||||
classDefPool.write(indexWriter, offsetWriter);
|
classDefPool.write(indexWriter, offsetWriter);
|
||||||
|
mapItem.write(offsetWriter);
|
||||||
} finally {
|
} finally {
|
||||||
indexWriter.close();
|
indexWriter.close();
|
||||||
offsetWriter.close();
|
offsetWriter.close();
|
||||||
|
@ -55,6 +55,7 @@ import java.util.*;
|
|||||||
public class EncodedArrayPool {
|
public class EncodedArrayPool {
|
||||||
@Nonnull private final Map<Key, Integer> internedEncodedArrayItems = Maps.newHashMap();
|
@Nonnull private final Map<Key, Integer> internedEncodedArrayItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public EncodedArrayPool(DexFile dexFile) {
|
public EncodedArrayPool(DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -84,10 +85,22 @@ public class EncodedArrayPool {
|
|||||||
return 0;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Key> encodedArrays = Lists.newArrayList(internedEncodedArrayItems.keySet());
|
List<Key> encodedArrays = Lists.newArrayList(internedEncodedArrayItems.keySet());
|
||||||
Collections.sort(encodedArrays);
|
Collections.sort(encodedArrays);
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Key encodedArray: encodedArrays) {
|
for (Key encodedArray: encodedArrays) {
|
||||||
internedEncodedArrayItems.put(encodedArray, writer.getPosition());
|
internedEncodedArrayItems.put(encodedArray, writer.getPosition());
|
||||||
writer.writeUleb128(encodedArray.getElementCount());
|
writer.writeUleb128(encodedArray.getElementCount());
|
||||||
|
@ -44,9 +44,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class FieldPool {
|
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<FieldReference, Integer> internedFieldIdItems = Maps.newHashMap();
|
@Nonnull private final Map<FieldReference, Integer> internedFieldIdItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public FieldPool(@Nonnull DexFile dexFile) {
|
public FieldPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -73,10 +75,22 @@ public class FieldPool {
|
|||||||
return internedFieldIdItems.size() * FIELD_ID_ITEM_SIZE;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<FieldReference> fields = Lists.newArrayList(internedFieldIdItems.keySet());
|
List<FieldReference> fields = Lists.newArrayList(internedFieldIdItems.keySet());
|
||||||
Collections.sort(fields);
|
Collections.sort(fields);
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (FieldReference field: fields) {
|
for (FieldReference field: fields) {
|
||||||
internedFieldIdItems.put(field, index++);
|
internedFieldIdItems.put(field, index++);
|
||||||
|
149
dexlib2/src/main/java/org/jf/dexlib2/writer/MapItem.java
Normal file
149
dexlib2/src/main/java/org/jf/dexlib2/writer/MapItem.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -43,9 +43,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class MethodPool {
|
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<MethodReference, Integer> internedMethodIdItems = Maps.newHashMap();
|
@Nonnull private final Map<MethodReference, Integer> internedMethodIdItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public MethodPool(@Nonnull DexFile dexFile) {
|
public MethodPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -72,9 +74,21 @@ public class MethodPool {
|
|||||||
return internedMethodIdItems.size() * METHOD_ID_ITEM_SIZE;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<MethodReference> methods = Lists.newArrayList(internedMethodIdItems.keySet());
|
List<MethodReference> methods = Lists.newArrayList(internedMethodIdItems.keySet());
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (MethodReference method: methods) {
|
for (MethodReference method: methods) {
|
||||||
internedMethodIdItems.put(method, index++);
|
internedMethodIdItems.put(method, index++);
|
||||||
|
@ -47,9 +47,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ProtoPool {
|
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<Key, Integer> internedProtoIdItems = Maps.newHashMap();
|
@Nonnull private final Map<Key, Integer> internedProtoIdItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public ProtoPool(@Nonnull DexFile dexFile) {
|
public ProtoPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -80,10 +82,22 @@ public class ProtoPool {
|
|||||||
return internedProtoIdItems.size() * PROTO_ID_ITEM_SIZE;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Key> prototypes = Lists.newArrayList(internedProtoIdItems.keySet());
|
List<Key> prototypes = Lists.newArrayList(internedProtoIdItems.keySet());
|
||||||
Collections.sort(prototypes);
|
Collections.sort(prototypes);
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Key proto: prototypes) {
|
for (Key proto: prototypes) {
|
||||||
internedProtoIdItems.put(proto, index++);
|
internedProtoIdItems.put(proto, index++);
|
||||||
|
@ -44,8 +44,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class StringPool {
|
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<String, Integer> internedStringIdItems = Maps.newHashMap();
|
@Nonnull private final Map<String, Integer> internedStringIdItems = Maps.newHashMap();
|
||||||
|
private int indexSectionOffset = -1;
|
||||||
|
private int dataSectionOffset = -1;
|
||||||
|
|
||||||
public void intern(@Nonnull CharSequence string) {
|
public void intern(@Nonnull CharSequence string) {
|
||||||
internedStringIdItems.put(string.toString(), 0);
|
internedStringIdItems.put(string.toString(), 0);
|
||||||
@ -77,10 +80,25 @@ public class StringPool {
|
|||||||
return internedStringIdItems.size() * STRING_ID_ITEM_SIZE;
|
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 {
|
public void write(@Nonnull DexWriter indexWriter, @Nonnull DexWriter offsetWriter) throws IOException {
|
||||||
List<String> strings = Lists.newArrayList(internedStringIdItems.keySet());
|
List<String> strings = Lists.newArrayList(internedStringIdItems.keySet());
|
||||||
Collections.sort(strings);
|
Collections.sort(strings);
|
||||||
|
|
||||||
|
indexSectionOffset = indexWriter.getPosition();
|
||||||
|
dataSectionOffset = offsetWriter.getPosition();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (String string: strings) {
|
for (String string: strings) {
|
||||||
internedStringIdItems.put(string, index++);
|
internedStringIdItems.put(string, index++);
|
||||||
|
@ -42,6 +42,7 @@ import java.util.*;
|
|||||||
public class TypeListPool {
|
public class TypeListPool {
|
||||||
@Nonnull private final Map<Key, Integer> internedTypeListItems = Maps.newHashMap();
|
@Nonnull private final Map<Key, Integer> internedTypeListItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public TypeListPool(@Nonnull DexFile dexFile) {
|
public TypeListPool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -66,10 +67,23 @@ public class TypeListPool {
|
|||||||
return offset;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<Key> typeLists = Lists.newArrayList(internedTypeListItems.keySet());
|
List<Key> typeLists = Lists.newArrayList(internedTypeListItems.keySet());
|
||||||
Collections.sort(typeLists);
|
Collections.sort(typeLists);
|
||||||
|
|
||||||
|
writer.align();
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
for (Key typeList: typeLists) {
|
for (Key typeList: typeLists) {
|
||||||
writer.align();
|
writer.align();
|
||||||
internedTypeListItems.put(typeList, writer.getPosition());
|
internedTypeListItems.put(typeList, writer.getPosition());
|
||||||
|
@ -43,9 +43,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TypePool {
|
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<String, Integer> internedTypeIdItems = Maps.newHashMap();
|
@Nonnull private final Map<String, Integer> internedTypeIdItems = Maps.newHashMap();
|
||||||
@Nonnull private final DexFile dexFile;
|
@Nonnull private final DexFile dexFile;
|
||||||
|
private int sectionOffset = -1;
|
||||||
|
|
||||||
public TypePool(@Nonnull DexFile dexFile) {
|
public TypePool(@Nonnull DexFile dexFile) {
|
||||||
this.dexFile = dexFile;
|
this.dexFile = dexFile;
|
||||||
@ -83,10 +85,22 @@ public class TypePool {
|
|||||||
return internedTypeIdItems.size() * TYPE_ID_ITEM_SIZE;
|
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 {
|
public void write(@Nonnull DexWriter writer) throws IOException {
|
||||||
List<String> types = Lists.newArrayList(internedTypeIdItems.keySet());
|
List<String> types = Lists.newArrayList(internedTypeIdItems.keySet());
|
||||||
Collections.sort(types);
|
Collections.sort(types);
|
||||||
|
|
||||||
|
sectionOffset = writer.getPosition();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (String type: types) {
|
for (String type: types) {
|
||||||
internedTypeIdItems.put(type, index++);
|
internedTypeIdItems.put(type, index++);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user