
com.alicp.jetcache.support.AbstractJsonEncoder Maven / Gradle / Ivy
The newest version!
/**
* Created on 2022/07/27.
*/
package com.alicp.jetcache.support;
import com.alicp.jetcache.CacheValueHolder;
import com.alicp.jetcache.anno.SerialPolicy;
import java.nio.charset.StandardCharsets;
/**
* @author huangli
*/
public abstract class AbstractJsonEncoder extends AbstractValueEncoder {
public AbstractJsonEncoder(boolean useIdentityNumber) {
super(useIdentityNumber);
}
protected abstract byte[] encodeSingleValue(Object value);
@Override
public byte[] apply(Object value) {
try {
JsonData[] data = encode(value);
int len = len(data);
byte[] buffer = useIdentityNumber ? new byte[len + 4] : new byte[len];
int index = 0;
if (useIdentityNumber) {
index = writeInt(buffer, index, SerialPolicy.IDENTITY_NUMBER_FASTJSON2);
}
if (data == null) {
writeShort(buffer, index, -1);
} else {
index = writeShort(buffer, index, data.length);
for (JsonData d : data) {
if (d == null) {
index = writeShort(buffer, index, -1);
} else {
index = writeShort(buffer, index, d.getClassName().length);
index = writeBytes(buffer, index, d.getClassName());
index = writeInt(buffer, index, d.getData().length);
index = writeBytes(buffer, index, d.getData());
}
}
}
return buffer;
} catch (Throwable e) {
StringBuilder sb = new StringBuilder("Fastjson Encode error. ");
sb.append("msg=").append(e.getMessage());
throw new CacheEncodeException(sb.toString(), e);
}
}
private int len(JsonData[] data) {
if (data == null) {
return 2;
}
int x = 2;
for (JsonData d : data) {
if (d == null) {
x += 2;
} else {
x += 2 + d.getClassName().length + 4 + d.getData().length;
}
}
return x;
}
private int writeInt(byte[] buf, int index, int value) {
buf[index] = (byte) (value >> 24 & 0xFF);
buf[index + 1] = (byte) (value >> 16 & 0xFF);
buf[index + 2] = (byte) (value >> 8 & 0xFF);
buf[index + 3] = (byte) (value & 0xFF);
return index + 4;
}
private int writeShort(byte[] buf, int index, int value) {
buf[index] = (byte) (value >> 8 & 0xFF);
buf[index + 1] = (byte) (value & 0xFF);
return index + 2;
}
private int writeBytes(byte[] buf, int index, byte[] data) {
System.arraycopy(data, 0, buf, index, data.length);
return index + data.length;
}
private JsonData[] encode(Object value) {
if (value == null) {
return null;
}
if (value instanceof CacheValueHolder) {
CacheValueHolder h = (CacheValueHolder) value;
Object bizObject = h.getValue();
h.setValue(null);
JsonData[] result = new JsonData[2];
result[0] = encodeJsonData(h);
result[1] = encodeJsonData(bizObject);
h.setValue(bizObject);
return result;
} else if (value instanceof CacheMessage) {
CacheMessage cm = (CacheMessage) value;
Object[] keys = cm.getKeys();
cm.setKeys(null);
JsonData[] result = keys == null ? new JsonData[1] : new JsonData[keys.length + 1];
result[0] = encodeJsonData(cm);
if (keys != null) {
for (int i = 0; i < keys.length; i++) {
result[i + 1] = encodeJsonData(keys[i]);
}
}
cm.setKeys(keys);
return result;
} else {
return new JsonData[]{encodeJsonData(value)};
}
}
private JsonData encodeJsonData(Object value) {
if (value == null) {
return null;
}
JsonData jsonData = new JsonData();
jsonData.setClassName(value.getClass().getName().getBytes(StandardCharsets.UTF_8));
jsonData.setData(encodeSingleValue(value));
return jsonData;
}
private static class JsonData {
private byte[] className;
private byte[] data;
public byte[] getClassName() {
return className;
}
public void setClassName(byte[] className) {
this.className = className;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy