183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/* 283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Copyright (C) 2008 The Android Open Source Project 383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Licensed under the Apache License, Version 2.0 (the "License"); 583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * you may not use this file except in compliance with the License. 683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * You may obtain a copy of the License at 783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * http://www.apache.org/licenses/LICENSE-2.0 983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 1083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Unless required by applicable law or agreed to in writing, software 1183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * distributed under the License is distributed on an "AS IS" BASIS, 1283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * See the License for the specific language governing permissions and 1483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * limitations under the License. 1583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 1683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@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 2583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compackage org.jf.dexlib.Util; 2683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 2783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/** 2883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * LEB128 (little-endian base 128) utilities. 2983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 3083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compublic final class Leb128Utils { 3183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 3283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * This class is uninstantiable. 3383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 3483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private Leb128Utils() { 3583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // This space intentionally left blank. 3683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 3783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 3883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 3983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Gets the number of bytes in the unsigned LEB128 encoding of the 4083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * given value. 41fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com * 4283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param value the value in question 4383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return its write size, in bytes 4483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 4583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public static int unsignedLeb128Size(int value) { 4683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // TODO: This could be much cleverer. 47fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com 48e9c67dbb9c8ef3bbb98d74b664fb47b8f485bd6fJesusFreke@JesusFreke.com int remaining = value >>> 7; 4983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int count = 0; 5083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 5183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (remaining != 0) { 5283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com value = remaining; 53e9c67dbb9c8ef3bbb98d74b664fb47b8f485bd6fJesusFreke@JesusFreke.com remaining >>>= 7; 5483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com count++; 5583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 5683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 5783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return count + 1; 5883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 5983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 6083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 6183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Gets the number of bytes in the signed LEB128 encoding of the 6283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * given value. 63fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com * 6483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param value the value in question 6583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return its write size, in bytes 6683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 6783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public static int signedLeb128Size(int value) { 6883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // TODO: This could be much cleverer. 6983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 7083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int remaining = value >> 7; 7183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int count = 0; 7283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com boolean hasMore = true; 7383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; 7483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 7583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (hasMore) { 7683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com hasMore = (remaining != end) 7783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com || ((remaining & 1) != ((value >> 6) & 1)); 7883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 7983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com value = remaining; 8083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com remaining >>= 7; 8183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com count++; 8283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 8383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 8483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return count; 8583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 86fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com 87fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com /** 88fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com * Writes an unsigned leb128 to the buffer at the specified location 89fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com * @param value the value to write as an unsigned leb128 90fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com * @param buffer the buffer to write to 91bcc4d2d9e186b00386cba334a31b0f9ebffd299aJesusFreke@JesusFreke.com * @param bufferIndex the index to start writing at 92fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com */ 93fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com public static void writeUnsignedLeb128(int value, byte[] buffer, int bufferIndex) { 94fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com int remaining = value >>> 7; 95fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com int count = 0; 96fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com 97fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com while (remaining != 0) { 98fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com buffer[bufferIndex] = (byte)((value & 0x7f) | 0x80); 99fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com bufferIndex++; 100fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com value = remaining; 101fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com remaining >>>= 7; 102fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com count++; 103fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com } 104fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com 105fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com buffer[bufferIndex] = (byte)(value & 0x7f); 106fda2e631ac0b1ca092973b7fff4b2f38d2c23437JesusFreke@JesusFreke.com } 10783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com} 108