private void writeDebugAndCodeItems(@Nonnull DexDataWriter offsetWriter, @Nonnull DeferredOutputStream temp) throws IOException { ByteArrayOutputStream ehBuf = new ByteArrayOutputStream(); debugSectionOffset = offsetWriter.getPosition(); DebugWriter<StringKey, TypeKey> debugWriter = new DebugWriter<StringKey, TypeKey>(stringSection, typeSection, offsetWriter); DexDataWriter codeWriter = new DexDataWriter(temp, 0); offsetWriter.align(); codeSectionOffset = offsetWriter.getPosition(); codeWriter.close(); temp.writeTo(offsetWriter); temp.close();
private void writeStrings(@Nonnull DexDataWriter indexWriter, @Nonnull DexDataWriter offsetWriter) throws IOException { stringIndexSectionOffset = indexWriter.getPosition(); stringDataSectionOffset = offsetWriter.getPosition(); int index = 0; List<Entry<? extends StringKey, Integer>> stringEntries = Lists.newArrayList(stringSection.getItems()); Collections.sort(stringEntries, toStringKeyComparator); for (Map.Entry<? extends StringKey, Integer> entry: stringEntries) { entry.setValue(index++); indexWriter.writeInt(offsetWriter.getPosition()); String stringValue = entry.getKey().toString(); offsetWriter.writeUleb128(stringValue.length()); offsetWriter.writeString(stringValue); offsetWriter.write(0); } }
private void writeMapItem(@Nonnull DexDataWriter writer, int type, int size, int offset) throws IOException { if (size > 0) { writer.writeUshort(type); writer.writeUshort(0); writer.writeInt(size); writer.writeInt(offset); } }
private void writeTypeLists(@Nonnull DexDataWriter writer) throws IOException { writer.align(); typeListSectionOffset = writer.getPosition(); for (Map.Entry<? extends TypeListKey, Integer> entry: typeListSection.getItems()) { writer.align(); entry.setValue(writer.getPosition()); Collection<? extends TypeKey> types = typeListSection.getTypes(entry.getKey()); writer.writeInt(types.size()); for (TypeKey typeKey: types) { writer.writeUshort(typeSection.getItemIndex(typeKey)); } } }
public void write(@Nonnull ArrayPayload instruction) { try { writer.writeUshort(instruction.getOpcode().value); writer.writeUshort(instruction.getElementWidth()); List<Number> elements = instruction.getArrayElements(); writer.writeInt(elements.size()); switch (instruction.getElementWidth()) { case 1: for (Number element: elements) { writer.write(element.byteValue()); writer.writeShort(element.shortValue()); writer.writeInt(element.intValue()); writer.writeLong(element.longValue()); if ((writer.getPosition() & 1) != 0) { writer.write(0);
private void writeAnnotationSets(@Nonnull DexDataWriter writer) throws IOException { writer.align(); annotationSetSectionOffset = writer.getPosition(); if (shouldCreateEmptyAnnotationSet()) { writer.writeInt(0); } for (Map.Entry<? extends AnnotationSetKey, Integer> entry: annotationSetSection.getItems()) { Collection<? extends AnnotationKey> annotations = Ordering.from(BaseAnnotation.BY_TYPE) .immutableSortedCopy(annotationSetSection.getAnnotations(entry.getKey())); writer.align(); entry.setValue(writer.getPosition()); writer.writeInt(annotations.size()); for (AnnotationKey annotationKey: annotations) { writer.writeInt(annotationSection.getItemOffset(annotationKey)); } } }
writer.align(); int codeItemOffset = writer.getPosition(); writer.writeUshort(classSection.getRegisterCount(methodKey)); writer.writeUshort(MethodUtil.getParameterRegisterCount(parameters, isStatic)); writer.writeUshort(outParamCount); writer.writeUshort(tryBlocks.size()); writer.writeInt(debugItemOffset); writer.writeInt(codeUnitCount); int codeOffset = 0; for (Instruction instruction: instructions) { writer.align(); DexDataWriter.writeUleb128(ehBuf, exceptionHandlerOffsetMap.size()); writer.writeInt(startAddress); writer.writeUshort(tbCodeUnitCount); writer.writeUshort(offset); } else { writer.writeUshort(offset); exceptionHandlerOffsetMap.put(tryBlock.getExceptionHandlers(), offset);
protected void writeRightZeroExtendedInt(int valueType, int value) throws IOException { int index = 3; do { tempBuf[index--] = (byte)((value & 0xFF000000) >>> 24); value <<= 8; } while (value != 0); int firstElement = index+1; int encodedLength = 4-firstElement; writeEncodedValueHeader(valueType, encodedLength - 1); write(tempBuf, firstElement, encodedLength); }
public void writeArray(Collection<? extends EncodedValue> elements) throws IOException { writer.writeEncodedValueHeader(ValueType.ARRAY, 0); writer.writeUleb128(elements.size()); for (EncodedValue element: elements) { writeEncodedValue(element); } }
private void writeAnnotationDirectories(@Nonnull DexDataWriter writer) throws IOException { writer.align(); annotationDirectorySectionOffset = writer.getPosition(); HashMap<AnnotationSetKey, Integer> internedItems = Maps.newHashMap(); continue; } else { internedItems.put(classAnnotationKey, writer.getPosition()); classSection.setAnnotationDirectoryOffset(key, writer.getPosition()); writer.writeInt(annotationSetSection.getNullableItemOffset(classAnnotationKey)); writer.writeInt(fieldAnnotations); writer.writeInt(methodAnnotations); writer.writeInt(parameterAnnotations); writer.write(tempBuffer.array(), 0, tempBuffer.position());
private void writeMethods(@Nonnull DexDataWriter writer) throws IOException { methodSectionOffset = writer.getPosition(); int index = 0; List<Map.Entry<? extends MethodRefKey, Integer>> methodEntries = Lists.newArrayList(methodSection.getItems()); Collections.sort(methodEntries, DexWriter.<MethodRefKey>comparableKeyComparator()); for (Map.Entry<? extends MethodRefKey, Integer> entry: methodEntries) { entry.setValue(index++); MethodRefKey key = entry.getKey(); writer.writeUshort(typeSection.getItemIndex(methodSection.getDefiningClass(key))); writer.writeUshort(protoSection.getItemIndex(methodSection.getPrototype(key))); writer.writeInt(stringSection.getItemIndex(methodSection.getName(key))); } }
private void writeHeader(@Nonnull DexDataWriter writer, int dataOffset, int fileSize) throws IOException { // Write the appropriate header. writer.write(HeaderItem.getMagicForApi(opcodes.api)); // checksum placeholder writer.writeInt(0); // signature placeholder writer.write(new byte[20]); writer.writeInt(fileSize); writer.writeInt(HeaderItem.ITEM_SIZE); writer.writeInt(HeaderItem.LITTLE_ENDIAN_TAG); // link writer.writeInt(0); writer.writeInt(0); // map writer.writeInt(mapSectionOffset); // index sections writeSectionInfo(writer, stringSection.getItems().size(), stringIndexSectionOffset); writeSectionInfo(writer, typeSection.getItems().size(), typeSectionOffset); writeSectionInfo(writer, protoSection.getItems().size(), protoSectionOffset); writeSectionInfo(writer, fieldSection.getItems().size(), fieldSectionOffset); writeSectionInfo(writer, methodSection.getItems().size(), methodSectionOffset); writeSectionInfo(writer, classSection.getItems().size(), classIndexSectionOffset); // data section writer.writeInt(fileSize - dataOffset); writer.writeInt(dataOffset); }
public void writeChar(char value) throws IOException { writer.writeEncodedUint(ValueType.CHAR, value); }
private void writeAnnotations(@Nonnull DexDataWriter writer) throws IOException { InternalEncodedValueWriter encodedValueWriter = new InternalEncodedValueWriter(writer); annotationSectionOffset = writer.getPosition(); for (Map.Entry<? extends AnnotationKey, Integer> entry: annotationSection.getItems()) { entry.setValue(writer.getPosition()); AnnotationKey key = entry.getKey(); writer.writeUbyte(annotationSection.getVisibility(key)); writer.writeUleb128(typeSection.getItemIndex(annotationSection.getType(key))); Collection<? extends AnnotationElement> elements = Ordering.from(BaseAnnotationElement.BY_NAME) .immutableSortedCopy(annotationSection.getElements(key)); writer.writeUleb128(elements.size()); for (AnnotationElement element: elements) { writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element))); writeEncodedValue(encodedValueWriter, annotationSection.getElementValue(element)); } } }
int debugItemOffset = writer.getPosition(); int startingLineNumber = 0; writer.writeUleb128(startingLineNumber); writer.writeUleb128(parameterCount); if (parameterNames != null) { int index = 0; writer.writeUleb128(stringSection.getNullableItemIndex(parameterName) + 1); writer.write(0);
private void writeTypes(@Nonnull DexDataWriter writer) throws IOException { typeSectionOffset = writer.getPosition(); int index = 0; List<Map.Entry<? extends TypeKey, Integer>> typeEntries = Lists.newArrayList(typeSection.getItems()); Collections.sort(typeEntries, toStringKeyComparator); for (Map.Entry<? extends TypeKey, Integer> entry : typeEntries) { entry.setValue(index++); writer.writeInt(stringSection.getItemIndex(typeSection.getString(entry.getKey()))); } }
public void writeByte(byte value) throws IOException { writer.writeEncodedInt(ValueType.BYTE, value); }
writer = new DexDataWriter(output, startPosition, 256); writer.align(); writer.write(1); writer.align(); writer.align(); writer.write(1); writer.write(2); writer.align(); writer.write(1); writer.write(2); writer.write(3); writer.align(); writer.align(); writer.write(1); writer.write(2); writer.write(3); writer.write(4); writer.align(); writer.align(); writer.align(); writer.align(); writer.write(1); writer.align();
private static DexDataWriter outputAt(DexDataStore dataStore, int filePosition) throws IOException { return new DexDataWriter(dataStore.outputAt(filePosition), filePosition); }