/** * Read a {@code byte[]} from the buffer {@code src}. */ public byte[] decode(PositionedByteRange src, int length) { byte[] val = new byte[length]; src.get(val); return val; }
@Override public T decode(PositionedByteRange src) { if (src.getRemaining() < length) { throw new IllegalArgumentException("Not enough buffer remaining. src.offset: " + src.getOffset() + " src.length: " + src.getLength() + " src.position: " + src.getPosition() + " max length: " + length); } // create a copy range limited to length bytes. boo. PositionedByteRange b = new SimplePositionedMutableByteRange(length); src.get(b.getBytes()); return base.decode(b); }
/** * Decode a Blob value, byte-for-byte copy. * @see #encodeBlobCopy(PositionedByteRange, byte[], int, int, Order) */ public static byte[] decodeBlobCopy(PositionedByteRange src) { byte header = src.get(); if (header == NULL || header == DESCENDING.apply(NULL)) { return null; } assert header == BLOB_COPY || header == DESCENDING.apply(BLOB_COPY); Order ord = header == BLOB_COPY ? ASCENDING : DESCENDING; final int length = src.getRemaining() - (ASCENDING == ord ? 0 : 1); byte[] ret = new byte[length]; src.get(ret); ord.apply(ret, 0, ret.length); // DESCENDING ordered BlobCopy requires a termination bit to preserve // sort-order semantics of null values. if (DESCENDING == ord) src.get(); return ret; }
static KeyValue readCell(PositionedByteRange pbr) throws Exception { int kvStartPos = pbr.getPosition(); int keyLen = pbr.getInt(); int valLen = pbr.getInt(); pbr.setPosition(pbr.getPosition() + keyLen + valLen); // Skip the key and value section int tagsLen = ((pbr.get() & 0xff) << 8) ^ (pbr.get() & 0xff); pbr.setPosition(pbr.getPosition() + tagsLen); // Skip the tags section long mvcc = pbr.getVLong(); KeyValue kv = new KeyValue(pbr.getBytes(), kvStartPos, (int) KeyValue.getKeyValueDataStructureSize(keyLen, valLen, tagsLen)); kv.setSequenceId(mvcc); return kv; }
/** * Decode a String value. */ public static String decodeString(PositionedByteRange src) { final byte header = src.get(); if (header == NULL || header == DESCENDING.apply(NULL)) return null; assert header == TEXT || header == DESCENDING.apply(TEXT); Order ord = header == TEXT ? ASCENDING : DESCENDING; byte[] a = src.getBytes(); final int offset = src.getOffset(), start = src.getPosition(); final byte terminator = ord.apply(TERM); int rawStartPos = offset + start, rawTermPos = rawStartPos; for (; a[rawTermPos] != terminator; rawTermPos++) ; src.setPosition(rawTermPos - offset + 1); // advance position to TERM + 1 if (DESCENDING == ord) { // make a copy so that we don't disturb encoded value with ord. byte[] copy = new byte[rawTermPos - rawStartPos]; System.arraycopy(a, rawStartPos, copy, 0, copy.length); ord.apply(copy); return new String(copy, UTF8); } else { return new String(a, rawStartPos, rawTermPos - rawStartPos, UTF8); } }
@Override public T decode(PositionedByteRange src) { if (wrapped.isSkippable()) { T ret = wrapped.decode(src); src.setPosition(src.getPosition() + term.length); return ret; } else { // find the terminator position int term = terminatorPosition(src); if (-1 == term) { throw new IllegalArgumentException("Terminator sequence not found."); } byte[] b = new byte[term - src.getPosition()]; src.get(b); // TODO: should we assert that b.position == b.length? T ret = wrapped.decode(new SimplePositionedMutableByteRange(b)); src.get(this.term); return ret; } }
@Override public String decode(PositionedByteRange src) { if (Order.ASCENDING == this.order) { // avoid unnecessary array copy for ASC case. String val = Bytes.toString(src.getBytes(), src.getOffset() + src.getPosition(), src.getRemaining()); src.setPosition(src.getLength()); return val; } else { byte[] b = new byte[src.getRemaining()]; src.get(b); order.apply(b, 0, b.length); return Bytes.toString(b); } }
/** * Decode an {@code int8} value. * @see #encodeInt8(PositionedByteRange, byte, Order) */ public static byte decodeInt8(PositionedByteRange src) { final byte header = src.get(); assert header == FIXED_INT8 || header == DESCENDING.apply(FIXED_INT8); Order ord = header == FIXED_INT8 ? ASCENDING : DESCENDING; return (byte)((ord.apply(src.get()) ^ 0x80) & 0xff); }
/** * Decode an {@code int16} value. * @see #encodeInt16(PositionedByteRange, short, Order) */ public static short decodeInt16(PositionedByteRange src) { final byte header = src.get(); assert header == FIXED_INT16 || header == DESCENDING.apply(FIXED_INT16); Order ord = header == FIXED_INT16 ? ASCENDING : DESCENDING; short val = (short) ((ord.apply(src.get()) ^ 0x80) & 0xff); val = (short) ((val << 8) + (ord.apply(src.get()) & 0xff)); return val; }
/** * Decode an {@code int32} value. * @see #encodeInt32(PositionedByteRange, int, Order) */ public static int decodeInt32(PositionedByteRange src) { final byte header = src.get(); assert header == FIXED_INT32 || header == DESCENDING.apply(FIXED_INT32); Order ord = header == FIXED_INT32 ? ASCENDING : DESCENDING; int val = (ord.apply(src.get()) ^ 0x80) & 0xff; for (int i = 1; i < 4; i++) { val = (val << 8) + (ord.apply(src.get()) & 0xff); } return val; }
/** * Decode an {@code int64} value. * @see #encodeInt64(PositionedByteRange, long, Order) */ public static long decodeInt64(PositionedByteRange src) { final byte header = src.get(); assert header == FIXED_INT64 || header == DESCENDING.apply(FIXED_INT64); Order ord = header == FIXED_INT64 ? ASCENDING : DESCENDING; long val = (ord.apply(src.get()) ^ 0x80) & 0xff; for (int i = 1; i < 8; i++) { val = (val << 8) + (ord.apply(src.get()) & 0xff); } return val; }
/** * Decode a 32-bit floating point value using the fixed-length encoding. * @see #encodeFloat32(PositionedByteRange, float, Order) */ public static float decodeFloat32(PositionedByteRange src) { final byte header = src.get(); assert header == FIXED_FLOAT32 || header == DESCENDING.apply(FIXED_FLOAT32); Order ord = header == FIXED_FLOAT32 ? ASCENDING : DESCENDING; int val = ord.apply(src.get()) & 0xff; for (int i = 1; i < 4; i++) { val = (val << 8) + (ord.apply(src.get()) & 0xff); } val ^= (~val >> (Integer.SIZE - 1)) | Integer.MIN_VALUE; return Float.intBitsToFloat(val); }
/** * Decode a 64-bit floating point value using the fixed-length encoding. * @see #encodeFloat64(PositionedByteRange, double, Order) */ public static double decodeFloat64(PositionedByteRange src) { final byte header = src.get(); assert header == FIXED_FLOAT64 || header == DESCENDING.apply(FIXED_FLOAT64); Order ord = header == FIXED_FLOAT64 ? ASCENDING : DESCENDING; long val = ord.apply(src.get()) & 0xff; for (int i = 1; i < 8; i++) { val = (val << 8) + (ord.apply(src.get()) & 0xff); } val ^= (~val >> (Long.SIZE - 1)) | Long.MIN_VALUE; return Double.longBitsToDouble(val); }
@Override public Object decode(PositionedByteRange src) { switch (src.get()) { case IS_INTEGER: return typeA.decode(src); case IS_STRING: return typeB.decode(src); default: throw new IllegalArgumentException("Unrecognized encoding format."); } }
@Override public int skip(PositionedByteRange src) { switch (src.get()) { case IS_INTEGER: return 1 + typeA.skip(src); case IS_STRING: return 1 + typeB.skip(src); default: throw new IllegalArgumentException("Unrecognized encoding format."); } }
/** * 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(); }
byte header = src.get(); boolean dsc = -1 == Integer.signum(header); header = dsc ? DESCENDING.apply(header) : header;
/** * 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); }