15867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com/* 25867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * [The "BSD licence"] 300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke) 45867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * All rights reserved. 55867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 65867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without 75867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions 85867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * are met: 95867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright 105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer. 115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright 125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer in the 135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * documentation and/or other materials provided with the distribution. 145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products 155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * derived from this software without specific prior written permission. 165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compackage org.jf.dexlib.Util; 305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compublic class EncodedValueUtils { 325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte getRequiredBytesForSignedIntegralValue(long value) { 335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com /* 345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Figure out how many bits are needed to represent the value, 355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * including a sign bit: The bit count is subtracted from 65 365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * and not 64 to account for the sign bit. The xor operation 375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * has the effect of leaving non-negative values alone and 385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * unary complementing negative values (so that a leading zero 395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * count always returns a useful number for our present 405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * purpose). 415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int requiredBits = 435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 65 - Long.numberOfLeadingZeros(value ^ (value >> 63)); 445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com // Round up the requiredBits to a number of bytes. 465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return (byte)((requiredBits + 0x07) >> 3); 475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static long decodeSignedIntegralValue(byte[] bytes) { 505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com long value = 0; 515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i = 0; i < bytes.length; i++) { 525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value |= (((long)(bytes[i] & 0xFF)) << (i * 8)); 535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int shift = (8 - bytes.length) * 8; 565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return value << shift >> shift; 575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] encodeSignedIntegralValue(long value) { 605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int requiredBytes = getRequiredBytesForSignedIntegralValue(value); 615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] bytes = new byte[requiredBytes]; 635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i = 0; i < requiredBytes; i++) { 655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[i] = (byte) value; 665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value >>= 8; 675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return bytes; 695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte getRequiredBytesForUnsignedIntegralValue(long value) { 765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com // Figure out how many bits are needed to represent the value. 775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int requiredBits = 64 - Long.numberOfLeadingZeros(value); 785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (requiredBits == 0) { 795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com requiredBits = 1; 805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com // Round up the requiredBits to a number of bytes. 835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return (byte)((requiredBits + 0x07) >> 3); 845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static long decodeUnsignedIntegralValue(byte[] bytes) { 875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com long value = 0; 885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i = 0; i < bytes.length; i++) { 895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value |= (((long)(bytes[i] & 0xFF)) << i * 8); 905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return value; 925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] encodeUnsignedIntegralValue(long value) { 955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int requiredBytes = getRequiredBytesForUnsignedIntegralValue(value); 965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] bytes = new byte[requiredBytes]; 985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i = 0; i < requiredBytes; i++) { 1005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[i] = (byte) value; 1015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value >>= 8; 1025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return bytes; 1045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static int getRequiredBytesForRightZeroExtendedValue(long value) { 1115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com // Figure out how many bits are needed to represent the value. 1125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int requiredBits = 64 - Long.numberOfTrailingZeros(value); 1135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (requiredBits == 0) { 1145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com requiredBits = 1; 1155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com // Round up the requiredBits to a number of bytes. 1185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return (requiredBits + 0x07) >> 3; 1195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static long decodeRightZeroExtendedValue(byte[] bytes) { 1225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com long value = 0; 1235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i = 0; i < bytes.length; i++) { 1245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value |= (((long)(bytes[i] & 0xFF)) << (i * 8)); 1255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return value << (8 - bytes.length) * 8; 1275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] encodeRightZeroExtendedValue(long value) { 1305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int requiredBytes = getRequiredBytesForRightZeroExtendedValue(value); 1315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com // Scootch the first bits to be written down to the low-order bits. 1335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value >>= 64 - (requiredBytes * 8); 1345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] bytes = new byte[requiredBytes]; 1365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for(int i = 0; i < requiredBytes; i++) { 1385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[i] = (byte)value; 1395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value >>= 8; 1405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return bytes; 1425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com} 144