Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
top.zeimao77.product.fileio.serialize.SerializeUtil Maven / Gradle / Ivy
package top.zeimao77.product.fileio.serialize;
import sun.misc.Unsafe;
import top.zeimao77.product.exception.BaseServiceRunException;
import top.zeimao77.product.exception.ExceptionCodeDefinition;
import top.zeimao77.product.util.ByteArrayCoDesUtil;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.*;
import static top.zeimao77.product.fileio.serialize.Type.*;
public class SerializeUtil {
public interface DataSerialize {
boolean canRead(byte type);
boolean canWrite(Object t,byte type);
T read(ByteBuffer byteBuffer);
void write(ByteBuffer byteBuffer,T t);
}
static byte nextType(ByteBuffer byteBuffer) {
if(byteBuffer.position() >= byteBuffer.limit())
throw new BaseServiceRunException(ExceptionCodeDefinition.NOT_SUPPORTED,"没有更多可读取数据;");
byteBuffer.mark();
byte b = byteBuffer.get();
byteBuffer.reset();
return b;
}
public static class StringDataSerialize implements DataSerialize{
private Charset charset = StandardCharsets.UTF_8;
public StringDataSerialize(Charset charset) {
this.charset = charset;
}
public StringDataSerialize() {}
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || MAP.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return (t instanceof String) && (STRING.getTypeValue() == type);
}
@Override
public String read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == STRING.getTypeValue()) {
int anInt = byteBuffer.getInt();
byte[] bs = new byte[anInt];
byteBuffer.get(bs,0,anInt);
return new String(bs, charset);
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, String val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(STRING.getTypeValue());
byte[] bytes = val.getBytes(charset);
byteBuffer.putInt(bytes.length);
byteBuffer.put(bytes);
}
}
}
public static class ZipStringDataSerialize implements DataSerialize {
private Charset charset;
public ZipStringDataSerialize(Charset charset) {
this.charset = charset;
}
public ZipStringDataSerialize() {
this.charset = StandardCharsets.UTF_8;
}
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || ZIPSTRING.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t instanceof String;
}
@Override
public String read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == ZIPSTRING.getTypeValue()) {
int anInt = byteBuffer.getInt();
byte[] bs = new byte[anInt];
byteBuffer.get(bs,0,anInt);
byte[] zipDecode = ByteArrayCoDesUtil.zipDecode(bs);
return new String(zipDecode, charset);
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, String val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(ZIPSTRING.getTypeValue());
byte[] bytes = val.getBytes(charset);
byte[] zipDecode = ByteArrayCoDesUtil.zipEncode(bytes);
byteBuffer.putInt(zipDecode.length);
byteBuffer.put(zipDecode);
}
}
}
public static class AutoStringDataSerialize implements DataSerialize {
private int zipSize;
private Charset charset;
private StringDataSerialize stringDataSerialize;
private ZipStringDataSerialize zipStringDataSerialize;
AutoStringDataSerialize(Charset charset,int zipSize) {
this.charset = charset;
this.zipSize = zipSize;
}
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || STRING.getTypeValue() == type
|| ZIPSTRING.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t instanceof String;
}
@Override
public String read(ByteBuffer byteBuffer) {
byte b = nextType(byteBuffer);
if (b == STRING.getTypeValue()) {
if(stringDataSerialize == null)
stringDataSerialize = new StringDataSerialize(charset);
return stringDataSerialize.read(byteBuffer);
}
else {
if(zipStringDataSerialize == null)
zipStringDataSerialize = new ZipStringDataSerialize(charset);
return zipStringDataSerialize.read(byteBuffer);
}
}
@Override
public void write(ByteBuffer byteBuffer, String s) {
if(zipSize == 0 || s.length() < zipSize) {
if(stringDataSerialize == null)
stringDataSerialize = new StringDataSerialize(charset);
stringDataSerialize.write(byteBuffer,s);
} else {
if(zipStringDataSerialize == null)
zipStringDataSerialize = new ZipStringDataSerialize(charset);
zipStringDataSerialize.write(byteBuffer,s);
}
}
}
public static class MapDataSerialize implements DataSerialize> {
DataSerialize serialize;
public MapDataSerialize(DataSerialize serialize) {
this.serialize = serialize;
}
public MapDataSerialize() {
serialize = BASE_DATA_SERIALIZE;
}
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || MAP.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Map;
}
@Override
public Map read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == MAP.getTypeValue()) {
int size = byteBuffer.getInt();
HashMap res = new HashMap<>(size);
for (int i = 0; i < size; i++) {
String key = AUTOSTRING_DATA_SERIALIZE.read(byteBuffer);
Object read = BASE_DATA_SERIALIZE.read(byteBuffer);
res.put(key,read);
}
return res;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Map val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(MAP.getTypeValue());
byteBuffer.putInt(val.size());
for (String key : val.keySet()) {
AUTOSTRING_DATA_SERIALIZE.write(byteBuffer,key);
Object o = val.get(key);
BASE_DATA_SERIALIZE.write(byteBuffer,o);
}
}
}
}
public static class ListDataSerialize implements DataSerialize> {
DataSerialize serialize;
public ListDataSerialize(DataSerialize serialize) {
this.serialize = serialize;
}
public ListDataSerialize() {
this.serialize = BASE_DATA_SERIALIZE;
}
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || ARRAY.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t instanceof List;
}
@Override
public List read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == ARRAY.getTypeValue()) {
int size = byteBuffer.getInt();
ArrayList res = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
res.add(serialize.read(byteBuffer));
}
return res;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, List val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(ARRAY.getTypeValue());
byteBuffer.putInt(val.size());
for (Object o : val) {
serialize.write(byteBuffer,o);
}
}
}
}
public static class SetDataSerialize implements DataSerialize> {
DataSerialize serialize;
public SetDataSerialize(DataSerialize serialize) {
this.serialize = serialize;
}
public SetDataSerialize() {
this.serialize = BASE_DATA_SERIALIZE;
}
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || ARRAY.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t instanceof List;
}
@Override
public Set read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == ARRAY.getTypeValue() || b == SET.getTypeValue()) {
int size = byteBuffer.getInt();
HashSet res = new HashSet<>(size);
for (int i = 0; i < size; i++) {
res.add(serialize.read(byteBuffer));
}
return res;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Set val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(SET.getTypeValue());
byteBuffer.putInt(val.size());
for (Object o : val) {
serialize.write(byteBuffer,o);
}
}
}
}
public static class BaseDataSerializeComponent implements DataSerialize {
@Override
public boolean canRead(byte type) {
return true;
}
@Override
public boolean canWrite(Object t, byte type) {
return true;
}
@Override
public Object read(ByteBuffer byteBuffer) {
byte b = nextType(byteBuffer);
Type type = parse(b);
switch (type) {
case NULL:
return VOID_DATA_SERIALIZER.read(byteBuffer);
case BYTES:
return BYTES_DATA_SERIALIZE.read(byteBuffer);
case CHAR:
return CHARACTER_DATA_SERIALIZE.read(byteBuffer);
case SHORT:
return SHORT_DATA_SERIALIZE.read(byteBuffer);
case BOOL:
return BOOLEAN_DATA_SERIALIZE.read(byteBuffer);
case INT32:
return INTEGER_DATA_SERIALIZE.read(byteBuffer);
case FLOAT:
return FLOAT_DATA_SERIALIZE.read(byteBuffer);
case INT64:
return LONG_DATA_SERIALIZE.read(byteBuffer);
case DOUBLE:
return DOUBLE_DATA_SERIALIZE.read(byteBuffer);
case STRING:
case ZIPSTRING:
return AUTOSTRING_DATA_SERIALIZE.read(byteBuffer);
case TIME:
return LOCAL_TIME_DATA_SERIALIZE.read(byteBuffer);
case DATE:
return LOCAL_DATE_DATA_SERIALIZE.read(byteBuffer);
case DATETIME:
return LOCAL_DATE_TIME_DATA_SERIALIZE.read(byteBuffer);
case ARRAY:
return LIST_DATA_SERIALIZE.read(byteBuffer);
case SET:
return SET_DATA_SERIALIZE.read(byteBuffer);
case MAP:
return MAP_DATA_SERIALIZE.read(byteBuffer);
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Object o) {
if(o == null)
VOID_DATA_SERIALIZER.write(byteBuffer,null);
else if(BYTES_DATA_SERIALIZE.canWrite(byteBuffer, BYTES.getTypeValue()))
BYTES_DATA_SERIALIZE.write(byteBuffer,(byte[])o);
else if(o instanceof Character t)
CHARACTER_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Short t)
SHORT_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Boolean t)
BOOLEAN_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Integer t)
INTEGER_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Float t)
FLOAT_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Long t)
LONG_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Double t)
DOUBLE_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof String t)
AUTOSTRING_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof LocalTime t)
LOCAL_TIME_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof LocalDate t)
LOCAL_DATE_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof LocalDateTime t)
LOCAL_DATE_TIME_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof List t)
LIST_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Set t)
SET_DATA_SERIALIZE.write(byteBuffer,t);
else if(o instanceof Map t)
MAP_DATA_SERIALIZE.write(byteBuffer,t);
}
}
public static final BaseDataSerializeComponent BASE_DATA_SERIALIZE = new BaseDataSerializeComponent();
public static final DataSerialize AUTOSTRING_DATA_SERIALIZE = new AutoStringDataSerialize(StandardCharsets.UTF_8,1024);
public static final DataSerialize INTEGER_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || INT32.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Integer;
}
@Override
public Integer read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if (b == INT32.getTypeValue())
return byteBuffer.getInt();
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Integer val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(INT32.getTypeValue());
byteBuffer.putInt(val);
}
}
};
public static final DataSerialize LONG_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || INT64.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Long;
}
@Override
public Long read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == INT64.getTypeValue())
return byteBuffer.getLong();
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Long val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(INT64.getTypeValue());
byteBuffer.putLong(val);
}
}
};
public static final DataSerialize BOOLEAN_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || BOOL.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Long;
}
@Override
public Boolean read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == BOOL.getTypeValue()) {
byte bool = byteBuffer.get();
return bool == 0x00 ? false : true;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Boolean val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(BOOL.getTypeValue());
byteBuffer.put(val ? (byte) 0x01 : (byte) 0x00);
}
}
};
public static final DataSerialize DOUBLE_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || DOUBLE.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Double;
}
@Override
public Double read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == DOUBLE.getTypeValue())
return byteBuffer.getDouble();
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Double val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(DOUBLE.getTypeValue());
byteBuffer.putDouble(val);
}
}
};
public static final DataSerialize LOCAL_TIME_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || TIME.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof LocalTime;
}
@Override
public LocalTime read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == TIME.getTypeValue()) {
int anInt = byteBuffer.getInt();
LocalTime localTime = LocalTime.ofSecondOfDay(anInt);
return localTime;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, LocalTime val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(TIME.getTypeValue());
int i = val.toSecondOfDay();
byteBuffer.putInt(i);
}
}
};
public static final DataSerialize LOCAL_DATE_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || DATE.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof LocalDate;
}
@Override
public LocalDate read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == DATE.getTypeValue()) {
long aLong = byteBuffer.getLong();
LocalDate localDate = LocalDate.ofEpochDay(aLong);
return localDate;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, LocalDate val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(DATE.getTypeValue());
long i = val.toEpochDay();
byteBuffer.putLong(i);
}
}
};
public static final DataSerialize SHORT_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || SHORT.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Short;
}
@Override
public Short read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == SHORT.getTypeValue())
return byteBuffer.getShort();
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Short val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(SHORT.getTypeValue());
byteBuffer.putShort(val);
}
}
};
public static final DataSerialize FLOAT_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || FLOAT.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Float;
}
@Override
public Float read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == FLOAT.getTypeValue()) {
return byteBuffer.getFloat();
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Float val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(FLOAT.getTypeValue());
byteBuffer.putFloat(val);
}
}
};
public static final DataSerialize LOCAL_DATE_TIME_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || DATETIME.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof LocalDateTime;
}
@Override
public LocalDateTime read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == DATETIME.getTypeValue()) {
long aLong = byteBuffer.getLong();
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(aLong, 0, ZoneOffset.UTC);
return localDateTime;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, LocalDateTime val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(DATETIME.getTypeValue());
long l = val.toEpochSecond(ZoneOffset.UTC);
byteBuffer.putLong(l);
}
}
};
public static final DataSerialize CHARACTER_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || CHAR.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t,byte type) {
return t instanceof Charset;
}
@Override
public Character read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == CHAR.getTypeValue()) {
return byteBuffer.getChar();
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Character val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(CHAR.getTypeValue());
byteBuffer.putChar(val);
}
}
};
public static final DataSerialize BYTES_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || BYTES.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t.getClass().isArray();
}
@Override
public byte[] read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(b == BYTES.getTypeValue()) {
int length = byteBuffer.getInt();
byte[] res = new byte[length];
byteBuffer.get(res,0,length);
return res;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, byte[] val) {
if(val == null)
byteBuffer.put(NULL.getTypeValue());
else {
byteBuffer.put(BYTES.getTypeValue());
byteBuffer.putInt(val.length);
byteBuffer.put(val,0,val.length);
}
}
};
public static final DataSerialize VOID_DATA_SERIALIZER = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t == null;
}
@Override
public Void read(ByteBuffer byteBuffer) {
byteBuffer.get();
return null;
}
@Override
public void write(ByteBuffer byteBuffer, Void unused) {
byteBuffer.put(NULL.getTypeValue());
}
};
public static final DataSerialize> SET_DATA_SERIALIZE = new SetDataSerialize();
public static final DataSerialize> LIST_DATA_SERIALIZE = new ListDataSerialize();
public static final DataSerialize> MAP_DATA_SERIALIZE = new MapDataSerialize();
public static final DataSerialize BIGDECIMAL_DATA_SERIALIZE = new DataSerialize<>() {
@Override
public boolean canRead(byte type) {
return NULL.getTypeValue() == type || DECIMAL.getTypeValue() == type;
}
@Override
public boolean canWrite(Object t, byte type) {
return t instanceof BigDecimal;
}
@Override
public BigDecimal read(ByteBuffer byteBuffer) {
byte b = byteBuffer.get();
if(DECIMAL.getTypeValue() == b) {
short scale = byteBuffer.getShort();
short length = byteBuffer.getShort();
byte[] bs = new byte[length];
byteBuffer.get(bs,0,length);
BigInteger intVal = new BigInteger(bs);
BigDecimal bigDecimal = new BigDecimal(intVal, scale);
return bigDecimal;
}
return null;
}
@Override
public void write(ByteBuffer byteBuffer, BigDecimal val) {
if(val == null) {
byteBuffer.put(NULL.getTypeValue());
return;
}
short scale = (short) val.scale();
byteBuffer.put(DECIMAL.getTypeValue());
byteBuffer.putShort(scale);
try {
Field intVal = BigDecimal.class.getDeclaredField("intVal");
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe)theUnsafe.get(null);
long l = unsafe.objectFieldOffset(intVal);
BigInteger iv = (BigInteger) unsafe.getObject(val, l);
byte[] bs = iv.toByteArray();
short length = (short) bs.length;
byteBuffer.putShort(length);
byteBuffer.put(bs);
} catch (NoSuchFieldException e) {}
catch (IllegalAccessException e) {}
}
};
}