• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.writer;
33 
34 import com.google.common.collect.Ordering;
35 import org.jf.dexlib2.ValueType;
36 import org.jf.dexlib2.base.BaseAnnotationElement;
37 import org.jf.dexlib2.iface.reference.FieldReference;
38 import org.jf.dexlib2.iface.reference.MethodHandleReference;
39 import org.jf.dexlib2.iface.reference.MethodReference;
40 
41 import javax.annotation.Nonnull;
42 import java.io.IOException;
43 import java.util.Collection;
44 
45 public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends FieldReference,
46         MethodRefKey extends MethodReference, AnnotationElement extends org.jf.dexlib2.iface.AnnotationElement,
47         ProtoRefKey, MethodHandleKey extends MethodHandleReference, EncodedValue> {
48     @Nonnull private final DexDataWriter writer;
49     @Nonnull private final StringSection<StringKey, ?> stringSection;
50     @Nonnull private final TypeSection<?, TypeKey, ?> typeSection;
51     @Nonnull private final FieldSection<?, ?, FieldRefKey, ?> fieldSection;
52     @Nonnull private final MethodSection<?, ?, ?, MethodRefKey, ?> methodSection;
53     @Nonnull private final ProtoSection<?, ?, ProtoRefKey, ?> protoSection;
54     @Nonnull private final MethodHandleSection<MethodHandleKey, ?, ?> methodHandleSection;
55     @Nonnull private final AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection;
56 
EncodedValueWriter( @onnull DexDataWriter writer, @Nonnull StringSection<StringKey, ?> stringSection, @Nonnull TypeSection<?, TypeKey, ?> typeSection, @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection, @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection, ProtoSection<?, ?, ProtoRefKey, ?> protoSection, MethodHandleSection<MethodHandleKey, ?, ?> methodHandleSection, @Nonnull AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection)57     public EncodedValueWriter(
58             @Nonnull DexDataWriter writer,
59             @Nonnull StringSection<StringKey, ?> stringSection,
60             @Nonnull TypeSection<?, TypeKey, ?> typeSection,
61             @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
62             @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
63             ProtoSection<?, ?, ProtoRefKey, ?> protoSection,
64             MethodHandleSection<MethodHandleKey, ?, ?> methodHandleSection,
65             @Nonnull AnnotationSection<StringKey, TypeKey, ?, AnnotationElement, EncodedValue> annotationSection) {
66         this.writer = writer;
67         this.stringSection = stringSection;
68         this.typeSection = typeSection;
69         this.fieldSection = fieldSection;
70         this.methodSection = methodSection;
71         this.protoSection = protoSection;
72         this.methodHandleSection = methodHandleSection;
73         this.annotationSection = annotationSection;
74     }
75 
writeEncodedValue(@onnull EncodedValue encodedValue)76     protected abstract void writeEncodedValue(@Nonnull EncodedValue encodedValue) throws IOException;
77 
writeAnnotation(TypeKey annotationType, Collection<? extends AnnotationElement> elements)78     public void writeAnnotation(TypeKey annotationType,
79                                 Collection<? extends AnnotationElement> elements) throws IOException {
80         writer.writeEncodedValueHeader(ValueType.ANNOTATION, 0);
81         writer.writeUleb128(typeSection.getItemIndex(annotationType));
82         writer.writeUleb128(elements.size());
83 
84         Collection<? extends AnnotationElement> sortedElements = Ordering.from(BaseAnnotationElement.BY_NAME)
85                 .immutableSortedCopy(elements);
86 
87         for (AnnotationElement element: sortedElements) {
88             writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element)));
89             writeEncodedValue(annotationSection.getElementValue(element));
90         }
91     }
92 
writeArray(Collection<? extends EncodedValue> elements)93     public void writeArray(Collection<? extends EncodedValue> elements) throws IOException {
94         writer.writeEncodedValueHeader(ValueType.ARRAY, 0);
95         writer.writeUleb128(elements.size());
96         for (EncodedValue element: elements) {
97             writeEncodedValue(element);
98         }
99     }
100 
writeBoolean(boolean value)101     public void writeBoolean(boolean value) throws IOException {
102         writer.writeEncodedValueHeader(ValueType.BOOLEAN, value ? 1 : 0);
103     }
104 
writeByte(byte value)105     public void writeByte(byte value) throws IOException {
106         writer.writeEncodedInt(ValueType.BYTE, value);
107     }
108 
writeChar(char value)109     public void writeChar(char value) throws IOException {
110         writer.writeEncodedUint(ValueType.CHAR, value);
111     }
112 
writeDouble(double value)113     public void writeDouble(double value) throws IOException {
114         writer.writeEncodedDouble(ValueType.DOUBLE, value);
115     }
116 
writeEnum(@onnull FieldRefKey value)117     public void writeEnum(@Nonnull FieldRefKey value) throws IOException {
118         writer.writeEncodedUint(ValueType.ENUM, fieldSection.getItemIndex(value));
119     }
120 
writeField(@onnull FieldRefKey value)121     public void writeField(@Nonnull FieldRefKey value) throws IOException {
122         writer.writeEncodedUint(ValueType.FIELD, fieldSection.getItemIndex(value));
123     }
124 
writeFloat(float value)125     public void writeFloat(float value) throws IOException {
126         writer.writeEncodedFloat(ValueType.FLOAT, value);
127     }
128 
writeInt(int value)129     public void writeInt(int value) throws IOException {
130         writer.writeEncodedInt(ValueType.INT, value);
131     }
132 
writeLong(long value)133     public void writeLong(long value) throws IOException {
134         writer.writeEncodedLong(ValueType.LONG, value);
135     }
136 
writeMethod(@onnull MethodRefKey value)137     public void writeMethod(@Nonnull MethodRefKey value) throws IOException {
138         writer.writeEncodedUint(ValueType.METHOD, methodSection.getItemIndex(value));
139     }
140 
writeNull()141     public void writeNull() throws IOException {
142         writer.write(ValueType.NULL);
143     }
144 
writeShort(int value)145     public void writeShort(int value) throws IOException {
146         writer.writeEncodedInt(ValueType.SHORT, value);
147     }
148 
writeString(@onnull StringKey value)149     public void writeString(@Nonnull StringKey value) throws IOException {
150         writer.writeEncodedUint(ValueType.STRING, stringSection.getItemIndex(value));
151     }
152 
writeType(@onnull TypeKey value)153     public void writeType(@Nonnull TypeKey value) throws IOException {
154         writer.writeEncodedUint(ValueType.TYPE, typeSection.getItemIndex(value));
155     }
156 
writeMethodType(@onnull ProtoRefKey value)157     public void writeMethodType(@Nonnull ProtoRefKey value) throws IOException {
158         writer.writeEncodedUint(ValueType.METHOD_TYPE, protoSection.getItemIndex(value));
159     }
160 
writeMethodHandle(@onnull MethodHandleKey value)161     public void writeMethodHandle(@Nonnull MethodHandleKey value) throws IOException {
162         writer.writeEncodedUint(ValueType.METHOD_HANDLE, methodHandleSection.getItemIndex(value));
163     }
164 }
165