in kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/common/FastHiveDecimalImpl.java [1863:1984]
public static boolean fastSerializationUtilsRead(
InputStream inputStream, int scale, byte[] scratchBytes, FastHiveDecimal fastResult)
throws IOException {
// Following a suggestion from Gopal, quickly read in the bytes from the stream.
// CONSIDER: Have ORC read the whole input stream into a big byte array with one call to
// the read(byte[] b, int off, int len) method and then let this method read from the big
// byte array.
int readCount = 0;
int input;
do {
input = inputStream.read();
if (input == -1) {
throw new EOFException("Reading BigInteger past EOF from " + inputStream);
}
scratchBytes[readCount++] = (byte) input;
} while (input >= 0x80);
/*
* Determine the 3 binary words like what SerializationUtils.readBigInteger does.
*/
long lowerWord63 = 0;
long middleWord63 = 0;
long highWord63 = 0;
long work = 0;
int offset = 0;
int readIndex = 0;
long b;
do {
b = scratchBytes[readIndex++];
work |= (0x7f & b) << (offset % 63);
offset += 7;
// if we've read 63 bits, roll them into the result
if (offset == 63) {
lowerWord63 = work;
work = 0;
} else if (offset % 63 == 0) {
if (offset == 126) {
middleWord63 = work;
} else if (offset == 189) {
highWord63 = work;
} else {
throw new EOFException("Reading more than 3 words of BigInteger");
}
work = 0;
}
} while (readIndex < readCount);
if (work != 0) {
if (offset < 63) {
lowerWord63 = work;
} else if (offset < 126) {
middleWord63 = work;
} else if (offset < 189) {
highWord63 = work;
} else {
throw new EOFException("Reading more than 3 words of BigInteger");
}
}
// Grab sign bit and shift it away.
boolean isNegative = ((lowerWord63 & 0x1) != 0);
lowerWord63 >>= 1;
/*
* Use common binary to decimal conversion method we share with fastSetFromBigIntegerBytes.
*/
if (!doBinaryToDecimalConversion(
lowerWord63,
middleWord63,
highWord63,
FAST_HIVE_DECIMAL_TWO_POWER_62,
FAST_HIVE_DECIMAL_TWO_POWER_125, // 2^(62 + 63)
fastResult)) {
return false;
}
if (isNegative) {
// Adjust negative result, again doing what SerializationUtils.readBigInteger does.
if (!doAddSameScaleSameSign(
/* resultSignum */ 1,
fastResult.fast0,
fastResult.fast1,
fastResult.fast2,
1,
0,
0,
fastResult)) {
return false;
}
}
if (fastResult.fast0 == 0 && fastResult.fast1 == 0 && fastResult.fast2 == 0) {
fastResult.fastSignum = 0;
} else {
fastResult.fastSignum = (isNegative ? -1 : 1);
final int rawPrecision = fastRawPrecision(fastResult);
fastResult.fastIntegerDigitCount = Math.max(0, rawPrecision - scale);
fastResult.fastScale = scale;
/*
* Just in case we deserialize a decimal with trailing zeroes...
*/
final int resultTrailingZeroCount =
fastTrailingDecimalZeroCount(
fastResult.fast0,
fastResult.fast1,
fastResult.fast2,
fastResult.fastIntegerDigitCount,
fastResult.fastScale);
if (resultTrailingZeroCount > 0) {
doFastScaleDown(fastResult, resultTrailingZeroCount, fastResult);
fastResult.fastScale -= resultTrailingZeroCount;
}
}
return true;
}