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