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    /** {@inheritDoc} */
527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSleb128() {
537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int end = offset;
547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int currentByteValue;
557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        result = buf[end++] & 0xff;
597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        if (result <= 0x7f) {
607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            result = (result << 25) >> 25;
617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        } else {
627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            currentByteValue = buf[end++] & 0xff;
637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            if (currentByteValue <= 0x7f) {
657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (result << 18) >> 18;
667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            } else {
677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                currentByteValue = buf[end++] & 0xff;
687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (currentByteValue & 0x7f) << 14;
697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (currentByteValue <= 0x7f) {
707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    result = (result << 11) >> 11;
717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                } else {
727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    currentByteValue = buf[end++] & 0xff;
737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    result |= (currentByteValue & 0x7f) << 21;
747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    if (currentByteValue <= 0x7f) {
757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        result = (result << 4) >> 4;
767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    } else {
777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        currentByteValue = buf[end++] & 0xff;
787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        if (currentByteValue > 0x7f) {
797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            throw new ExceptionWithContext(
807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                                    "Invalid sleb128 integer encountered at offset 0x%x", offset);
817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        }
827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        result |= currentByteValue << 28;
837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    }
847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            }
867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = end;
897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSmallUleb128() {
9345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver        return readUleb128(false);
9445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    }
9545b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver
9645b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    private int readUleb128(boolean allowLarge) {
977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int end = offset;
987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int currentByteValue;
997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
1007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
1017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        result = buf[end++] & 0xff;
1037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        if (result > 0x7f) {
1047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            currentByteValue = buf[end++] & 0xff;
1057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
1067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            if (currentByteValue > 0x7f) {
1077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                currentByteValue = buf[end++] & 0xff;
1087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (currentByteValue & 0x7f) << 14;
1097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (currentByteValue > 0x7f) {
1107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    currentByteValue = buf[end++] & 0xff;
1117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    result |= (currentByteValue & 0x7f) << 21;
1127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    if (currentByteValue > 0x7f) {
1137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        currentByteValue = buf[end++];
1147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        // MSB shouldn't be set on last byte
1167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        if (currentByteValue < 0) {
1177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            throw new ExceptionWithContext(
1187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                                    "Invalid uleb128 integer encountered at offset 0x%x", offset);
1197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        } else if ((currentByteValue & 0xf) > 0x07) {
12045b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                            if (!allowLarge) {
12145b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                // for non-large uleb128s, we assume most significant bit of the result will not be
12245b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                // set, so that it can fit into a signed integer without wrapping
12345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                throw new ExceptionWithContext(
12445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                                        "Encountered valid uleb128 that is out of range at offset 0x%x", offset);
12545b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver                            }
1267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        }
1277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        result |= currentByteValue << 28;
1287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    }
1297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
1307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            }
1317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
1327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = end;
1347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
1357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
1367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
137d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver    /**
13845b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     * Reads a "large" uleb128. That is, one that may legitimately be greater than a signed int.
13945b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     *
14045b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben 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
14145b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     * caller to handle the value appropriately.
14245b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver     */
14345b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    public int readLargeUleb128() {
14445b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver       return readUleb128(true);
14545b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    }
14645b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver
14745b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver    /**
148d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     * Reads a "big" uleb128 that can legitimately be > 2^31. The value is returned as a signed integer, with the
149d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     * expected semantics of re-interpreting an unsigned value as a signed value.
150d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     *
151d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     * @return The unsigned value, reinterpreted as a signed int
152d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver     */
153d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver    public int readBigUleb128() {
154d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        int end = offset;
155d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        int currentByteValue;
156d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        int result;
157d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        byte[] buf = dexBuf.buf;
158d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
159d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        result = buf[end++] & 0xff;
160d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        if (result > 0x7f) {
161d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            currentByteValue = buf[end++] & 0xff;
162d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
163d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            if (currentByteValue > 0x7f) {
164d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                currentByteValue = buf[end++] & 0xff;
165d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                result |= (currentByteValue & 0x7f) << 14;
166d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                if (currentByteValue > 0x7f) {
167d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    currentByteValue = buf[end++] & 0xff;
168d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    result |= (currentByteValue & 0x7f) << 21;
169d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    if (currentByteValue > 0x7f) {
170d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        currentByteValue = buf[end++];
171d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
172d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        // MSB shouldn't be set on last byte
173d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        if (currentByteValue < 0) {
174d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                            throw new ExceptionWithContext(
175d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                                    "Invalid uleb128 integer encountered at offset 0x%x", offset);
176d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        }
177d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                        result |= currentByteValue << 28;
178d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                    }
179d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver                }
180d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver            }
181d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        }
182d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
183d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        offset = end;
184d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver        return result;
185d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver    }
186d38f3a79838220a666f80c7c2495a184d319a960Ben Gruver
1877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void skipUleb128() {
1887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int end = offset;
1897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte currentByteValue;
1907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
1917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
1927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        currentByteValue = buf[end++];
1937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        if (currentByteValue < 0) { // if the MSB is set
1947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            currentByteValue = buf[end++];
1957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            if (currentByteValue < 0) { // if the MSB is set
1967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                currentByteValue = buf[end++];
1977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (currentByteValue < 0) { // if the MSB is set
1987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    currentByteValue = buf[end++];
1997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    if (currentByteValue < 0) { // if the MSB is set
2007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        currentByteValue = buf[end++];
2017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        if (currentByteValue < 0) {
2027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            throw new ExceptionWithContext(
2037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                                    "Invalid uleb128 integer encountered at offset 0x%x", offset);
2047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        }
2057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    }
2067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
2077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            }
2087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
2097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = end;
2117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSmallUint() {
2147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readSmallUint(o);
2167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 4;
2177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readOptionalUint() {
2217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readOptionalUint(o);
2237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 4;
2247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int peekUshort() {
2287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return dexBuf.readUshort(offset);
2297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUshort() {
2327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readUshort(offset);
2347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 2;
2357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int peekUbyte() {
2397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return dexBuf.readUbyte(offset);
2407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2427301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUbyte() {
2437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2447301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readUbyte(offset);
2457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 1;
2467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2477301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2497301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readLong() {
2507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        long result = dexBuf.readLong(offset);
2527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 8;
2537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readInt() {
2577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readInt(offset);
2597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 4;
2607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readShort() {
2647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readShort(offset);
2667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 2;
2677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readByte() {
2717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = dexBuf.readByte(offset);
2737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + 1;
2747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
2757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
2767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void skipByte() { offset++; }
2787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public void moveRelative(int i) { offset += i; }
2797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
2817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUshort(int offset) { return dexBuf.readUshort(offset); }
2827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
2837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readLong(int offset) { return dexBuf.readLong(offset); }
2847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readInt(int offset) { return dexBuf.readInt(offset); }
2857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readShort(int offset) { return dexBuf.readShort(offset); }
2867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readByte(int offset) { return dexBuf.readByte(offset); }
2877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSizedInt(int bytes) {
2897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
2907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
2917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
2927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
2937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
2947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
2957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
2967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
2977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
2987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+3] << 24);
2997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
3017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
3037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2]) << 16);
3047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
3067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1]) << 8);
3087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
3107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = buf[o];
3117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
3137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
3147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
3157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + bytes;
3167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
3177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
3187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSizedSmallUint(int bytes) {
3207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
3217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
3227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result = 0;
3247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
3257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
3267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                int b = buf[o+3];
3277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                if (b < 0) {
3287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                    throw new ExceptionWithContext(
3297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                            "Encountered valid sized uint that is out of range at offset 0x%x", offset);
3307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                }
3317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = b << 24;
3327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                // fall-through
3337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
3347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (buf[o+2] & 0xff) << 16;
3357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                // fall-through
3367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
3377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (buf[o+1] & 0xff) << 8;
3387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                // fall-through
3397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
3407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result |= (buf[o] & 0xff);
3417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3427301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
3437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
3447301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
3457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + bytes;
3467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
3477301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
3487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3497301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public int readSizedRightExtendedInt(int bytes) {
3507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
3517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
3527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int result;
3547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
3557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
3567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
3587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
3597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+3] << 24);
3607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
3627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) << 8 |
3637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 16) |
3647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+2] << 24);
3657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
3677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) << 16 |
3687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+1] << 24);
3697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
3717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = buf[o] << 24;
3727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
3747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext(
3757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        "Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
3767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
3777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + bytes;
3787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
3797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
3807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readSizedRightExtendedLong(int bytes) {
3827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
3837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
3847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
3857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        long result;
3867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
3877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 8:
3887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
3897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
3907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
3917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
3927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
3937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 40) |
3947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+6] & 0xffL) << 48) |
3957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+7]) << 56);
3967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
3977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 7:
3987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xff)) << 8 |
3997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 16) |
4007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 24) |
4017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 32) |
4027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 40) |
4037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 48) |
4047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+6]) << 56);
4057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 6:
4077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xff)) << 16 |
4087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 24) |
4097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 32) |
4107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 40) |
4117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 48) |
4127301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+5]) << 56);
4137301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4147301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 5:
4157301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 24 |
4167301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 32) |
4177301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 40) |
4187301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 48) |
4197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+4]) << 56);
4207301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4217301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
4227301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 32 |
4237301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 40) |
4247301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xffL) << 48) |
4257301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+3]) << 56);
4267301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4277301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
4287301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 40 |
4297301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xffL) << 48) |
4307301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+2]) << 56);
4317301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4327301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
4337301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((buf[o] & 0xffL)) << 48 |
4347301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+1]) << 56);
4357301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4367301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
4377301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = ((long)buf[o]) << 56;
4387301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4397301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
4407301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext(
4417301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        "Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
4427301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
4437301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + bytes;
4447301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
4457301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
4467301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
4477301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    public long readSizedLong(int bytes) {
4487301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        int o = offset;
4497301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        byte[] buf = dexBuf.buf;
4507301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
4517301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        long result;
4527301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        switch (bytes) {
4537301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 8:
4547301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4557301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4567301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4577301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4587301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
4597301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 40) |
4607301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+6] & 0xffL) << 48) |
4617301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+7]) << 56);
4627301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4637301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 7:
4647301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4657301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4667301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4677301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4687301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
4697301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+5] & 0xffL) << 40) |
4707301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((long)(buf[o+6]) << 48);
4717301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4727301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 6:
4737301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4747301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4757301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4767301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4777301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+4] & 0xffL) << 32) |
4787301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((long)(buf[o+5]) << 40);
4797301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4807301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 5:
4817301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4827301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4837301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4847301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+3] & 0xffL) << 24) |
4857301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((long)(buf[o+4]) << 32);
4867301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4877301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 4:
4887301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4897301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4907301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+2] & 0xff) << 16) |
4917301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (((long)buf[o+3]) << 24);
4927301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4937301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 3:
4947301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
4957301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        ((buf[o+1] & 0xff) << 8) |
4967301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+2] << 16);
4977301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
4987301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 2:
4997301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = (buf[o] & 0xff) |
5007301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                        (buf[o+1] << 8);
5017301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
5027301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            case 1:
5037301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                result = buf[o];
5047301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                break;
5057301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver            default:
5067301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver                throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
5077301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        }
5087301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver
5097301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        offset = o + bytes;
5107301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver        return result;
5117301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver    }
51260d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver
51360d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver    public String readString(int utf16Length) {
51460d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        int[] ret = new int[1];
51560d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        String value = Utf8Utils.utf8BytesWithUtf16LengthToString(dexBuf.buf, offset, utf16Length, ret);
51660d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        offset += ret[0];
51760d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver        return value;
51860d834f95104bcbe856f4100ec967f4aae67eb04Ben Gruver    }
5197301fbe30e6661c67c33552efd28a8d7587aba3dBen Gruver}
520