1*055d4590SKeyi Gui /* 2*055d4590SKeyi Gui * Copyright (C) 2008 The Android Open Source Project 3*055d4590SKeyi Gui * 4*055d4590SKeyi Gui * Licensed under the Apache License, Version 2.0 (the "License"); 5*055d4590SKeyi Gui * you may not use this file except in compliance with the License. 6*055d4590SKeyi Gui * You may obtain a copy of the License at 7*055d4590SKeyi Gui * 8*055d4590SKeyi Gui * http://www.apache.org/licenses/LICENSE-2.0 9*055d4590SKeyi Gui * 10*055d4590SKeyi Gui * Unless required by applicable law or agreed to in writing, software 11*055d4590SKeyi Gui * distributed under the License is distributed on an "AS IS" BASIS, 12*055d4590SKeyi Gui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*055d4590SKeyi Gui * See the License for the specific language governing permissions and 14*055d4590SKeyi Gui * limitations under the License. 15*055d4590SKeyi Gui */ 16*055d4590SKeyi Gui 17*055d4590SKeyi Gui package com.android.dex; 18*055d4590SKeyi Gui 19*055d4590SKeyi Gui import com.android.dex.util.ByteInput; 20*055d4590SKeyi Gui import com.android.dex.util.ByteOutput; 21*055d4590SKeyi Gui 22*055d4590SKeyi Gui /** 23*055d4590SKeyi Gui * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3 24*055d4590SKeyi Gui * section 7.6. 25*055d4590SKeyi Gui */ 26*055d4590SKeyi Gui public final class Leb128 { Leb128()27*055d4590SKeyi Gui private Leb128() { 28*055d4590SKeyi Gui } 29*055d4590SKeyi Gui 30*055d4590SKeyi Gui /** 31*055d4590SKeyi Gui * Gets the number of bytes in the unsigned LEB128 encoding of the 32*055d4590SKeyi Gui * given value. 33*055d4590SKeyi Gui * 34*055d4590SKeyi Gui * @param value the value in question 35*055d4590SKeyi Gui * @return its write size, in bytes 36*055d4590SKeyi Gui */ unsignedLeb128Size(int value)37*055d4590SKeyi Gui public static int unsignedLeb128Size(int value) { 38*055d4590SKeyi Gui // TODO: This could be much cleverer. 39*055d4590SKeyi Gui 40*055d4590SKeyi Gui int remaining = value >> 7; 41*055d4590SKeyi Gui int count = 0; 42*055d4590SKeyi Gui 43*055d4590SKeyi Gui while (remaining != 0) { 44*055d4590SKeyi Gui remaining >>= 7; 45*055d4590SKeyi Gui count++; 46*055d4590SKeyi Gui } 47*055d4590SKeyi Gui 48*055d4590SKeyi Gui return count + 1; 49*055d4590SKeyi Gui } 50*055d4590SKeyi Gui 51*055d4590SKeyi Gui /** 52*055d4590SKeyi Gui * Reads an signed integer from {@code in}. 53*055d4590SKeyi Gui */ readSignedLeb128(ByteInput in)54*055d4590SKeyi Gui public static int readSignedLeb128(ByteInput in) { 55*055d4590SKeyi Gui int result = 0; 56*055d4590SKeyi Gui int cur; 57*055d4590SKeyi Gui int count = 0; 58*055d4590SKeyi Gui int signBits = -1; 59*055d4590SKeyi Gui 60*055d4590SKeyi Gui do { 61*055d4590SKeyi Gui cur = in.readByte() & 0xff; 62*055d4590SKeyi Gui result |= (cur & 0x7f) << (count * 7); 63*055d4590SKeyi Gui signBits <<= 7; 64*055d4590SKeyi Gui count++; 65*055d4590SKeyi Gui } while (((cur & 0x80) == 0x80) && count < 5); 66*055d4590SKeyi Gui 67*055d4590SKeyi Gui if ((cur & 0x80) == 0x80) { 68*055d4590SKeyi Gui throw new DexException("invalid LEB128 sequence"); 69*055d4590SKeyi Gui } 70*055d4590SKeyi Gui 71*055d4590SKeyi Gui // Sign extend if appropriate 72*055d4590SKeyi Gui if (((signBits >> 1) & result) != 0 ) { 73*055d4590SKeyi Gui result |= signBits; 74*055d4590SKeyi Gui } 75*055d4590SKeyi Gui 76*055d4590SKeyi Gui return result; 77*055d4590SKeyi Gui } 78*055d4590SKeyi Gui 79*055d4590SKeyi Gui /** 80*055d4590SKeyi Gui * Reads an unsigned integer from {@code in}. 81*055d4590SKeyi Gui */ readUnsignedLeb128(ByteInput in)82*055d4590SKeyi Gui public static int readUnsignedLeb128(ByteInput in) { 83*055d4590SKeyi Gui int result = 0; 84*055d4590SKeyi Gui int cur; 85*055d4590SKeyi Gui int count = 0; 86*055d4590SKeyi Gui 87*055d4590SKeyi Gui do { 88*055d4590SKeyi Gui cur = in.readByte() & 0xff; 89*055d4590SKeyi Gui result |= (cur & 0x7f) << (count * 7); 90*055d4590SKeyi Gui count++; 91*055d4590SKeyi Gui } while (((cur & 0x80) == 0x80) && count < 5); 92*055d4590SKeyi Gui 93*055d4590SKeyi Gui if ((cur & 0x80) == 0x80) { 94*055d4590SKeyi Gui throw new DexException("invalid LEB128 sequence"); 95*055d4590SKeyi Gui } 96*055d4590SKeyi Gui 97*055d4590SKeyi Gui return result; 98*055d4590SKeyi Gui } 99*055d4590SKeyi Gui 100*055d4590SKeyi Gui /** 101*055d4590SKeyi Gui * Writes {@code value} as an unsigned integer to {@code out}, starting at 102*055d4590SKeyi Gui * {@code offset}. Returns the number of bytes written. 103*055d4590SKeyi Gui */ writeUnsignedLeb128(ByteOutput out, int value)104*055d4590SKeyi Gui public static void writeUnsignedLeb128(ByteOutput out, int value) { 105*055d4590SKeyi Gui int remaining = value >>> 7; 106*055d4590SKeyi Gui 107*055d4590SKeyi Gui while (remaining != 0) { 108*055d4590SKeyi Gui out.writeByte((byte) ((value & 0x7f) | 0x80)); 109*055d4590SKeyi Gui value = remaining; 110*055d4590SKeyi Gui remaining >>>= 7; 111*055d4590SKeyi Gui } 112*055d4590SKeyi Gui 113*055d4590SKeyi Gui out.writeByte((byte) (value & 0x7f)); 114*055d4590SKeyi Gui } 115*055d4590SKeyi Gui 116*055d4590SKeyi Gui /** 117*055d4590SKeyi Gui * Writes {@code value} as a signed integer to {@code out}, starting at 118*055d4590SKeyi Gui * {@code offset}. Returns the number of bytes written. 119*055d4590SKeyi Gui */ writeSignedLeb128(ByteOutput out, int value)120*055d4590SKeyi Gui public static void writeSignedLeb128(ByteOutput out, int value) { 121*055d4590SKeyi Gui int remaining = value >> 7; 122*055d4590SKeyi Gui boolean hasMore = true; 123*055d4590SKeyi Gui int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; 124*055d4590SKeyi Gui 125*055d4590SKeyi Gui while (hasMore) { 126*055d4590SKeyi Gui hasMore = (remaining != end) 127*055d4590SKeyi Gui || ((remaining & 1) != ((value >> 6) & 1)); 128*055d4590SKeyi Gui 129*055d4590SKeyi Gui out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0))); 130*055d4590SKeyi Gui value = remaining; 131*055d4590SKeyi Gui remaining >>= 7; 132*055d4590SKeyi Gui } 133*055d4590SKeyi Gui } 134*055d4590SKeyi Gui } 135