DexBackedEncodedValue.java revision bddef6af3c39732ba0329c4a8e233f3858226f39
1be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver/* 2be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Copyright 2012, Google Inc. 3be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * All rights reserved. 4be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * 5be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Redistribution and use in source and binary forms, with or without 6be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * modification, are permitted provided that the following conditions are 7be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * met: 8be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * 9be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * * Redistributions of source code must retain the above copyright 10be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * notice, this list of conditions and the following disclaimer. 11be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * * Redistributions in binary form must reproduce the above 12be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * copyright notice, this list of conditions and the following disclaimer 13be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * in the documentation and/or other materials provided with the 14be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * distribution. 15be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * * Neither the name of Google Inc. nor the names of its 16be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * contributors may be used to endorse or promote products derived from 17be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * this software without specific prior written permission. 18be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * 19be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver */ 31be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 32be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverpackage org.jf.dexlib2.dexbacked.value; 33be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 34f4662586da3c902c3a0ed21a174b814e248c7fb8Ben Gruverimport org.jf.dexlib2.ValueType; 35f4662586da3c902c3a0ed21a174b814e248c7fb8Ben Gruverimport org.jf.dexlib2.dexbacked.DexReader; 36be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.iface.value.EncodedValue; 377c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.dexlib2.immutable.value.*; 387c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.dexlib2.util.Preconditions; 397c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverimport org.jf.util.ExceptionWithContext; 40be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 4125d385a441b95d56987c81f00f19297d799e1b31Ben Gruverimport javax.annotation.Nonnull; 4225d385a441b95d56987c81f00f19297d799e1b31Ben Gruver 437c71ad420dbdfe2e36f205d335a261435181a25bBen Gruverpublic abstract class DexBackedEncodedValue { 4425d385a441b95d56987c81f00f19297d799e1b31Ben Gruver @Nonnull 4525d385a441b95d56987c81f00f19297d799e1b31Ben Gruver public static EncodedValue readFrom(@Nonnull DexReader reader) { 467c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int startOffset = reader.getOffset(); 47be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 487c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver try { 497c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int b = reader.readUbyte(); 507c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueType = b & 0x1f; 517c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueArg = b >>> 5; 52be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 537c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver switch (valueType) { 547c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BYTE: 557c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 0); 567c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableByteEncodedValue((byte)reader.readByte()); 577c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.SHORT: 587c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 1); 597c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableShortEncodedValue((short)reader.readSizedInt(valueArg + 1)); 607c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.CHAR: 617c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 1); 627c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableCharEncodedValue((char)reader.readSizedSmallUint(valueArg + 1)); 637c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.INT: 647c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 657c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableIntEncodedValue(reader.readSizedInt(valueArg + 1)); 667c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.LONG: 677c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 7); 687c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableLongEncodedValue(reader.readSizedLong(valueArg + 1)); 697c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FLOAT: 707c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 717c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableFloatEncodedValue(Float.intBitsToFloat( 72a88239d92d47b45f0e2f9637afeacabcb9e4f3aeBen Gruver reader.readSizedRightExtendedInt(valueArg + 1))); 737c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.DOUBLE: 747c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 7); 757c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new ImmutableDoubleEncodedValue(Double.longBitsToDouble( 76a88239d92d47b45f0e2f9637afeacabcb9e4f3aeBen Gruver reader.readSizedRightExtendedLong(valueArg + 1))); 777c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.STRING: 787c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 7922c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedStringEncodedValue(reader, valueArg); 807c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.TYPE: 817c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 82fd26bc6062ab671ad7675c7cca0465b74723f16bBen Gruver return new ImmutableTypeEncodedValue(reader.dexBuf.getType( 83fd26bc6062ab671ad7675c7cca0465b74723f16bBen Gruver reader.readSizedSmallUint(valueArg + 1))); 847c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FIELD: 857c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 8622c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedFieldEncodedValue(reader, valueArg); 877c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.METHOD: 887c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 8922c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedMethodEncodedValue(reader, valueArg); 907c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ENUM: 917c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 3); 9222c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return new DexBackedEnumEncodedValue(reader, valueArg); 937c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ARRAY: 947c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 0); 957c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new DexBackedArrayEncodedValue(reader); 967c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ANNOTATION: 977c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 0); 987c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return new DexBackedAnnotationEncodedValue(reader); 997c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.NULL: 10022c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver Preconditions.checkValueArg(valueArg, 0); 1017c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver return ImmutableNullEncodedValue.INSTANCE; 1027c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BOOLEAN: 1037c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver Preconditions.checkValueArg(valueArg, 1); 104bddef6af3c39732ba0329c4a8e233f3858226f39Ben Gruver return ImmutableBooleanEncodedValue.forBoolean(valueArg == 1); 1057c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver default: 1067c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw new ExceptionWithContext("Invalid encoded_value type: 0x%x", valueType); 1077c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 1087c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } catch (Exception ex) { 1097c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw ExceptionWithContext.withContext(ex, "Error while reading encoded value at offset 0x%x", startOffset); 1107c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 111be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 112be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver 11325d385a441b95d56987c81f00f19297d799e1b31Ben Gruver public static void skipFrom(@Nonnull DexReader reader) { 1147c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int startOffset = reader.getOffset(); 1157c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver 1167c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver try { 1177c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int b = reader.readUbyte(); 1187c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueType = b & 0x1f; 1197c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver 1207c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver switch (valueType) { 1217c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BYTE: 1227c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver reader.skipByte(); 1237c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1247c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.SHORT: 1257c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.CHAR: 1267c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.INT: 1277c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.LONG: 1287c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FLOAT: 1297c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.DOUBLE: 1307c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.STRING: 1317c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.TYPE: 1327c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.FIELD: 1337c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.METHOD: 1347c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ENUM: 1357c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver int valueArg = b >>> 5; 13668f69b899ff18bf6ced6249d48dd7f059a51255fBen Gruver reader.moveRelative(valueArg+1); 1377c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1387c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ARRAY: 1397c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver DexBackedArrayEncodedValue.skipFrom(reader); 1407c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1417c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.ANNOTATION: 1427c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver DexBackedAnnotationEncodedValue.skipFrom(reader); 1437c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1447c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.NULL: 1457c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver case ValueType.BOOLEAN: 1467c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver break; 1477c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver default: 1487c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw new ExceptionWithContext("Invalid encoded_value type: 0x%x", valueType); 1497c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 1507c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } catch (Exception ex) { 1517c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver throw ExceptionWithContext.withContext(ex, "Error while skipping encoded value at offset 0x%x", 1527c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver startOffset); 1537c71ad420dbdfe2e36f205d335a261435181a25bBen Gruver } 154be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver } 155be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver} 156