ByteArrayInput.java revision bba8645009131cbc0c596ca1fdb26f7c848e6795
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 175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compackage org.jf.dexlib.Util; 185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com/** 205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Implementation of {@link Input} which reads the data from a 215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * <code>byte[]</code> instance. 225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * <p><b>Note:</b> As per the {@link Input } interface, multi-byte 245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * reads all use little-endian order.</p> 255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compublic class ByteArrayInput 275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com implements Input { 285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** non-null; the data itself */ 305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private byte[] data; 315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** >= 0; current read cursor */ 335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private int cursor; 345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Constructs an instance with the given data 375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * @param data non-null; data array to use for input 395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public ByteArrayInput(byte[] data) { 415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (data == null) { 425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NullPointerException("data == null"); 435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com this.data = data; 465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com this.cursor = 0; 475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Gets the underlying <code>byte[]</code> of this instance 515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * @return non-null; the <code>byte[]</code> 535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public byte[] getArray() { 555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return data; 565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int getCursor() { 605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return cursor; 615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void setCursor(int cursor) { 655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (cursor < 0 || cursor >= data.length) 665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new IndexOutOfBoundsException("The provided cursor value " + 675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com "is not within the bounds of this instance's data array"); 685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com this.cursor = cursor; 695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void assertCursor(int expectedCursor) { 735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (cursor != expectedCursor) { 745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new ExceptionWithContext("expected cursor " + 755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com expectedCursor + "; actual value: " + cursor); 765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public byte readByte() { 81bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return data[cursor++]; 825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readShort() { 865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int readAt = cursor; 87bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com int result = ((data[readAt++] & 0xff) + 88bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 8)); 89bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = readAt; 90bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return result; 915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readInt() { 955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int readAt = cursor; 96bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com int result = (data[readAt++] & 0xff) + 97bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 8) + 98bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 16) + 99bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xff) << 24); 100bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = readAt; 101bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return result; 1025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public long readLong() { 1065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int readAt = cursor; 1075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 108bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com long result = (data[readAt++] & 0xffL) | 109bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 8) | 110bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 16) | 111bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 24) | 112bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 32) | 113bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 40) | 114bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 48) | 115bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com ((data[readAt++] & 0xffL) << 58); 116bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = readAt; 117bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com return result; 1185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readUnsignedOrSignedLeb128() { 1235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor; 1245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int currentByteValue; 1255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result; 1265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = data[end++] & 0xff; 1285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > 0x7f) { 1295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 1315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 14; 1345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 21; 1375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x0f) { 1405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwInvalidLeb(); 1415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= currentByteValue << 28; 1435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 1475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 1485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 1525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //If the last byte is 0, then this was an unsigned value (incorrectly) written in a signed format 1545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //The caller wants to know if this is the case, so we'll return the negated value instead 1555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //If there was only a single byte that had a value of 0, then we would have returned in the above 1565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //"else" 1575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (data[end-1] == 0) { 1585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return ~result; 1595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readUnsignedLeb128() { 1685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor; 1695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int currentByteValue; 1705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result; 1715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = data[end++] & 0xff; 1735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > 0x7f) { 1745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 1765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 14; 1795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 21; 1825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x7f) { 1835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 1845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x0f) { 1855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwInvalidLeb(); 1865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= currentByteValue << 28; 1885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 1945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 1985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public int readSignedLeb128() { 1995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor; 2005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int currentByteValue; 2015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result; 2025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = data[end++] & 0xff; 2045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result <= 0x7f) { 2055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 25) >> 25; 2065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7); 2095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue <= 0x7f) { 2105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 18) >> 18; 2115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 14; 2145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue <= 0x7f) { 2155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 11) >> 11; 2165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= (currentByteValue & 0x7f) << 21; 2195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue <= 0x7f) { 2205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (result << 4) >> 4; 2215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com currentByteValue = data[end++] & 0xff; 2235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (currentByteValue > 0x0f) { 2245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwInvalidLeb(); 2255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result |= currentByteValue << 28; 2275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void read(byte[] bytes, int offset, int length) { 2385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor + length; 2395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (end > data.length) { 2415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwBounds(); 2425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com System.arraycopy(data, cursor, bytes, offset, length); 2455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void read(byte[] bytes) { 2505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int length = bytes.length; 2515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor + length; 2525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (end > data.length) { 2545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwBounds(); 2555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com System.arraycopy(data, cursor, bytes, 0, length); 2585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public byte[] readBytes(int length) { 2635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int end = cursor + length; 2645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (end > data.length) { 2665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throwBounds(); 2675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] result = new byte[length]; 2705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com System.arraycopy(data, cursor, result, 0, length); 2715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor = end; 2725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2761f29ee7351fd7fb48bb093b39b5f9ffddb34a3eaJesusFreke@JesusFreke.com public String realNullTerminatedUtf8String() { 2775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int startPosition = cursor; 2785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com while (data[cursor] != 0) { 2795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor++; 2805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int byteCount = cursor - startPosition; 2821f29ee7351fd7fb48bb093b39b5f9ffddb34a3eaJesusFreke@JesusFreke.com 2835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //skip the terminating null 2845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com cursor++; 2855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2861f29ee7351fd7fb48bb093b39b5f9ffddb34a3eaJesusFreke@JesusFreke.com return Utf8Utils.utf8BytesToString(data, startPosition, byteCount); 2875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void skipBytes(int count) { 291bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor += count; 2925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** {@inheritDoc} */ 2955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public void alignTo(int alignment) { 296bba8645009131cbc0c596ca1fdb26f7c848e6795JesusFreke@JesusFreke.com cursor = AlignmentUtils.alignOffset(cursor, alignment); 2975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 3005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Throws the excpetion for when an attempt is made to read past the 3015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * end of the instance. 3025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 3035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private static void throwBounds() { 3045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new IndexOutOfBoundsException("attempt to read past the end"); 3055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /** 3085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Throws the exception for when an invalid LEB128 value is encountered 3095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 3105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com private static void throwInvalidLeb() { 3115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new RuntimeException("invalid LEB128 integer encountered"); 3125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com} 314