ByteArrayInput.java revision 7ed253b78bd28abb0a56463ca26bb26c1c07302c
15867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com/* 2a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Copyright (C) 2007 The Android Open Source Project 35867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 4a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Licensed under the Apache License, Version 2.0 (the "License"); 5a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * you may not use this file except in compliance with the License. 6a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * You may obtain a copy of the License at 75867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 8a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * http://www.apache.org/licenses/LICENSE-2.0 9a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * 10a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Unless required by applicable law or agreed to in writing, software 11a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * distributed under the License is distributed on an "AS IS" BASIS, 12a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * See the License for the specific language governing permissions and 14a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * limitations under the License. 155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 17128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com/* 18128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * As per the Apache license requirements, this file has been modified 19128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * from its original state. 20128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * 21128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * Such modifications are Copyright (C) 2010 Ben Gruver, and are released 22128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * under the original license 23128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com */ 24128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com 255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compackage org.jf.dexlib.Util; 265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com/** 285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Implementation of {@link Input} which reads the data from a 295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * <code>byte[]</code> instance. 305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * <p><b>Note:</b> As per the {@link Input } interface, multi-byte 325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * reads all use little-endian order.</p> 335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compublic class ByteArrayInput 355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com implements Input { 365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** non-null; the data itself */ 385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private byte[] data; 395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** >= 0; current read cursor */ 415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private int cursor; 425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Constructs an instance with the given data 455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * @param data non-null; data array to use for input 475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public ByteArrayInput(byte[] data) { 495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (data == null) { 505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NullPointerException("data == null"); 515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com this.data = data; 545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com this.cursor = 0; 555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Gets the underlying <code>byte[]</code> of this instance 595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * @return non-null; the <code>byte[]</code> 615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public byte[] getArray() { 635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return data; 645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int getCursor() { 685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return cursor; 695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void setCursor(int cursor) { 735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (cursor < 0 || cursor >= data.length) 745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new IndexOutOfBoundsException("The provided cursor value " + 755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com "is not within the bounds of this instance's data array"); 765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com this.cursor = cursor; 775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void assertCursor(int expectedCursor) { 815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (cursor != expectedCursor) { 825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new ExceptionWithContext("expected cursor " + 835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com expectedCursor + "; actual value: " + cursor); 845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public byte readByte() { 89bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return data[cursor++]; 905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readShort() { 945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int readAt = cursor; 95bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com int result = ((data[readAt++] & 0xff) + 96bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 8)); 97bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = readAt; 98bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return result; 995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readInt() { 1035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int readAt = cursor; 104bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com int result = (data[readAt++] & 0xff) + 105bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 8) + 106bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 16) + 107bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 24); 108bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = readAt; 109bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return result; 1105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public long readLong() { 1145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int readAt = cursor; 1155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 116bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com long result = (data[readAt++] & 0xffL) | 117bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 8) | 118bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 16) | 119bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 24) | 120bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 32) | 121bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 40) | 122bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 48) | 1237ed253b78bd28abb0a56463ca26bb26c1c07302cjesusfreke@jesusfreke.com ((data[readAt++] & 0xffL) << 56); 124bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = readAt; 125bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return result; 1265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readUnsignedOrSignedLeb128() { 1315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor; 1325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int currentByteValue; 1335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result; 1345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = data[end++] & 0xff; 1365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > 0x7f) { 1375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 1395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 14; 1425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 21; 1455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x0f) { 1485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwInvalidLeb(); 1495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= currentByteValue << 28; 1515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 1555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 1565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 1605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format 1625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //The caller wants to know if this is the case, so we'll return the negated value instead 1635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //If there was only a single byte that had a value of 0, then we would have returned in the above 1645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //"else" 1655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (data[end-1] == 0) { 1665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return ~result; 1675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readUnsignedLeb128() { 1765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor; 1775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int currentByteValue; 1785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result; 1795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = data[end++] & 0xff; 1815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > 0x7f) { 1825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 1845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 14; 1875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 21; 1905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x0f) { 1935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwInvalidLeb(); 1945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= currentByteValue << 28; 1965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readSignedLeb128() { 2075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor; 2085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int currentByteValue; 2095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result; 2105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = data[end++] & 0xff; 2125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result <= 0x7f) { 2135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 25) >> 25; 2145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 2175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue <= 0x7f) { 2185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 18) >> 18; 2195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 14; 2225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue <= 0x7f) { 2235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 11) >> 11; 2245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 21; 2275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue <= 0x7f) { 2285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 4) >> 4; 2295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x0f) { 2325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwInvalidLeb(); 2335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= currentByteValue << 28; 2355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void read(byte[] bytes, int offset, int length) { 2465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor + length; 2475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (end > data.length) { 2495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwBounds(); 2505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com System.arraycopy(data, cursor, bytes, offset, length); 2535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void read(byte[] bytes) { 2585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int length = bytes.length; 2595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor + length; 2605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (end > data.length) { 2625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwBounds(); 2635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com System.arraycopy(data, cursor, bytes, 0, length); 2665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public byte[] readBytes(int length) { 2715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor + length; 2725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (end > data.length) { 2745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwBounds(); 2755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] result = new byte[length]; 2785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com System.arraycopy(data, cursor, result, 0, length); 2795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2841f29ee7351fd7fb48bb093b39b5f9ffddb34a3eaJesusFreke@JesusFreke.com public String realNullTerminatedUtf8String() { 2855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int startPosition = cursor; 2865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com while (data[cursor] != 0) { 2875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor++; 2885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int byteCount = cursor - startPosition; 2901f29ee7351fd7fb48bb093b39b5f9ffddb34a3eaJesusFreke@JesusFreke.com 2915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //skip the terminating null 2925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor++; 2935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2941f29ee7351fd7fb48bb093b39b5f9ffddb34a3eaJesusFreke@JesusFreke.com return Utf8Utils.utf8BytesToString(data, startPosition, byteCount); 2955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void skipBytes(int count) { 299bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor += count; 3005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 3035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void alignTo(int alignment) { 304bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = AlignmentUtils.alignOffset(cursor, alignment); 3055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 3085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Throws the excpetion for when an attempt is made to read past the 3095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * end of the instance. 3105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 3115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private static void throwBounds() { 3125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new IndexOutOfBoundsException("attempt to read past the end"); 3135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 3165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Throws the exception for when an invalid LEB128 value is encountered 3175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 3185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private static void throwInvalidLeb() { 3195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new RuntimeException("invalid LEB128 integer encountered"); 3205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com} 322