VarintUtils.java
package edu.jiangxin.apktoolbox.convert.protobuf.unsupervised;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
public class VarintUtils {
/**
* 解码为有符号类型
*
* @param bigInteger
* @return
*/
protected static BigInteger interpretAsSignedType(BigInteger bigInteger){
BigInteger i = bigInteger.and(new BigInteger("1"));
if (i.equals(new BigInteger("0"))) {
return bigInteger.divide(new BigInteger("2"));
}
return new BigInteger("-1").multiply(bigInteger.add((new BigInteger("1")).divide(new BigInteger("2"))));
}
/**
* 解码可变整数
*
* @param buffer
* @param offset
* @return
*/
protected static Map<String, Object> decodeVarint(byte[] buffer, int offset) {
BigInteger res = new BigInteger("0");
int shift = 0;
byte bytes;
int count = 0;
do {
if (offset >= buffer.length) {
throw new RuntimeException("Index out of bound decoding varint");
}
count++;
bytes = buffer[offset++];
BigInteger multiplier = new BigInteger("2").pow(shift);
BigInteger thisByteValue = (new BigInteger(Long.toString(bytes & 0x7f))).multiply(multiplier);
shift += 7;
res = res.add(thisByteValue);
} while ((bytes & 0xff) >= 128 && count < 8);
Map<String, Object> result = new HashMap<>(2);
result.put("value", res);
result.put("length", (shift / 7));
return result;
}
}