@Override public int compare(Object aObj, Object bObj) { AutoDetectDataType aType = getType(aObj); AutoDetectDataType bType = getType(bObj); if (aType == bType) { return aType.compare(aObj, bObj); } int typeDiff = aType.typeId - bType.typeId; return Integer.signum(typeDiff); }
@Override public Object read(ByteBuffer buff) { int tag = buff.get(); int typeId; if (tag <= TYPE_SERIALIZED_OBJECT) { typeId = tag; } else { switch (tag) { case TAG_BOOLEAN_TRUE: typeId = TYPE_BOOLEAN; break; case TAG_INTEGER_NEGATIVE: case TAG_INTEGER_FIXED: typeId = TYPE_INT; break; case TAG_LONG_NEGATIVE: case TAG_LONG_FIXED: typeId = TYPE_LONG; break; case TAG_BIG_INTEGER_0: case TAG_BIG_INTEGER_1: case TAG_BIG_INTEGER_SMALL: typeId = TYPE_BIG_INTEGER; break; case TAG_FLOAT_0: case TAG_FLOAT_1: case TAG_FLOAT_FIXED: typeId = TYPE_FLOAT; break; case TAG_DOUBLE_0: case TAG_DOUBLE_1: case TAG_DOUBLE_FIXED: typeId = TYPE_DOUBLE; break; case TAG_BIG_DECIMAL_0: case TAG_BIG_DECIMAL_1: case TAG_BIG_DECIMAL_SMALL: case TAG_BIG_DECIMAL_SMALL_SCALED: typeId = TYPE_BIG_DECIMAL; break; default: if (tag >= TAG_INTEGER_0_15 && tag <= TAG_INTEGER_0_15 + 15) { typeId = TYPE_INT; } else if (tag >= TAG_STRING_0_15 && tag <= TAG_STRING_0_15 + 15) { typeId = TYPE_STRING; } else if (tag >= TAG_LONG_0_7 && tag <= TAG_LONG_0_7 + 7) { typeId = TYPE_LONG; } else if (tag >= TAG_BYTE_ARRAY_0_15 && tag <= TAG_BYTE_ARRAY_0_15 + 15) { typeId = TYPE_ARRAY; } else { throw DataUtils.newIllegalStateException( DataUtils.ERROR_FILE_CORRUPT, "Unknown tag {0}", tag); } } } if (typeId != last.typeId) { last = newType(typeId); } return last.read(buff, tag); }
@Override public void write(WriteBuffer buff, Object obj) { if (!isBigDecimal(obj)) { super.write(buff, obj); return; } BigDecimal x = (BigDecimal) obj; if (BigDecimal.ZERO.equals(x)) { buff.put((byte) TAG_BIG_DECIMAL_0); } else if (BigDecimal.ONE.equals(x)) { buff.put((byte) TAG_BIG_DECIMAL_1); } else { int scale = x.scale(); BigInteger b = x.unscaledValue(); int bits = b.bitLength(); if (bits < 64) { if (scale == 0) { buff.put((byte) TAG_BIG_DECIMAL_SMALL); } else { buff.put((byte) TAG_BIG_DECIMAL_SMALL_SCALED).putVarInt(scale); } buff.putVarLong(b.longValue()); } else { byte[] bytes = b.toByteArray(); buff.put((byte) TYPE_BIG_DECIMAL).putVarInt(scale).putVarInt(bytes.length).put(bytes); } } }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Long)) { super.write(buff, obj); return; } long x = (Long) obj; if (x < 0) { // -Long.MIN_VALUE is smaller than 0 if (-x < 0 || -x > DataUtils.COMPRESSED_VAR_LONG_MAX) { buff.put((byte) TAG_LONG_FIXED); buff.putLong(x); } else { buff.put((byte) TAG_LONG_NEGATIVE); buff.putVarLong(-x); } } else if (x <= 7) { buff.put((byte) (TAG_LONG_0_7 + x)); } else if (x <= DataUtils.COMPRESSED_VAR_LONG_MAX) { buff.put((byte) TYPE_LONG); buff.putVarLong(x); } else { buff.put((byte) TAG_LONG_FIXED); buff.putLong(x); } }
@Override public void write(WriteBuffer buff, Object obj) { if (obj != null) { super.write(buff, obj); return; } buff.put((byte) TYPE_NULL); }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Character)) { super.write(buff, obj); return; } buff.put((byte) TYPE_CHAR); buff.putChar(((Character) obj).charValue()); }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Byte)) { super.write(buff, obj); return; } buff.put((byte) TYPE_BYTE); buff.put(((Byte) obj).byteValue()); }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Boolean)) { super.write(buff, obj); return; } int tag = ((Boolean) obj) ? TAG_BOOLEAN_TRUE : TYPE_BOOLEAN; buff.put((byte) tag); }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Short)) { super.write(buff, obj); return; } buff.put((byte) TYPE_SHORT); buff.putShort(((Short) obj).shortValue()); }
@Override public void write(WriteBuffer buff, Object obj) { if (!isDate(obj)) { super.write(buff, obj); return; } buff.put((byte) TYPE_DATE); Date a = (Date) obj; buff.putLong(a.getTime()); }
@Override public void write(WriteBuffer buff, Object obj) { if (!isArray(obj)) { super.write(buff, obj); return; } Class<?> type = obj.getClass().getComponentType(); Integer classId = getCommonClassId(type); if (classId != null) { if (type.isPrimitive()) { if (type == byte.class) { byte[] data = (byte[]) obj; int len = data.length; if (len <= 15) { buff.put((byte) (TAG_BYTE_ARRAY_0_15 + len)); } else { buff.put((byte) TYPE_ARRAY).put((byte) classId.intValue()).putVarInt(len); } buff.put(data); return; } int len = Array.getLength(obj); buff.put((byte) TYPE_ARRAY).put((byte) classId.intValue()).putVarInt(len); for (int i = 0; i < len; i++) { if (type == boolean.class) { buff.put((byte) (((boolean[]) obj)[i] ? 1 : 0)); } else if (type == char.class) { buff.putChar(((char[]) obj)[i]); } else if (type == short.class) { buff.putShort(((short[]) obj)[i]); } else if (type == int.class) { buff.putInt(((int[]) obj)[i]); } else if (type == float.class) { buff.putFloat(((float[]) obj)[i]); } else if (type == double.class) { buff.putDouble(((double[]) obj)[i]); } else { buff.putLong(((long[]) obj)[i]); } } return; } buff.put((byte) TYPE_ARRAY).put((byte) classId.intValue()); } else { buff.put((byte) TYPE_ARRAY).put((byte) -1); String c = type.getName(); StringDataType.INSTANCE.write(buff, c); } Object[] array = (Object[]) obj; int len = array.length; buff.putVarInt(len); for (Object x : array) { elementType.write(buff, x); } }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof UUID)) { super.write(buff, obj); return; } buff.put((byte) TYPE_UUID); UUID a = (UUID) obj; buff.putLong(a.getMostSignificantBits()); buff.putLong(a.getLeastSignificantBits()); }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof String)) { super.write(buff, obj); return; } String s = (String) obj; int len = s.length(); if (len <= 15) { buff.put((byte) (TAG_STRING_0_15 + len)); } else { buff.put((byte) TYPE_STRING).putVarInt(len); } buff.putStringData(s, len); }
@Override public void write(WriteBuffer buff, Object obj) { if (!isBigInteger(obj)) { super.write(buff, obj); return; } BigInteger x = (BigInteger) obj; if (BigInteger.ZERO.equals(x)) { buff.put((byte) TAG_BIG_INTEGER_0); } else if (BigInteger.ONE.equals(x)) { buff.put((byte) TAG_BIG_INTEGER_1); } else { int bits = x.bitLength(); if (bits <= 63) { buff.put((byte) TAG_BIG_INTEGER_SMALL).putVarLong(x.longValue()); } else { byte[] bytes = x.toByteArray(); buff.put((byte) TYPE_BIG_INTEGER).putVarInt(bytes.length).put(bytes); } } }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Float)) { super.write(buff, obj); return; } float x = (Float) obj; int f = Float.floatToIntBits(x); if (f == ObjectDataType.FLOAT_ZERO_BITS) { buff.put((byte) TAG_FLOAT_0); } else if (f == ObjectDataType.FLOAT_ONE_BITS) { buff.put((byte) TAG_FLOAT_1); } else { int value = Integer.reverse(f); if (value >= 0 && value <= DataUtils.COMPRESSED_VAR_INT_MAX) { buff.put((byte) TYPE_FLOAT).putVarInt(value); } else { buff.put((byte) TAG_FLOAT_FIXED).putFloat(x); } } }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Integer)) { super.write(buff, obj); return; } int x = (Integer) obj; if (x < 0) { // -Integer.MIN_VALUE is smaller than 0 if (-x < 0 || -x > DataUtils.COMPRESSED_VAR_INT_MAX) { buff.put((byte) TAG_INTEGER_FIXED).putInt(x); } else { buff.put((byte) TAG_INTEGER_NEGATIVE).putVarInt(-x); } } else if (x <= 15) { buff.put((byte) (TAG_INTEGER_0_15 + x)); } else if (x <= DataUtils.COMPRESSED_VAR_INT_MAX) { buff.put((byte) TYPE_INT).putVarInt(x); } else { buff.put((byte) TAG_INTEGER_FIXED).putInt(x); } }
@Override public void write(WriteBuffer buff, Object obj) { if (!(obj instanceof Double)) { super.write(buff, obj); return; } double x = (Double) obj; long d = Double.doubleToLongBits(x); if (d == ObjectDataType.DOUBLE_ZERO_BITS) { buff.put((byte) TAG_DOUBLE_0); } else if (d == ObjectDataType.DOUBLE_ONE_BITS) { buff.put((byte) TAG_DOUBLE_1); } else { long value = Long.reverse(d); if (value >= 0 && value <= DataUtils.COMPRESSED_VAR_LONG_MAX) { buff.put((byte) TYPE_DOUBLE); buff.putVarLong(value); } else { buff.put((byte) TAG_DOUBLE_FIXED); buff.putDouble(x); } } }
@Override public ByteBuffer write(ByteBuffer buff, Object obj) { return last.write(buff, obj); }
@Override public int getMemory(Object obj) { return last.getMemory(obj); }
@Override public int compare(Object a, Object b) { return last.compare(a, b); }
@Override public void write(WriteBuffer buff, Object obj) { last.write(buff, obj); }