EncodedValue.java revision 8543d8b6262a3f89b1c757fd9c39cac9487a5804
1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2009 Ben Gruver 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29package org.jf.dexlib.EncodedValue; 30 31import org.jf.dexlib.CompositeField; 32import org.jf.dexlib.DexFile; 33import org.jf.dexlib.Field; 34import org.jf.dexlib.util.AnnotatedOutput; 35import org.jf.dexlib.util.Input; 36 37public class EncodedValue extends CompositeField<EncodedValue> { 38 private class ValueTypeArgField implements Field<ValueTypeArgField> { 39 private ValueType valueType; 40 private byte valueArg; 41 42 public ValueTypeArgField() { 43 } 44 45 public ValueTypeArgField(ValueType valueType) { 46 this.valueType = valueType; 47 } 48 49 public void writeTo(AnnotatedOutput out) { 50 out.annotate(1, "valuetype=" + Integer.toString(valueType.getMapValue()) + " valueArg=" + Integer.toString(valueArg)); 51 byte value = (byte)(valueType.getMapValue() | (valueArg << 5)); 52 out.writeByte(value); 53 } 54 55 public void readFrom(Input in) { 56 byte value = in.readByte(); 57 valueType = ValueType.fromByte((byte)(value & 0x1F)); 58 valueArg = (byte)((value & 0xFF) >>> 5); 59 } 60 61 public int place(int offset) { 62 return offset + 1; 63 } 64 65 public ValueType getValueType() { 66 return valueType; 67 } 68 69 public byte getValueArg() { 70 return valueArg; 71 } 72 73 public void copyTo(DexFile dexFile, ValueTypeArgField copy) { 74 copy.valueType = valueType; 75 copy.valueArg = valueArg; 76 } 77 78 public int hashCode() { 79 return valueType.hashCode() * 31 + ((Byte)valueArg).hashCode(); 80 } 81 82 public boolean equals(Object o) { 83 if (!(o instanceof ValueTypeArgField)) { 84 return false; 85 } 86 87 ValueTypeArgField other = (ValueTypeArgField)o; 88 return valueType.equals(other.valueType) && (valueArg == other.valueArg); 89 } 90 } 91 92 private class EncodedValueSubFieldWrapper implements Field<EncodedValueSubFieldWrapper> { 93 private final DexFile dexFile; 94 private EncodedValueSubField subField; 95 96 public EncodedValueSubFieldWrapper(DexFile dexFile) { 97 this.dexFile = dexFile; 98 } 99 100 public EncodedValueSubFieldWrapper(DexFile dexFile, EncodedValueSubField subField) { 101 this.dexFile = dexFile; 102 this.subField = subField; 103 } 104 105 public void writeTo(AnnotatedOutput out) { 106 subField.writeTo(out); 107 } 108 109 public void readFrom(Input in) { 110 subField = EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, getValueType()); 111 subField.setInitialValueArg(getValueArg()); 112 subField.readFrom(in); 113 } 114 115 public int place(int offset) { 116 return subField.place(offset); 117 } 118 119 public EncodedValueSubField getEncodedValueSubField() { 120 return subField; 121 } 122 123 public void copyTo(DexFile dexFile, EncodedValueSubFieldWrapper copy) { 124 EncodedValueSubField fieldCopy = EncodedValueSubFieldFactory.makeEncodedValueField(dexFile, getValueType()); 125 copy.subField = fieldCopy; 126 127 //both fields should be the same type because they were both made with the a call to 128 //EncodedValueSubFieldFactory.makeEncodedValueField using the same value type. 129 subField.copyTo(dexFile, fieldCopy); 130 } 131 132 public int hashCode() { 133 return subField.hashCode(); 134 } 135 136 public boolean equals(Object o) { 137 if (!(o instanceof EncodedValueSubFieldWrapper)) { 138 return false; 139 } 140 141 EncodedValueSubFieldWrapper other = (EncodedValueSubFieldWrapper)o; 142 return subField.equals(other.subField); 143 } 144 } 145 146 private final ValueTypeArgField valueTypeArg; 147 private final EncodedValueSubFieldWrapper encodedValue; 148 149 public EncodedValue(final DexFile dexFile) { 150 super("encoded_value"); 151 fields = new Field[] { 152 valueTypeArg = new ValueTypeArgField(), 153 encodedValue = new EncodedValueSubFieldWrapper(dexFile) 154 }; 155 } 156 157 public EncodedValue(final DexFile dexFile, EncodedValueSubField subField) { 158 super("encoded_value"); 159 fields = new Field[] { 160 valueTypeArg = new ValueTypeArgField(subField.getValueType()), 161 encodedValue = new EncodedValueSubFieldWrapper(dexFile, subField) 162 }; 163 } 164 165 public int place(int offset) { 166 offset = valueTypeArg.place(offset); 167 int ret = encodedValue.place(offset); 168 169 valueTypeArg.valueArg = encodedValue.getEncodedValueSubField().getValueArg(); 170 return ret; 171 } 172 173 public ValueType getValueType() { 174 return valueTypeArg.getValueType(); 175 } 176 177 public byte getValueArg() { 178 return valueTypeArg.getValueArg(); 179 } 180 181 public EncodedValueSubField getValue() { 182 return encodedValue.getEncodedValueSubField(); 183 } 184} 185