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;
  }
Deserialize data written in the format used by the SerializationUtils methods
readBigInteger/writeBigInteger and create a decimal using the supplied scale.

ORC uses those SerializationUtils methods for its serialization.

A scratch bytes array is necessary to do the binary to decimal conversion for better
performance.  Pass a FAST_SCRATCH_BUFFER_LEN_SERIALIZATION_UTILS_READ byte array for
scratchBytes.

@param inputStream the stream to read from
@param scale the scale of the number
@param scratchBytes  An array for the binary to decimal conversion for better
                     performance.  Must have length of
                     FAST_SCRATCH_BUFFER_LEN_SERIALIZATION_UTILS_READ.
@param fastResult an object to reuse
@return The deserialized decimal or null if the conversion failed.
@throws IOException failures in reading the stream
storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java