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