17301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver/*
27301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * Copyright 2012, Google Inc.
37301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * All rights reserved.
47301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver *
57301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * Redistribution and use in source and binary forms, with or without
67301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * modification, are permitted provided that the following conditions are
77301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * met:
87301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver *
97301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver *     * Redistributions of source code must retain the above copyright
107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * notice, this list of conditions and the following disclaimer.
117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver *     * Redistributions in binary form must reproduce the above
127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * copyright notice, this list of conditions and the following disclaimer
137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * in the documentation and/or other materials provided with the
147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * distribution.
157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver *     * Neither the name of Google Inc. nor the names of its
167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * contributors may be used to endorse or promote products derived from
177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * this software without specific prior written permission.
187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver *
197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver */
317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruverpackage org.jf.dexlib2.dexbacked;
337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruverimport org.jf.util.ExceptionWithContext;
3560d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruverimport org.jf.util.Utf8Utils;
367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruverimport javax.annotation.Nonnull;
387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruverpublic class BaseDexReader<T extends BaseDexBuffer> {
407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    @Nonnull public final T dexBuf;
417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    private int offset;
427301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public BaseDexReader(@Nonnull T dexBuf, int offset) {
447301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        this.dexBuf = dexBuf;
457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        this.offset = offset;
467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
477301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int getOffset() { return offset; }
497301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void setOffset(int offset) { this.offset = offset; }
507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSleb128() {
528920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int end = dexBuf.baseOffset + offset;
537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int currentByteValue;
547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        result = buf[end++] & 0xff;
587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        if (result <= 0x7f) {
597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            result = (result << 25) >> 25;
607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        } else {
617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            currentByteValue = buf[end++] & 0xff;
627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            if (currentByteValue <= 0x7f) {
647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (result << 18) >> 18;
657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            } else {
667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                currentByteValue = buf[end++] & 0xff;
677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (currentByteValue & 0x7f) << 14;
687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (currentByteValue <= 0x7f) {
697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    result = (result << 11) >> 11;
707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                } else {
717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    currentByteValue = buf[end++] & 0xff;
727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    result |= (currentByteValue & 0x7f) << 21;
737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    if (currentByteValue <= 0x7f) {
747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        result = (result << 4) >> 4;
757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    } else {
767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        currentByteValue = buf[end++] & 0xff;
777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        if (currentByteValue > 0x7f) {
787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            throw new ExceptionWithContext(
797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                                    "Invalid sleb128 integer encountered at offset 0x%x", offset);
807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        }
817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        result |= currentByteValue << 28;
827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    }
837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            }
857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
878920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = end - dexBuf.baseOffset;
887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSmallUleb128() {
9245b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        return readUleb128(false);
9345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    }
9445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver
9545b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    private int readUleb128(boolean allowLarge) {
968920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int end = dexBuf.baseOffset + offset;
977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int currentByteValue;
987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
1007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        result = buf[end++] & 0xff;
1027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        if (result > 0x7f) {
1037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            currentByteValue = buf[end++] & 0xff;
1047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
1057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            if (currentByteValue > 0x7f) {
1067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                currentByteValue = buf[end++] & 0xff;
1077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (currentByteValue & 0x7f) << 14;
1087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (currentByteValue > 0x7f) {
1097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    currentByteValue = buf[end++] & 0xff;
1107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    result |= (currentByteValue & 0x7f) << 21;
1117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    if (currentByteValue > 0x7f) {
1127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        currentByteValue = buf[end++];
1137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        // MSB shouldn't be set on last byte
1157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        if (currentByteValue < 0) {
1167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            throw new ExceptionWithContext(
1177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                                    "Invalid uleb128 integer encountered at offset 0x%x", offset);
1187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        } else if ((currentByteValue & 0xf) > 0x07) {
11945b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                            if (!allowLarge) {
12045b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                // for non-large uleb128s, we assume most significant bit of the result will not be
12145b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                // set, so that it can fit into a signed integer without wrapping
12245b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                throw new ExceptionWithContext(
12345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                        "Encountered valid uleb128 that is out of range at offset 0x%x", offset);
12445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                            }
1257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        }
1267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        result |= currentByteValue << 28;
1277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    }
1287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
1297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            }
1307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
1317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1328920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = end - dexBuf.baseOffset;
1337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
1347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
1357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
136d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver    /**
13745b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     * Reads a "large" uleb128. That is, one that may legitimately be greater than a signed int.
13845b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     *
13945b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     * The value is returned as if it were signed. i.e. a value of 0xFFFFFFFF would be returned as -1. It is up to the
14045b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     * caller to handle the value appropriately.
14145b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     */
14245b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    public int readLargeUleb128() {
14345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver       return readUleb128(true);
14445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    }
14545b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver
14645b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    /**
147d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     * Reads a "big" uleb128 that can legitimately be > 2^31. The value is returned as a signed integer, with the
148d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     * expected semantics of re-interpreting an unsigned value as a signed value.
149d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     *
150d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     * @return The unsigned value, reinterpreted as a signed int
151d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     */
152d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver    public int readBigUleb128() {
1538920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int end = dexBuf.baseOffset + offset;
154d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        int currentByteValue;
155d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        int result;
156d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        byte[] buf = dexBuf.buf;
157d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
158d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        result = buf[end++] & 0xff;
159d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        if (result > 0x7f) {
160d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            currentByteValue = buf[end++] & 0xff;
161d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
162d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            if (currentByteValue > 0x7f) {
163d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                currentByteValue = buf[end++] & 0xff;
164d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                result |= (currentByteValue & 0x7f) << 14;
165d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                if (currentByteValue > 0x7f) {
166d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    currentByteValue = buf[end++] & 0xff;
167d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    result |= (currentByteValue & 0x7f) << 21;
168d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    if (currentByteValue > 0x7f) {
169d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        currentByteValue = buf[end++];
170d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
171d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        // MSB shouldn't be set on last byte
172d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        if (currentByteValue < 0) {
173d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                            throw new ExceptionWithContext(
174d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                                    "Invalid uleb128 integer encountered at offset 0x%x", offset);
175d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        }
176d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        result |= currentByteValue << 28;
177d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    }
178d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                }
179d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            }
180d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        }
181d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
1828920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = end - dexBuf.baseOffset;
183d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        return result;
184d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver    }
185d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
1867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void skipUleb128() {
1878920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int end = dexBuf.baseOffset + offset;
1887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte currentByteValue;
1897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
1907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        currentByteValue = buf[end++];
1927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        if (currentByteValue < 0) { // if the MSB is set
1937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            currentByteValue = buf[end++];
1947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            if (currentByteValue < 0) { // if the MSB is set
1957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                currentByteValue = buf[end++];
1967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (currentByteValue < 0) { // if the MSB is set
1977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    currentByteValue = buf[end++];
1987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    if (currentByteValue < 0) { // if the MSB is set
1997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        currentByteValue = buf[end++];
2007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        if (currentByteValue < 0) {
2017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            throw new ExceptionWithContext(
2027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                                    "Invalid uleb128 integer encountered at offset 0x%x", offset);
2037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        }
2047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    }
2057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
2067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            }
2077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
2087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2098920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = end - dexBuf.baseOffset;
2107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSmallUint() {
2137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readSmallUint(o);
2157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 4;
2167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readOptionalUint() {
2207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readOptionalUint(o);
2227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 4;
2237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int peekUshort() {
2277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return dexBuf.readUshort(offset);
2287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUshort() {
2317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readUshort(offset);
2337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 2;
2347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int peekUbyte() {
2387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return dexBuf.readUbyte(offset);
2397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUbyte() {
2427301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readUbyte(offset);
2447301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 1;
2457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2477301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readLong() {
2497301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        long result = dexBuf.readLong(offset);
2517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 8;
2527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readInt() {
2567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readInt(offset);
2587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 4;
2597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readShort() {
2637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readShort(offset);
2657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 2;
2667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readByte() {
2707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readByte(offset);
2727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 1;
2737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void skipByte() { offset++; }
2777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void moveRelative(int i) { offset += i; }
2787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
2807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUshort(int offset) { return dexBuf.readUshort(offset); }
2817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
2827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readLong(int offset) { return dexBuf.readLong(offset); }
2837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readInt(int offset) { return dexBuf.readInt(offset); }
2847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readShort(int offset) { return dexBuf.readShort(offset); }
2857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readByte(int offset) { return dexBuf.readByte(offset); }
2867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSizedInt(int bytes) {
2888920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int o = dexBuf.baseOffset + offset;
2897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
2907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
2927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
2937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
2947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
2957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
2967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
2977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+3] << 24);
2987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
2997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
3007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
3027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2]) << 16);
3037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
3057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1]) << 8);
3077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
3097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = buf[o];
3107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
3127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
3137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
3148920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = o + bytes - dexBuf.baseOffset;
3157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
3167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
3177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSizedSmallUint(int bytes) {
3198920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int o = dexBuf.baseOffset + offset;
3207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
3217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = 0;
3237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
3247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
3257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                int b = buf[o+3];
3267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (b < 0) {
3277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    throw new ExceptionWithContext(
3287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            "Encountered valid sized uint that is out of range at offset 0x%x", offset);
3297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
3307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = b << 24;
3317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                // fall-through
3327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
3337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (buf[o+2] & 0xff) << 16;
3347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                // fall-through
3357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
3367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (buf[o+1] & 0xff) << 8;
3377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                // fall-through
3387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
3397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (buf[o] & 0xff);
3407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
3427301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
3437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
3448920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = o + bytes - dexBuf.baseOffset;
3457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
3467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
3477301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSizedRightExtendedInt(int bytes) {
3498920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int o = dexBuf.baseOffset + offset;
3507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
3517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
3537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
3547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
3557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
3577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
3587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+3] << 24);
3597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
3617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) << 8 |
3627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 16) |
3637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+2] << 24);
3647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
3667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) << 16 |
3677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+1] << 24);
3687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
3707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = buf[o] << 24;
3717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
3737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext(
3747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        "Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
3757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
3768920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = o + bytes - dexBuf.baseOffset;
3777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
3787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
3797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readSizedRightExtendedLong(int bytes) {
3818920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int o = dexBuf.baseOffset + offset;
3827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
3837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        long result;
3857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
3867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 8:
3877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
3897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
3907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
3917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
3927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 40) |
3937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+6] & 0xffL) << 48) |
3947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+7]) << 56);
3957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 7:
3977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xff)) << 8 |
3987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 16) |
3997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 24) |
4007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 32) |
4017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 40) |
4027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 48) |
4037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+6]) << 56);
4047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 6:
4067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xff)) << 16 |
4077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 24) |
4087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 32) |
4097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 40) |
4107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 48) |
4117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+5]) << 56);
4127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 5:
4147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 24 |
4157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 32) |
4167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 40) |
4177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 48) |
4187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+4]) << 56);
4197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
4217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 32 |
4227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 40) |
4237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 48) |
4247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+3]) << 56);
4257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
4277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 40 |
4287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 48) |
4297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+2]) << 56);
4307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
4327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 48 |
4337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+1]) << 56);
4347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
4367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((long)buf[o]) << 56;
4377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
4397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext(
4407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        "Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
4417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
4428920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = o + bytes - dexBuf.baseOffset;
4437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
4447301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
4457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
4467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readSizedLong(int bytes) {
4478920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        int o = dexBuf.baseOffset + offset;
4487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
4497301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
4507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        long result;
4517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
4527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 8:
4537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
4587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 40) |
4597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+6] & 0xffL) << 48) |
4607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+7]) << 56);
4617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 7:
4637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
4687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 40) |
4697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((long)(buf[o+6]) << 48);
4707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 6:
4727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
4777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((long)(buf[o+5]) << 40);
4787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 5:
4807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((long)(buf[o+4]) << 32);
4857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
4877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+3]) << 24);
4917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
4937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+2] << 16);
4967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
4987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+1] << 8);
5007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
5017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
5027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = buf[o];
5037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
5047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
5057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
5067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
5077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
5088920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        offset = o + bytes - dexBuf.baseOffset;
5097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
5107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
51160d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver
51260d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver    public String readString(int utf16Length) {
51360d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        int[] ret = new int[1];
5148920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver        String value = Utf8Utils.utf8BytesWithUtf16LengthToString(
5158920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver                dexBuf.buf, dexBuf.baseOffset + offset, utf16Length, ret);
51660d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        offset += ret[0];
51760d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        return value;
51860d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver    }
5197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver}
520