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