/** * Return true when the next encoded value in {@code src} uses Numeric * encoding, false otherwise. {@code NaN}, {@code +/-Inf} are valid Numeric * values. */ public static boolean isNumeric(PositionedByteRange src) { byte x = (-1 == Integer.signum(src.peek()) ? DESCENDING : ASCENDING).apply(src.peek()); return x >= NEG_INF && x <= NAN; }
/** * Return true when the next encoded value in {@code src} uses Numeric * encoding and is {@code Infinite}, false otherwise. */ public static boolean isNumericInfinite(PositionedByteRange src) { byte x = (-1 == Integer.signum(src.peek()) ? DESCENDING : ASCENDING).apply(src.peek()); return NEG_INF == x || POS_INF == x; }
/** * Inspect {@code src} for an encoded varuint64 for its length in bytes. * Preserves the state of {@code src}. * @param src source buffer * @param comp if true, parse the compliment of the value. * @return the number of bytes consumed by this value. */ @VisibleForTesting static int lengthVaruint64(PositionedByteRange src, boolean comp) { int a0 = (comp ? DESCENDING : ASCENDING).apply(src.peek()) & 0xff; if (a0 <= 240) return 1; if (a0 <= 248) return 2; if (a0 == 249) return 3; if (a0 == 250) return 4; if (a0 == 251) return 5; if (a0 == 252) return 6; if (a0 == 253) return 7; if (a0 == 254) return 8; if (a0 == 255) return 9; throw unexpectedHeader(src.peek()); }
/** * Decode a {@link BigDecimal} value from the variable-length encoding. * @throws IllegalArgumentException when the encoded value is not a Numeric. * @see #encodeNumeric(PositionedByteRange, BigDecimal, Order) */ public static BigDecimal decodeNumericAsBigDecimal(PositionedByteRange src) { if (isNull(src)) { src.get(); return null; } if (!isNumeric(src)) throw unexpectedHeader(src.peek()); if (isNumericNaN(src)) throw unexpectedHeader(src.peek()); if (isNumericInfinite(src)) throw unexpectedHeader(src.peek()); return decodeNumericValue(src); }
/** * Decode a primitive {@code long} value from the Numeric encoding. Numeric * encoding is based on {@link BigDecimal}; in the event the encoded value is * larger than can be represented in a {@code long}, this method performs an * implicit narrowing conversion as described in * {@link BigDecimal#doubleValue()}. * @throws NullPointerException when the encoded value is {@code NULL}. * @throws IllegalArgumentException when the encoded value is not a Numeric. * @see #encodeNumeric(PositionedByteRange, long, Order) * @see BigDecimal#longValue() */ public static long decodeNumericAsLong(PositionedByteRange src) { // TODO: should an encoded NULL value throw unexpectedHeader() instead? if (isNull(src)) throw new NullPointerException(); if (!isNumeric(src)) throw unexpectedHeader(src.peek()); if (isNumericNaN(src)) throw unexpectedHeader(src.peek()); if (isNumericInfinite(src)) throw unexpectedHeader(src.peek()); if (isNumericZero(src)) { src.get(); return Long.valueOf(0); } return decodeNumericValue(src).longValue(); }
if (src.peek() == ord.apply(TERM)) {