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.builder;
33 
34 import org.jf.dexlib2.base.value.*;
35 import org.jf.dexlib2.iface.value.EncodedValue;
36 import org.jf.dexlib2.immutable.value.*;
37 import org.jf.util.ExceptionWithContext;
38 
39 import javax.annotation.Nonnull;
40 import java.util.List;
41 import java.util.Set;
42 
43 public abstract class BuilderEncodedValues {
44     public static interface BuilderEncodedValue extends EncodedValue {
45     }
46 
47     public static class BuilderAnnotationEncodedValue extends BaseAnnotationEncodedValue
48             implements BuilderEncodedValue {
49         @Nonnull final BuilderTypeReference typeReference;
50         @Nonnull final Set<? extends BuilderAnnotationElement> elements;
51 
BuilderAnnotationEncodedValue(@onnull BuilderTypeReference typeReference, @Nonnull Set<? extends BuilderAnnotationElement> elements)52         BuilderAnnotationEncodedValue(@Nonnull BuilderTypeReference typeReference,
53                                       @Nonnull Set<? extends BuilderAnnotationElement> elements) {
54             this.typeReference = typeReference;
55             this.elements = elements;
56         }
57 
getType()58         @Nonnull @Override public String getType() {
59             return typeReference.getType();
60         }
61 
getElements()62         @Nonnull @Override public Set<? extends BuilderAnnotationElement> getElements() {
63             return elements;
64         }
65     }
66 
67     public static class BuilderArrayEncodedValue extends BaseArrayEncodedValue implements BuilderEncodedValue {
68         @Nonnull final List<? extends BuilderEncodedValue> elements;
69 
BuilderArrayEncodedValue(@onnull List<? extends BuilderEncodedValue> elements)70         BuilderArrayEncodedValue(@Nonnull List<? extends BuilderEncodedValue> elements) {
71             this.elements = elements;
72         }
73 
getValue()74         @Nonnull @Override public List<? extends EncodedValue> getValue() {
75             return elements;
76         }
77     }
78 
79     @Nonnull
defaultValueForType(String type)80     public static BuilderEncodedValue defaultValueForType(String type) {
81         switch (type.charAt(0)) {
82             case 'Z':
83                 return BuilderBooleanEncodedValue.FALSE_VALUE;
84             case 'B':
85                 return new BuilderByteEncodedValue((byte)0);
86             case 'S':
87                 return new BuilderShortEncodedValue((short)0);
88             case 'C':
89                 return new BuilderCharEncodedValue((char)0);
90             case 'I':
91                 return new BuilderIntEncodedValue(0);
92             case 'J':
93                 return new BuilderLongEncodedValue(0);
94             case 'F':
95                 return new BuilderFloatEncodedValue(0);
96             case 'D':
97                 return new BuilderDoubleEncodedValue(0);
98             case 'L':
99             case '[':
100                 return BuilderNullEncodedValue.INSTANCE;
101             default:
102                 throw new ExceptionWithContext("Unrecognized type: %s", type);
103         }
104     }
105 
106     public static class BuilderBooleanEncodedValue extends BaseBooleanEncodedValue
107             implements BuilderEncodedValue {
108         public static final BuilderBooleanEncodedValue TRUE_VALUE = new BuilderBooleanEncodedValue(true);
109         public static final BuilderBooleanEncodedValue FALSE_VALUE = new BuilderBooleanEncodedValue(false);
110 
111         private final boolean value;
112 
BuilderBooleanEncodedValue(boolean value)113         private BuilderBooleanEncodedValue(boolean value) {
114             this.value = value;
115         }
116 
getValue()117         @Override public boolean getValue() {
118             return value;
119         }
120     }
121 
122     public static class BuilderByteEncodedValue extends ImmutableByteEncodedValue
123             implements BuilderEncodedValue {
BuilderByteEncodedValue(byte value)124         public BuilderByteEncodedValue(byte value) {
125             super(value);
126         }
127     }
128 
129     public static class BuilderCharEncodedValue extends ImmutableCharEncodedValue
130             implements BuilderEncodedValue {
BuilderCharEncodedValue(char value)131         public BuilderCharEncodedValue(char value) {
132             super(value);
133         }
134     }
135 
136     public static class BuilderDoubleEncodedValue extends ImmutableDoubleEncodedValue
137             implements BuilderEncodedValue {
BuilderDoubleEncodedValue(double value)138         public BuilderDoubleEncodedValue(double value) {
139             super(value);
140         }
141     }
142 
143     public static class BuilderEnumEncodedValue extends BaseEnumEncodedValue
144             implements BuilderEncodedValue {
145         @Nonnull final BuilderFieldReference enumReference;
146 
BuilderEnumEncodedValue(@onnull BuilderFieldReference enumReference)147         BuilderEnumEncodedValue(@Nonnull BuilderFieldReference enumReference) {
148             this.enumReference = enumReference;
149         }
150 
getValue()151         @Nonnull @Override public BuilderFieldReference getValue() {
152             return enumReference;
153         }
154     }
155 
156     public static class BuilderFieldEncodedValue extends BaseFieldEncodedValue
157             implements BuilderEncodedValue {
158         @Nonnull final BuilderFieldReference fieldReference;
159 
BuilderFieldEncodedValue(@onnull BuilderFieldReference fieldReference)160         BuilderFieldEncodedValue(@Nonnull BuilderFieldReference fieldReference) {
161             this.fieldReference = fieldReference;
162         }
163 
getValue()164         @Nonnull @Override public BuilderFieldReference getValue() {
165             return fieldReference;
166         }
167     }
168 
169     public static class BuilderFloatEncodedValue extends ImmutableFloatEncodedValue
170             implements BuilderEncodedValue {
BuilderFloatEncodedValue(float value)171         public BuilderFloatEncodedValue(float value) {
172             super(value);
173         }
174     }
175 
176     public static class BuilderIntEncodedValue extends ImmutableIntEncodedValue
177             implements BuilderEncodedValue {
BuilderIntEncodedValue(int value)178         public BuilderIntEncodedValue(int value) {
179             super(value);
180         }
181     }
182 
183     public static class BuilderLongEncodedValue extends ImmutableLongEncodedValue
184             implements BuilderEncodedValue {
BuilderLongEncodedValue(long value)185         public BuilderLongEncodedValue(long value) {
186             super(value);
187         }
188     }
189 
190     public static class BuilderMethodEncodedValue extends BaseMethodEncodedValue
191             implements BuilderEncodedValue {
192         @Nonnull final BuilderMethodReference methodReference;
193 
BuilderMethodEncodedValue(@onnull BuilderMethodReference methodReference)194         BuilderMethodEncodedValue(@Nonnull BuilderMethodReference methodReference) {
195             this.methodReference = methodReference;
196         }
197 
getValue()198         @Override public BuilderMethodReference getValue() {
199             return methodReference;
200         }
201     }
202 
203     public static class BuilderNullEncodedValue extends BaseNullEncodedValue
204             implements BuilderEncodedValue {
205         public static final BuilderNullEncodedValue INSTANCE = new BuilderNullEncodedValue();
206 
BuilderNullEncodedValue()207         private BuilderNullEncodedValue() {}
208     }
209 
210     public static class BuilderShortEncodedValue extends ImmutableShortEncodedValue
211             implements BuilderEncodedValue {
BuilderShortEncodedValue(short value)212         public BuilderShortEncodedValue(short value) {
213             super(value);
214         }
215     }
216 
217     public static class BuilderStringEncodedValue extends BaseStringEncodedValue
218             implements BuilderEncodedValue {
219         @Nonnull final BuilderStringReference stringReference;
220 
BuilderStringEncodedValue(@onnull BuilderStringReference stringReference)221         BuilderStringEncodedValue(@Nonnull BuilderStringReference stringReference) {
222             this.stringReference = stringReference;
223         }
224 
getValue()225         @Nonnull @Override public String getValue() {
226             return stringReference.getString();
227         }
228     }
229 
230     public static class BuilderTypeEncodedValue extends BaseTypeEncodedValue
231             implements BuilderEncodedValue {
232         @Nonnull final BuilderTypeReference typeReference;
233 
BuilderTypeEncodedValue(@onnull BuilderTypeReference typeReference)234         BuilderTypeEncodedValue(@Nonnull BuilderTypeReference typeReference) {
235             this.typeReference = typeReference;
236         }
237 
getValue()238         @Nonnull @Override public String getValue() {
239             return typeReference.getType();
240         }
241     }
242 }
243