1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dexfuzz.rawdex; 18 19 import java.io.IOException; 20 21 public class EncodedValue implements RawDexObject { 22 public byte valueArg; 23 public byte valueType; 24 public byte[] value; 25 public EncodedArray encodedArray; 26 public EncodedAnnotation encodedAnnotation; 27 28 private static final byte VALUE_BYTE = 0x00; 29 private static final byte VALUE_ARRAY = 0x1c; 30 private static final byte VALUE_ANNOTATION = 0x1d; 31 private static final byte VALUE_NULL = 0x1e; 32 private static final byte VALUE_BOOLEAN = 0x1f; 33 34 @Override read(DexRandomAccessFile file)35 public void read(DexRandomAccessFile file) throws IOException { 36 int valueArgAndType = file.readUnsignedByte(); 37 38 // Get lower 5 bits. 39 valueType = (byte) (valueArgAndType & 0x1f); 40 // Get upper 3 bits. 41 valueArg = (byte) ((valueArgAndType & 0xe0) >> 5); 42 43 int size = 0; 44 45 switch (valueType) { 46 case VALUE_BYTE: 47 size = 1; 48 break; 49 case VALUE_ARRAY: 50 (encodedArray = new EncodedArray()).read(file); 51 size = 0; // So we don't read into value. 52 break; 53 case VALUE_ANNOTATION: 54 (encodedAnnotation = new EncodedAnnotation()).read(file); 55 size = 0; // So we don't read into value. 56 break; 57 case VALUE_NULL: 58 case VALUE_BOOLEAN: 59 // No value 60 size = 0; 61 break; 62 default: 63 // All others encode value_arg as (size - 1), so... 64 size = valueArg + 1; 65 break; 66 } 67 68 if (size != 0) { 69 value = new byte[size]; 70 for (int i = 0; i < size; i++) { 71 value[i] = file.readByte(); 72 } 73 } 74 } 75 76 @Override write(DexRandomAccessFile file)77 public void write(DexRandomAccessFile file) throws IOException { 78 int valueArgAndType = ((valueType) | (valueArg << 5)); 79 file.writeByte(valueArgAndType); 80 81 if (encodedArray != null) { 82 encodedArray.write(file); 83 } else if (encodedAnnotation != null) { 84 encodedAnnotation.write(file); 85 } else if (value != null) { 86 file.write(value); 87 } 88 } 89 90 @Override incrementIndex(IndexUpdateKind kind, int insertedIdx)91 public void incrementIndex(IndexUpdateKind kind, int insertedIdx) { 92 if (encodedArray != null) { 93 encodedArray.incrementIndex(kind, insertedIdx); 94 } else if (encodedAnnotation != null) { 95 encodedAnnotation.incrementIndex(kind, insertedIdx); 96 } 97 } 98 } 99