11bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver/* 21bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * Copyright 2013, Google Inc. 31bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * All rights reserved. 41bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * 51bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * Redistribution and use in source and binary forms, with or without 61bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * modification, are permitted provided that the following conditions are 71bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * met: 81bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * 91bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * * Redistributions of source code must retain the above copyright 101bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * notice, this list of conditions and the following disclaimer. 111bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * * Redistributions in binary form must reproduce the above 121bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * copyright notice, this list of conditions and the following disclaimer 131bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * in the documentation and/or other materials provided with the 141bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * distribution. 151bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * * Neither the name of Google Inc. nor the names of its 161bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * contributors may be used to endorse or promote products derived from 171bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * this software without specific prior written permission. 181bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * 191bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 201bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 211bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 221bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 231bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 241bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 251bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 261bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 271bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 281bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 291bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 301bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver */ 311bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 321bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverpackage org.jf.dexlib2.writer; 331bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 34bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruverimport com.google.common.collect.Ordering; 351bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport org.jf.dexlib2.ValueType; 36bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruverimport org.jf.dexlib2.base.BaseAnnotationElement; 371bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport org.jf.dexlib2.iface.reference.FieldReference; 381bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport org.jf.dexlib2.iface.reference.MethodReference; 391bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 401bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport javax.annotation.Nonnull; 411bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport java.io.IOException; 421bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverimport java.util.Collection; 431bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 441bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverpublic abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends FieldReference, 45bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver MethodRefKey extends MethodReference, AnnotationElement extends org.jf.dexlib2.iface.AnnotationElement, 46bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver EncodedValue> { 471bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull private final DexDataWriter writer; 481bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull private final StringSection<StringKey, ?> stringSection; 491bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull private final TypeSection<?, TypeKey, ?> typeSection; 5042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final FieldSection<?, ?, FieldRefKey, ?> fieldSection; 5142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final MethodSection<?, ?, ?, MethodRefKey, ?> methodSection; 521bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull private final AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection; 531bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 541bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public EncodedValueWriter( 551bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull DexDataWriter writer, 561bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull StringSection<StringKey, ?> stringSection, 571bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull TypeSection<?, TypeKey, ?> typeSection, 5842627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection, 5942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection, 601bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver @Nonnull AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection) { 611bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.writer = writer; 621bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.stringSection = stringSection; 631bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.typeSection = typeSection; 641bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.fieldSection = fieldSection; 651bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.methodSection = methodSection; 661bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver this.annotationSection = annotationSection; 671bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 681bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 691bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver protected abstract void writeEncodedValue(@Nonnull EncodedValue encodedValue) throws IOException; 701bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 711bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeAnnotation(TypeKey annotationType, 721bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver Collection<? extends AnnotationElement> elements) throws IOException { 731bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedValueHeader(ValueType.ANNOTATION, 0); 741bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeUleb128(typeSection.getItemIndex(annotationType)); 751bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeUleb128(elements.size()); 76bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver 77bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver Collection<? extends AnnotationElement> sortedElements = Ordering.from(BaseAnnotationElement.BY_NAME) 78bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver .immutableSortedCopy(elements); 79bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver 80bf167c2f0ed5b9ebde990819554b33373449e39bBen Gruver for (AnnotationElement element: sortedElements) { 811bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element))); 821bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writeEncodedValue(annotationSection.getElementValue(element)); 831bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 841bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 851bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 861bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeArray(Collection<? extends EncodedValue> elements) throws IOException { 871bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedValueHeader(ValueType.ARRAY, 0); 881bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeUleb128(elements.size()); 891bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver for (EncodedValue element: elements) { 901bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writeEncodedValue(element); 911bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 921bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 931bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 941bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeBoolean(boolean value) throws IOException { 951bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedValueHeader(ValueType.BOOLEAN, value ? 1 : 0); 961bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 971bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 981bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeByte(byte value) throws IOException { 991bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedInt(ValueType.BYTE, value); 1001bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1011bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1021bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeChar(char value) throws IOException { 1031bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedUint(ValueType.CHAR, value); 1041bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1051bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1061bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeDouble(double value) throws IOException { 1071bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedDouble(ValueType.DOUBLE, value); 1081bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1091bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1101bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeEnum(@Nonnull FieldRefKey value) throws IOException { 1111bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedUint(ValueType.ENUM, fieldSection.getItemIndex(value)); 1121bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1131bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1141bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeField(@Nonnull FieldRefKey value) throws IOException { 1151bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedUint(ValueType.FIELD, fieldSection.getItemIndex(value)); 1161bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1171bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1181bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeFloat(float value) throws IOException { 1191bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedFloat(ValueType.FLOAT, value); 1201bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1211bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1221bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeInt(int value) throws IOException { 1231bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedInt(ValueType.INT, value); 1241bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1251bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1261bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeLong(long value) throws IOException { 1271bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedLong(ValueType.LONG, value); 1281bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1291bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1301bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeMethod(@Nonnull MethodRefKey value) throws IOException { 1311bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedUint(ValueType.METHOD, methodSection.getItemIndex(value)); 1321bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1331bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1341bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeNull() throws IOException { 1351bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.write(ValueType.NULL); 1361bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1371bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1381bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeShort(int value) throws IOException { 1391bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedInt(ValueType.SHORT, value); 1401bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1411bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1421bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeString(@Nonnull StringKey value) throws IOException { 1431bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedUint(ValueType.STRING, stringSection.getItemIndex(value)); 1441bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1451bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver 1461bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver public void writeType(@Nonnull TypeKey value) throws IOException { 1471bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver writer.writeEncodedUint(ValueType.TYPE, typeSection.getItemIndex(value)); 1481bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver } 1491bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver} 150