blob: e2058ffcb23eac6d1794c30e0e651eb5f28c4fa4 [file] [log] [blame]
package org.jetbrains.debugger.sourcemap;
final class Base64VLQ {
private Base64VLQ() {
}
interface CharIterator {
boolean hasNext();
char next();
}
// A Base64 VLQ digit can represent 5 bits, so it is base-32.
private static final int VLQ_BASE_SHIFT = 5;
private static final int VLQ_BASE = 1 << VLQ_BASE_SHIFT;
// A mask of bits for a VLQ digit (11111), 31 decimal.
private static final int VLQ_BASE_MASK = VLQ_BASE - 1;
// The continuation bit is the 6th bit.
private static final int VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Decodes the next VLQValue from the provided CharIterator.
*/
public static int decode(CharIterator in) {
int result = 0;
int shift = 0;
int digit;
do {
digit = Base64.BASE64_DECODE_MAP[in.next()];
assert (digit != -1) : "invalid char";
result += (digit & VLQ_BASE_MASK) << shift;
shift += VLQ_BASE_SHIFT;
}
while ((digit & VLQ_CONTINUATION_BIT) != 0);
boolean negate = (result & 1) == 1;
result >>= 1;
return negate ? -result : result;
}
private static final class Base64 {
/**
* A map used to convert integer values in the range 0-63 to their base64
* values.
*/
private static final String BASE64_MAP =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789+/";
/**
* A map used to convert base64 character into integer values.
*/
private static final int[] BASE64_DECODE_MAP = new int[256];
static {
for (int i = 0; i < BASE64_MAP.length(); i++) {
BASE64_DECODE_MAP[BASE64_MAP.charAt(i)] = i;
}
}
}
}