开发完成写出功能。现在正在开发读取功能。

master
linbin 2024-09-10 02:37:54 +08:00
parent c1882f5362
commit 5862c362f3
27 changed files with 809 additions and 1082 deletions

10
pom.xml
View File

@ -12,6 +12,8 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<distributionManagement>
<repository>
@ -69,14 +71,6 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,166 +0,0 @@
package com.jfirer.se;
import com.jfirer.se.serializer.Serializer;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class ClassInfo
{
private int classId = ClassInfoResolver.NO_CLASS_ID;
private Class clazz;
private String className;
private Serializer serializer;
private JfireSE jfireSE;
private Object[] tracking;
private boolean refTracking;
private int refTrackingIndex = 0;
public void writeBytes(ByteArray byteArray, Object instance, boolean knownClazz)
{
if (instance == null)
{
byteArray.put(JfireSE.NULL);
return;
}
if (serializer == null)
{
serializer = jfireSE.getSerializer(clazz);
}
if (knownClazz)
{
if (refTracking)
{
int tracking = addTracking(instance);
if (tracking == -1)
{
byteArray.put((byte) 7);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put((byte) 9);
byteArray.writeVarInt(tracking);
}
}
else
{
jfireSE.incrDepth();
byteArray.put((byte) 8);
serializer.writeBytes(byteArray, instance);
jfireSE.reduceDepth();
}
}
else
{
if (refTracking)
{
if (classId == ClassInfoResolver.NO_CLASS_ID)
{
byteArray.put((byte) 1);
byteArray.writeString(className);
jfireSE.getClassId(this);
addTracking(instance);
serializer.writeBytes(byteArray, instance);
}
else
{
int tracking = addTracking(instance);
if (tracking == -1)
{
byteArray.put((byte) 4);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put((byte) 6);
byteArray.writeVarInt(classId);
byteArray.writeVarInt(tracking);
}
}
}
else
{
jfireSE.incrDepth();
if (classId == ClassInfoResolver.NO_CLASS_ID)
{
byteArray.put((byte) 2);
byteArray.writeString(className);
jfireSE.getClassId(this);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put((byte) 5);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
jfireSE.reduceDepth();
}
}
}
public void reset(int tempClassIdStart)
{
if (classId < tempClassIdStart)
{
;
}
else
{
classId = ClassInfoResolver.NO_CLASS_ID;
}
refTrackingIndex = 0;
}
public int addTracking(Object instance)
{
if (tracking == null)
{
tracking = new Object[4];
}
for (int i = 0; i < refTrackingIndex; i++)
{
if (tracking[i] == instance)
{
return i;
}
}
if (refTrackingIndex == tracking.length)
{
Object[] newRefTracking = new Object[tracking.length * 2];
System.arraycopy(tracking, 0, newRefTracking, 0, tracking.length);
tracking = newRefTracking;
}
tracking[refTrackingIndex++] = instance;
return -1;
}
/**
* 3
*
* @param byteArray
* @param refTracking
* @return
*/
public Object readBytes(ByteArray byteArray, boolean refTracking)
{
if (serializer == null)
{
serializer = jfireSE.getSerializer(clazz);
}
Object instance = serializer.readBytes(byteArray);
if (refTracking)
{
addTracking(instance);
}
return instance;
}
public Object getTracking(int instanceId)
{
return tracking[instanceId];
}
}

View File

@ -1,116 +0,0 @@
package com.jfirer.se;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.IdentityHashMap;
import java.util.Map;
public class ClassInfoResolver
{
public static int NO_CLASS_ID = 0;
private Map<Class, ClassInfo> store = new IdentityHashMap<>();
private int nextTempClassId = 1;
private int tempClassIdStart = 1;
private ClassInfo[] tracking = new ClassInfo[32];
private JfireSE jfireSE;
public ClassInfoResolver(JfireSE jfireSE)
{
this.jfireSE = jfireSE;
registerClass(int[].class);
registerClass(long[].class);
registerClass(short[].class);
registerClass(float[].class);
registerClass(double[].class);
registerClass(char[].class);
registerClass(boolean[].class);
registerClass(byte[].class);
registerClass(String[].class);
registerClass(Integer[].class);
registerClass(Long[].class);
registerClass(Short[].class);
registerClass(Float[].class);
registerClass(Double[].class);
registerClass(Character[].class);
registerClass(Boolean[].class);
registerClass(ByteArray[].class);
registerClass(String.class);
registerClass(Integer.class);
registerClass(Long.class);
registerClass(Short.class);
registerClass(Float.class);
registerClass(Double.class);
registerClass(Character.class);
registerClass(Boolean.class);
registerClass(ByteArray.class);
registerClass(Date.class);
registerClass(java.sql.Date.class);
registerClass(LocalDateTime.class);
}
public void getClassId(ClassInfo classInfo)
{
if (nextTempClassId > tracking.length)
{
ClassInfo[] newTracking = new ClassInfo[tracking.length << 1];
System.arraycopy(tracking, 0, newTracking, 0, tracking.length);
tracking = newTracking;
}
tracking[nextTempClassId] = classInfo;
classInfo.setClassId(nextTempClassId);
nextTempClassId += 1;
}
public void reset()
{
for (int i = 1; i < nextTempClassId; i++)
{
tracking[i].reset(tempClassIdStart);
}
nextTempClassId = tempClassIdStart;
}
public ClassInfo getClassInfo(Class clazz)
{
ClassInfo classInfo = store.get(clazz);
if (classInfo == null)
{
classInfo = new ClassInfo().setClassName(clazz.getName()).setJfireSE(jfireSE).setRefTracking(jfireSE.isRefTracking()).setClazz(clazz);
store.put(clazz, classInfo);
return classInfo;
}
return classInfo;
}
public void registerClass(Class clazz)
{
ClassInfo classInfo = getClassInfo(clazz);
if (classInfo == null)
{
classInfo = new ClassInfo().setClassName(clazz.getName()).setJfireSE(jfireSE).setRefTracking(jfireSE.isRefTracking()).setClazz(clazz);
store.put(clazz, classInfo);
}
for (int i = 1; i < tempClassIdStart; i++)
{
if (tracking[i].getClazz() == clazz)
{
return;
}
}
if (tempClassIdStart > tracking.length)
{
ClassInfo[] newTracking = new ClassInfo[tracking.length << 1];
System.arraycopy(tracking, 0, newTracking, 0, tracking.length);
tracking = newTracking;
}
tracking[tempClassIdStart] = classInfo;
classInfo.setClassId(tempClassIdStart);
tempClassIdStart += 1;
nextTempClassId = tempClassIdStart;
}
public ClassInfo getClassInfo(int classId)
{
return tracking[classId];
}
}

View File

@ -1,140 +0,0 @@
package com.jfirer.se;
import com.jfirer.se.serializer.Serializer;
import com.jfirer.se.serializer.SerializerResolver;
import lombok.Getter;
import lombok.experimental.Accessors;
import java.util.HashMap;
import java.util.Map;
@Accessors(chain = true)
public class JfireSE
{
public static final byte NULL = 0;
public static final byte NOT_NULL = 1;
@Getter
private boolean refTracking = true;
private SerializerResolver serializerResolver = new SerializerResolver();
private ClassInfoResolver classInfoResolver = new ClassInfoResolver(this);
private int depth = 1;
private Map<String, Class<?>> classNameMap = new HashMap<>();
private ByteArray byteArray = new ByteArray(1024);
public Serializer getSerializer(Class clazz)
{
return serializerResolver.getSerializer(clazz, this);
}
public ClassInfo getClassInfo(Class clazz)
{
return classInfoResolver.getClassInfo(clazz);
}
public ClassInfo getClassInfo(String className)
{
Class<?> clazz = classNameMap.computeIfAbsent(className, name -> {
try
{
return Class.forName(name);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
});
ClassInfo classInfo = getClassInfo(clazz);
getClassId(classInfo);
return classInfo;
}
public void getClassId(ClassInfo classInfo)
{
classInfoResolver.getClassId(classInfo);
}
public void incrDepth()
{
if (depth++ > 256)
{
throw new IllegalStateException("序列化深度超过256可能存在循环引用请开启循环引用设置");
}
}
public void reduceDepth()
{
depth--;
}
public byte[] writeBytes(Object instance)
{
if (instance == null)
{
byteArray.put(NULL);
}
else
{
ClassInfo classInfo = getClassInfo(instance.getClass());
classInfo.writeBytes(byteArray, instance, false);
classInfoResolver.reset();
}
byte[] result = byteArray.toArray();
byteArray.setWriterIndex(0);
return result;
}
public Object readBytes(byte[] bytes)
{
return readBytes(new ByteArray(bytes));
}
public Object readBytes(ByteArray byteArray)
{
byte flag = byteArray.get();
switch (flag)
{
case 0 -> {return null;}
case 1 ->
{
String className = byteArray.readString();
ClassInfo classInfo = getClassInfo(className);
return classInfo.readBytes(byteArray, true);
}
case 2 ->
{
String className = byteArray.readString();
ClassInfo classInfo = getClassInfo(className);
return classInfo.readBytes(byteArray, false);
}
case 3, 7, 8, 9 ->
{
throw new IllegalArgumentException();
}
case 4 ->
{
int classId = byteArray.readVarInt();
ClassInfo classInfo = classInfoResolver.getClassInfo(classId);
return classInfo.readBytes(byteArray, true);
}
case 5 ->
{
int classId = byteArray.readVarInt();
ClassInfo classInfo = classInfoResolver.getClassInfo(classId);
return classInfo.readBytes(byteArray, false);
}
case 6 ->
{
int classId = byteArray.readVarInt();
int instanceId = byteArray.readVarInt();
ClassInfo classInfo = classInfoResolver.getClassInfo(classId);
return classInfo.getTracking(instanceId);
}
default -> throw new IllegalArgumentException();
}
}
public void registerClass(Class clazz)
{
classInfoResolver.registerClass(clazz);
}
}

View File

@ -1,10 +0,0 @@
package com.jfirer.se.serializer;
import com.jfirer.se.ByteArray;
public interface Serializer
{
void writeBytes(ByteArray byteArray, Object instance);
Object readBytes(ByteArray byteArray);
}

View File

@ -1,54 +0,0 @@
package com.jfirer.se.serializer;
import com.jfirer.se.JfireSE;
import com.jfirer.se.serializer.impl.ArraySerializer;
import com.jfirer.se.serializer.impl.ObjectSerializer;
import io.github.karlatemp.unsafeaccessor.Unsafe;
import java.util.IdentityHashMap;
import java.util.Map;
public class SerializerResolver
{
private Map<Class, Serializer> store = new IdentityHashMap<>();
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
public SerializerResolver()
{
}
public Serializer getSerializer(Class clazz, JfireSE jfireSE)
{
Serializer serializer = store.get(clazz);
if (serializer != null)
{
return serializer;
}
if (clazz.isArray())
{
serializer = new ArraySerializer(clazz, jfireSE);
}
else
{
serializer = new ObjectSerializer(clazz, jfireSE);
}
store.put(clazz, serializer);
return serializer;
}
public void registerSerializer(Class clazz, Serializer serializer)
{
store.put(clazz, serializer);
}
private static int getShift(int value)
{
int count = 0;
while (value != 0)
{
count++;
value >>= 1;
}
return count - 1;
}
}

View File

@ -1,99 +0,0 @@
package com.jfirer.se.serializer.impl;
import com.jfirer.se.ByteArray;
import com.jfirer.se.ClassInfo;
import com.jfirer.se.JfireSE;
import com.jfirer.se.serializer.Serializer;
import io.github.karlatemp.unsafeaccessor.Unsafe;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
@SuppressWarnings("rawtypes")
public class ArraySerializer implements Serializer
{
private Class componentType;
private int arrayBaseOffset;
private int arrayIndexScale;
private int arrayIndexScaleShift;
private boolean componentTypeFinal;
private ClassInfo classInfoOfComponentTypeFinal;
private ClassInfo cachedClassInfo;
private JfireSE jfireSE;
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
public ArraySerializer(Class clazz, JfireSE jfireSE)
{
this.jfireSE = jfireSE;
componentType = clazz.getComponentType();
arrayBaseOffset = UNSAFE.arrayBaseOffset(clazz);
arrayIndexScale = UNSAFE.arrayIndexScale(clazz);
arrayIndexScaleShift = arrayIndexScale == 4 ? 2 : 3;
componentTypeFinal = Modifier.isFinal(componentType.getModifiers());
if (componentTypeFinal)
{
classInfoOfComponentTypeFinal = jfireSE.getClassInfo(componentType);
}
}
@Override
public void writeBytes(ByteArray byteArray, Object instance)
{
int length = ((Object[]) instance).length;
byteArray.writeVarInt(length);
for (int i = 0; i < length; i++)
{
Object element = UNSAFE.getReference(instance, arrayBaseOffset + ((long) i << arrayIndexScaleShift));
if (element == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
if (componentTypeFinal)
{
classInfoOfComponentTypeFinal.writeBytes(byteArray, element, true);
}
else
{
if (cachedClassInfo != null && cachedClassInfo.getClazz() == element.getClass())
{
cachedClassInfo.writeBytes(byteArray, element, false);
}
else
{
cachedClassInfo = jfireSE.getClassInfo(element.getClass());
cachedClassInfo.writeBytes(byteArray, element, false);
}
}
}
}
}
@Override
public Object readBytes(ByteArray byteArray)
{
int length = byteArray.readVarInt();
Object array = Array.newInstance(componentType, length);
for (int i = 0; i < length; i++)
{
if (componentTypeFinal)
{
int flag = byteArray.readVarInt();
switch (flag)
{
case JfireSE.NULL -> UNSAFE.putReference(array, arrayBaseOffset + ((long) i << arrayIndexScaleShift), null);
case 7 -> UNSAFE.putReference(array, arrayBaseOffset + ((long) i << arrayIndexScaleShift), classInfoOfComponentTypeFinal.readBytes(byteArray, true));
case 8 -> UNSAFE.putReference(array, arrayBaseOffset + ((long) i << arrayIndexScaleShift), classInfoOfComponentTypeFinal.readBytes(byteArray, false));
case 9 -> UNSAFE.putReference(array, arrayBaseOffset + ((long) i << arrayIndexScaleShift), classInfoOfComponentTypeFinal.getTracking(byteArray.readVarInt()));
default -> throw new IllegalArgumentException();
}
}
else
{
UNSAFE.putReference(array, arrayBaseOffset + ((long) i << arrayIndexScaleShift), jfireSE.readBytes(byteArray));
}
}
return array;
}
}

View File

@ -1,440 +0,0 @@
package com.jfirer.se.serializer.impl;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.baseutil.reflect.ValueAccessor;
import com.jfirer.se.ByteArray;
import com.jfirer.se.ClassInfo;
import com.jfirer.se.JfireSE;
import com.jfirer.se.serializer.Serializer;
import io.github.karlatemp.unsafeaccessor.Unsafe;
import lombok.Data;
import lombok.SneakyThrows;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
@SuppressWarnings("rawtypes")
public class ObjectSerializer implements Serializer
{
private FieldInfo[] primitiveFieldInfos;
private FieldInfo[] boxFieldInfos;
private FinalFieldInfo[] finalFieldInfos;
private VariableFieldInfo[] variableFieldInfos;
private JfireSE jfireSE;
private Class clazz;
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
public ObjectSerializer(Class clazz, JfireSE jfireSE)
{
this.clazz = clazz;
this.jfireSE = jfireSE;
Class type = clazz;
List<Field> fields = new ArrayList<>();
while (type != Object.class)
{
fields.addAll(Arrays.stream(type.getDeclaredFields()).filter(Predicate.not(field -> Modifier.isStatic(field.getModifiers()))).toList());
type = type.getSuperclass();
}
primitiveFieldInfos = fields.stream().filter(field -> field.getType().isPrimitive()).sorted(Comparator.comparing(o -> o.getType().getName())).map(FieldInfo::new).toArray(FieldInfo[]::new);
boxFieldInfos = fields.stream().filter(field -> ReflectUtil.isPrimitiveBox(field.getType()) || field.getType() == String.class).sorted(Comparator.comparing(o -> o.getType().getName())).map(FieldInfo::new).toArray(FieldInfo[]::new);
finalFieldInfos = fields.stream().filter(Predicate.not(field -> ReflectUtil.isPrimitiveBox(field.getType())))//
.filter(Predicate.not(field -> ReflectUtil.isPrimitive(field.getType())))//
.filter(field -> field.getType() != String.class)//
.filter(field -> field.getType() != void.class && field.getType() != Void.class)//
.filter(field -> Modifier.isFinal(field.getType().getModifiers()))//
.sorted(Comparator.comparing(o -> o.getType().getName()))//
.map(FinalFieldInfo::new).toArray(FinalFieldInfo[]::new);
variableFieldInfos = fields.stream().filter(Predicate.not(field -> ReflectUtil.isPrimitiveBox(field.getType())))//
.filter(Predicate.not(field -> ReflectUtil.isPrimitive(field.getType())))//
.filter(field -> field.getType() != String.class)//
.filter(field -> field.getType() != void.class && field.getType() != Void.class)//
.filter(field -> !Modifier.isFinal(field.getType().getModifiers()))//
.sorted(Comparator.comparing(o -> o.getType().getName()))//
.map(VariableFieldInfo::new).toArray(VariableFieldInfo[]::new);
}
@Override
public void writeBytes(ByteArray byteArray, Object instance)
{
for (FieldInfo primitiveFieldInfo : primitiveFieldInfos)
{
primitiveFieldInfo.write(byteArray, instance);
}
for (FieldInfo boxFieldInfo : boxFieldInfos)
{
boxFieldInfo.write(byteArray, instance);
}
for (FinalFieldInfo finalFieldInfo : finalFieldInfos)
{
finalFieldInfo.write(byteArray, instance);
}
for (VariableFieldInfo variableFieldInfo : variableFieldInfos)
{
variableFieldInfo.write(byteArray, instance);
}
}
@SneakyThrows
@Override
public Object readBytes(ByteArray byteArray)
{
Object instance = UNSAFE.allocateInstance(clazz);
for (FieldInfo primitiveFieldInfo : primitiveFieldInfos)
{
primitiveFieldInfo.read(byteArray, instance);
}
for (FieldInfo boxFieldInfo : boxFieldInfos)
{
boxFieldInfo.read(byteArray, instance);
}
for (FinalFieldInfo finalFieldInfo : finalFieldInfos)
{
finalFieldInfo.read(byteArray, instance);
}
for (VariableFieldInfo variableFieldInfo : variableFieldInfos)
{
variableFieldInfo.read(byteArray, instance);
}
return instance;
}
@Data
class FieldInfo
{
int classId;
ValueAccessor accessor;
FieldInfo(Field field)
{
classId = ReflectUtil.getClassId(field.getType());
accessor = new ValueAccessor(field);
}
void read(ByteArray byteArray, Object instance)
{
switch (classId)
{
case ReflectUtil.PRIMITIVE_INT -> accessor.set(instance, byteArray.readVarInt());
case ReflectUtil.PRIMITIVE_LONG -> accessor.set(instance, byteArray.readVarLong());
case ReflectUtil.PRIMITIVE_FLOAT -> accessor.set(instance, byteArray.readFloat());
case ReflectUtil.PRIMITIVE_DOUBLE -> accessor.set(instance, byteArray.readDouble());
case ReflectUtil.PRIMITIVE_BOOL -> accessor.set(instance, byteArray.readBoolean() );
case ReflectUtil.PRIMITIVE_CHAR -> accessor.set(instance, byteArray.readChar());
case ReflectUtil.PRIMITIVE_SHORT -> accessor.set(instance, byteArray.readShort());
case ReflectUtil.PRIMITIVE_BYTE -> accessor.set(instance, byteArray.get());
case ReflectUtil.CLASS_INT ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readVarInt());
}
}
case ReflectUtil.CLASS_LONG ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readVarLong());
}
}
case ReflectUtil.CLASS_FLOAT ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readFloat());
}
}
case ReflectUtil.CLASS_DOUBLE ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readDouble());
}
}
case ReflectUtil.CLASS_BOOL ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readBoolean());
}
}
case ReflectUtil.CLASS_CHAR ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readChar());
}
}
case ReflectUtil.CLASS_SHORT ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.readShort());
}
}
case ReflectUtil.CLASS_BYTE ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.set(instance, byteArray.get());
}
}
case ReflectUtil.CLASS_STRING ->
{
if (byteArray.get() == JfireSE.NULL)
{
accessor.setObject(instance, null);
}
else
{
accessor.setObject(instance, byteArray.readString());
}
}
}
}
void write(ByteArray byteArray, Object instance)
{
switch (classId)
{
case ReflectUtil.PRIMITIVE_INT -> byteArray.writeVarInt(accessor.getInt(instance));
case ReflectUtil.PRIMITIVE_LONG -> byteArray.writeVarLong(accessor.getLong(instance));
case ReflectUtil.PRIMITIVE_FLOAT -> byteArray.writeFloat(accessor.getFloat(instance));
case ReflectUtil.PRIMITIVE_DOUBLE -> byteArray.writeDouble(accessor.getDouble(instance));
case ReflectUtil.PRIMITIVE_BOOL -> byteArray.writeBoolean(accessor.getBoolean(instance));
case ReflectUtil.PRIMITIVE_CHAR -> byteArray.writeChar(accessor.getChar(instance));
case ReflectUtil.PRIMITIVE_SHORT -> byteArray.writeShort(accessor.getShort(instance));
case ReflectUtil.PRIMITIVE_BYTE -> byteArray.put(accessor.getByte(instance));
case ReflectUtil.CLASS_INT ->
{
Integer value = accessor.getIntObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeVarInt(value);
}
}
case ReflectUtil.CLASS_LONG ->
{
Long value = accessor.getLongObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeVarLong(value);
}
}
case ReflectUtil.CLASS_FLOAT ->
{
Float value = accessor.getFloatObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeFloat(value);
}
}
case ReflectUtil.CLASS_DOUBLE ->
{
Double value = accessor.getDoubleObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeDouble(value);
}
}
case ReflectUtil.CLASS_BOOL ->
{
Boolean value = accessor.getBooleanObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.put((byte) (value ? 1 : 0));
}
}
case ReflectUtil.CLASS_CHAR ->
{
Character value = accessor.getCharObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeChar(value);
}
}
case ReflectUtil.CLASS_SHORT ->
{
Short value = accessor.getShortObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeShort(value);
}
}
case ReflectUtil.CLASS_BYTE ->
{
Byte value = accessor.getByteObject(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.put(value);
}
}
case ReflectUtil.CLASS_STRING ->
{
String value = (String) accessor.get(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeString(value);
}
}
default -> throw new IllegalArgumentException();
}
}
}
class FinalFieldInfo
{
ValueAccessor accessor;
ClassInfo classInfo;
FinalFieldInfo(Field field)
{
accessor = new ValueAccessor(field);
classInfo = jfireSE.getClassInfo(field.getType());
}
void write(ByteArray byteArray, Object instance)
{
Object value = accessor.get(instance);
if (value == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
classInfo.writeBytes(byteArray, value, true);
}
}
public void read(ByteArray byteArray, Object instance)
{
byte flag = byteArray.get();
switch (flag)
{
case JfireSE.NULL -> accessor.setObject(instance, null);
case 7 -> accessor.setObject(instance, classInfo.readBytes(byteArray, true));
case 8 -> accessor.setObject(instance, classInfo.readBytes(byteArray, false));
case 9 -> accessor.setObject(instance, classInfo.getTracking(byteArray.readVarInt()));
default -> throw new IllegalArgumentException();
}
}
}
class VariableFieldInfo
{
ValueAccessor accessor;
ClassInfo classInfo;
VariableFieldInfo(Field field)
{
accessor = new ValueAccessor(field);
}
void write(ByteArray byteArray, Object instance)
{
if (instance == null)
{
byteArray.put(JfireSE.NULL);
return;
}
Class<?> clazz = instance.getClass();
if (classInfo != null && classInfo.getClazz() == clazz)
{
classInfo.writeBytes(byteArray, instance, false);
}
else
{
classInfo = jfireSE.getClassInfo(clazz);
classInfo.writeBytes(byteArray, instance, false);
}
}
void read(ByteArray byteArray, Object instance)
{
accessor.setObject(instance, jfireSE.readBytes(byteArray));
}
}
}

View File

@ -1,4 +1,4 @@
package com.jfirer.se;
package com.jfirer.se2;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.fse.InternalByteArray;

View File

@ -0,0 +1,39 @@
package com.jfirer.se2;
public interface JfireSE
{
byte NULL = 0;
byte NOT_NULL = 1;
byte NAME_ID_CONTENT_TRACK = 2;
byte NAME_ID_CONTENT_UN_TRACK = 3;
byte ID_INSTANCE_ID = 4;
byte id_content_track = 5;
byte id_content_un_track = 6;
byte instance_id = 7;
byte content_track = 8;
byte content_un_track = 9;
static JfireSEConfig supportRefTracking(boolean support)
{
return new JfireSEConfig().setRefTracking(support);
}
static JfireSEConfig useCompile()
{
return new JfireSEConfig().useCompile();
}
static JfireSEConfig staticRegisterClass(Class<?> clazz)
{
return new JfireSEConfig().staticRegisterClass(clazz);
}
static JfireSE build()
{
return new JfireSEConfig().build();
}
byte[] write(Object instance);
Object read(byte[] bytes);
}

View File

@ -0,0 +1,65 @@
package com.jfirer.se2;
import com.jfirer.se2.classinfo.StaticClasInfo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.*;
@Data
@Accessors(chain = true)
public class JfireSEConfig
{
private boolean refTracking = false;
private boolean useCompile = false;
private short staticClassId = 0;
private StaticClasInfo[] clasInfos = new StaticClasInfo[10];
private List<Class<?>> list = new LinkedList<>();
private Set<Class<?>> set = new HashSet<>();
public JfireSEConfig()
{
staticRegisterClass(ArrayList.class);
staticRegisterClass(HashSet.class);
staticRegisterClass(HashMap.class);
staticRegisterClass(LinkedList.class);
}
public JfireSEConfig useCompile()
{
useCompile = true;
return this;
}
public JfireSEConfig refTracking()
{
refTracking = true;
return this;
}
public JfireSEConfig staticRegisterClass(Class<?> clazz)
{
if (set.add(clazz))
{
list.add(clazz);
return this;
}
else
{
throw new IllegalArgumentException("重复添加");
}
}
public JfireSE build()
{
StaticClasInfo[] array = list.stream().map(this::resolve).toArray(StaticClasInfo[]::new);
return new JfireSEImpl(refTracking, array);
}
private StaticClasInfo resolve(Class<?> clazz)
{
StaticClasInfo staticClasInfo = new StaticClasInfo(staticClassId, clazz.getName(), clazz, refTracking);
staticClassId++;
return staticClasInfo;
}
}

View File

@ -0,0 +1,130 @@
package com.jfirer.se2;
import com.jfirer.se2.classinfo.ClassInfo;
import com.jfirer.se2.classinfo.DynamicClassInfo;
import com.jfirer.se2.classinfo.StaticClasInfo;
import com.jfirer.se2.serializer.Serializer;
import com.jfirer.se2.serializer.SerializerFactory;
public class JfireSEImpl implements JfireSE
{
private final boolean refTracking;
private final int staticClassId;
private int dyncmicClassId;
/**
* classInfo
*/
private ClassInfo[] serializedClassInfos;
/**
*
*/
private ClassInfo[] deSerializedClassInfos;
private SerializerFactory serializerFactory = new SerializerFactory();
private ByteArray byteArray = new ByteArray(1000);
public JfireSEImpl(boolean refTracking, StaticClasInfo[] staticClasInfos)
{
this.refTracking = refTracking;
this.staticClassId = staticClasInfos.length - 1;
serializedClassInfos = new ClassInfo[staticClasInfos.length * 2];
deSerializedClassInfos = new ClassInfo[serializedClassInfos.length];
System.arraycopy(staticClasInfos, 0, serializedClassInfos, 0, staticClasInfos.length);
System.arraycopy(staticClasInfos, 0, deSerializedClassInfos, 0, staticClasInfos.length);
dyncmicClassId = staticClassId + 1;
}
public ClassInfo getForSerialize(Class<?> clazz)
{
for (int i = 0; i < dyncmicClassId; i++)
{
if (serializedClassInfos[i].getClazz() == clazz)
{
return serializedClassInfos[i];
}
}
if (dyncmicClassId == serializedClassInfos.length)
{
ClassInfo[] tmp = new ClassInfo[serializedClassInfos.length * 2];
System.arraycopy(serializedClassInfos, 0, tmp, 0, serializedClassInfos.length);
serializedClassInfos = tmp;
}
DynamicClassInfo dynamicClassInfo = new DynamicClassInfo((short) dyncmicClassId, clazz.getName(), clazz, refTracking);
serializedClassInfos[dyncmicClassId] = dynamicClassInfo;
dyncmicClassId++;
Serializer serializer = serializerFactory.getSerializer(clazz, this);
dynamicClassInfo.setSerializer(serializer);
return dynamicClassInfo;
}
private void resetSerialized()
{
for (int i = staticClassId; i < dyncmicClassId; i++)
{
serializedClassInfos[i].reset();
}
}
@Override
public byte[] write(Object instance)
{
if (instance == null)
{
byteArray.put(JfireSE.NULL);
byte[] array = byteArray.toArray();
byteArray.clear();
return array;
}
ClassInfo classInfo = getForSerialize(instance.getClass());
classInfo.write(byteArray, instance);
byte[] array = byteArray.toArray();
byteArray.clear();
resetSerialized();
return array;
}
@Override
public Object read(byte[] bytes)
{
ByteArray stream = new ByteArray(bytes);
byte b = stream.get();
if (b == JfireSE.NULL)
{
return null;
}
switch (b)
{
case JfireSE.NAME_ID_CONTENT_TRACK ->
{
String className = byteArray.readString();
int classId = byteArray.readVarInt();
try
{
Class<?> clazz = Class.forName(className);
ClassInfo classInfo = getForSerialize(clazz);
if (deSerializedClassInfos == null)
{
deSerializedClassInfos = new ClassInfo[classId + 1];
deSerializedClassInfos[classId] = classInfo;
}
else if (classId >= deSerializedClassInfos.length)
{
int newLen = deSerializedClassInfos.length * 2;
newLen = newLen > classId ? newLen : classId + 1;
ClassInfo[] tmp = new ClassInfo[newLen];
System.arraycopy(deSerializedClassInfos, 0, tmp, 0, deSerializedClassInfos.length);
deSerializedClassInfos = tmp;
deSerializedClassInfos[classId] = classInfo;
}
else
{
deSerializedClassInfos[classId] = classInfo;
}
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
}
}
}

View File

@ -0,0 +1,79 @@
package com.jfirer.se2.classinfo;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.serializer.Serializer;
import lombok.Data;
import java.util.Arrays;
@Data
public abstract class ClassInfo
{
protected final short classId;
protected final String className;
protected final Class<?> clazz;
protected final boolean refTrack;
protected Object[] tracking;
protected int refTrackingIndex = 0;
protected Serializer serializer;
public int addTracking(Object instance)
{
if (tracking == null)
{
tracking = new Object[4];
}
for (int i = 0; i < refTrackingIndex; i++)
{
if (tracking[i] == instance)
{
return i;
}
}
if (refTrackingIndex == tracking.length)
{
Object[] newRefTracking = new Object[tracking.length * 2];
System.arraycopy(tracking, 0, newRefTracking, 0, tracking.length);
tracking = newRefTracking;
}
tracking[refTrackingIndex++] = instance;
return -1;
}
public void reset()
{
if (refTrackingIndex != 0)
{
Arrays.fill(tracking, 0, refTrackingIndex, null);
refTrackingIndex = 0;
}
}
public abstract void write(ByteArray byteArray, Object instance);
public void writeKnownClazz(ByteArray byteArray, Object instance)
{
if (refTrack)
{
int index = addTracking(instance);
if (index == -1)
{
byteArray.put(JfireSE.content_track);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put(JfireSE.instance_id);
byteArray.writeVarInt(index);
}
}
else
{
byteArray.put(JfireSE.content_un_track);
serializer.writeBytes(byteArray, instance);
}
}
public abstract void readWithTrack(ByteArray byteArray);
}

View File

@ -0,0 +1,80 @@
package com.jfirer.se2.classinfo;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
public class DynamicClassInfo extends ClassInfo
{
/**
*
*/
private boolean firstSerialized = true;
public DynamicClassInfo(short classId, String className, Class<?> clazz, boolean refTracking)
{
super(classId, className, clazz, refTracking);
}
@Override
public void reset()
{
super.reset();
firstSerialized = true;
}
@Override
public void write(ByteArray byteArray, Object instance)
{
if (refTrack)
{
if (firstSerialized)
{
firstSerialized = true;
addTracking(instance);
byteArray.put(JfireSE.NAME_ID_CONTENT_TRACK);
byteArray.writeString(className);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
else
{
int i = addTracking(instance);
if (i == -1)
{
byteArray.put(JfireSE.id_content_track);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put(JfireSE.ID_INSTANCE_ID);
byteArray.writeVarInt(classId);
byteArray.writeVarInt(i);
}
}
}
else
{
if (firstSerialized)
{
firstSerialized = true;
byteArray.put(JfireSE.NAME_ID_CONTENT_UN_TRACK);
byteArray.writeString(className);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put(JfireSE.id_content_un_track);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
}
}
}

View File

@ -0,0 +1,39 @@
package com.jfirer.se2.classinfo;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
public class StaticClasInfo extends ClassInfo
{
public StaticClasInfo(short classId, String className, Class<?> clazz, boolean refTracking)
{
super(classId, className, clazz, refTracking);
}
@Override
public void write(ByteArray byteArray, Object instance)
{
if (refTrack)
{
int i = addTracking(instance);
if (i == -1)
{
byteArray.put(JfireSE.id_content_track);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
else
{
byteArray.put(JfireSE.ID_INSTANCE_ID);
byteArray.writeVarInt(classId);
byteArray.writeVarInt(i);
}
}
else
{
byteArray.put(JfireSE.id_content_un_track);
byteArray.writeVarInt(classId);
serializer.writeBytes(byteArray, instance);
}
}
}

View File

@ -0,0 +1,10 @@
package com.jfirer.se2.serializer;
import com.jfirer.se2.ByteArray;
public interface Serializer
{
void writeBytes(ByteArray byteArray, Object instance);
Object read(ByteArray stream);
}

View File

@ -0,0 +1,17 @@
package com.jfirer.se2.serializer;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.serializer.impl.ObjectSerializer.ObjectSerializer;
import java.util.HashMap;
import java.util.Map;
public class SerializerFactory
{
private Map<Class<?>, Serializer> store = new HashMap<>();
public Serializer getSerializer(Class<?> clazz, JfireSEImpl jfireSE)
{
return store.putIfAbsent(clazz, new ObjectSerializer(clazz, jfireSE));
}
}

View File

@ -0,0 +1,142 @@
package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.baseutil.reflect.ValueAccessor;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import java.lang.reflect.Field;
public class BoxedFieldInfo extends FieldInfo
{
public BoxedFieldInfo(Field field)
{
super(ReflectUtil.getClassId(field.getType()), new ValueAccessor(field));
}
@Override
public void write(ByteArray byteArray, Object instance)
{
switch (classId)
{
case ReflectUtil.CLASS_BOOL ->
{
Boolean obj = accessor.getBooleanObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeBoolean(obj);
}
}
case ReflectUtil.CLASS_BYTE ->
{
Byte obj = accessor.getByteObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.put(obj);
}
}
case ReflectUtil.CLASS_CHAR ->
{
Character obj = accessor.getCharObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeChar(obj);
}
}
case ReflectUtil.CLASS_SHORT ->
{
Short obj = accessor.getShortObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeVarInt(obj);
}
}
case ReflectUtil.CLASS_INT ->
{
Integer obj = accessor.getIntObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeVarInt(obj);
}
}
case ReflectUtil.CLASS_LONG ->
{
Long obj = accessor.getLongObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeVarLong(obj);
}
}
case ReflectUtil.CLASS_FLOAT ->
{
Float obj = accessor.getFloatObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeFloat(obj);
}
}
case ReflectUtil.CLASS_DOUBLE ->
{
Double obj = accessor.getDoubleObject(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeDouble(obj);
}
}
case ReflectUtil.CLASS_STRING ->
{
String obj = (String) accessor.get(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
byteArray.put(JfireSE.NOT_NULL);
byteArray.writeString(obj);
}
}
default -> throw new RuntimeException("不支持的类型");
}
}
}

View File

@ -0,0 +1,18 @@
package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.baseutil.reflect.ValueAccessor;
import com.jfirer.se2.ByteArray;
public abstract class FieldInfo
{
protected int classId;
protected ValueAccessor accessor;
public FieldInfo(int classId, ValueAccessor accessor)
{
this.classId = classId;
this.accessor = accessor;
}
public abstract void write(ByteArray byteArray, Object instance);
}

View File

@ -0,0 +1,35 @@
package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.baseutil.reflect.ValueAccessor;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.classinfo.ClassInfo;
import java.lang.reflect.Field;
public class FinalFieldInfo extends FieldInfo
{
private ClassInfo classInfo;
public FinalFieldInfo(Field field, JfireSEImpl jfireSE)
{
super(ReflectUtil.getClassId(field.getType()), new ValueAccessor(field));
classInfo = jfireSE.getForSerialize(field.getType());
}
@Override
public void write(ByteArray byteArray, Object instance)
{
Object obj = accessor.get(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
classInfo.writeKnownClazz(byteArray, obj);
}
}
}

View File

@ -0,0 +1,67 @@
package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.serializer.Serializer;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.function.Predicate;
public class ObjectSerializer implements Serializer
{
private Class<?> clazz;
private FieldInfo[] fieldInfos;
public ObjectSerializer(Class<?> clazz, JfireSEImpl jfireSE)
{
Class type = clazz;
List<Field> fields = new ArrayList<>();
while (type != Object.class)
{
fields.addAll(Arrays.stream(type.getDeclaredFields()).filter(Predicate.not(field -> Modifier.isStatic(field.getModifiers()))).toList());
type = type.getSuperclass();
}
List<PrimitiveFieldInfo> primitiveFieldInfos = fields.stream().filter(field -> field.getType().isPrimitive())//
.sorted(Comparator.comparing(o -> o.getType().getName()))//
.map(PrimitiveFieldInfo::new)//
.toList();
List<BoxedFieldInfo> boxedFieldInfos = fields.stream().filter(field -> ReflectUtil.isPrimitiveBox(field.getType()) || field.getType() == String.class)//
.sorted(Comparator.comparing(o -> o.getType().getName()))//
.map(BoxedFieldInfo::new)//
.toList();
List<FinalFieldInfo> finalFieldInfos = fields.stream().filter(Predicate.not(field -> ReflectUtil.isPrimitiveBox(field.getType())))//
.filter(Predicate.not(field -> ReflectUtil.isPrimitive(field.getType())))//
.filter(field -> field.getType() != String.class)//
.filter(field -> field.getType() != void.class && field.getType() != Void.class)//
.filter(field -> Modifier.isFinal(field.getType().getModifiers()))//
.sorted(Comparator.comparing(o -> o.getType().getName()))//
.map(field -> new FinalFieldInfo(field, jfireSE))//
.toList();
List<VariableFieldInfo> variableFieldInfos = fields.stream().filter(Predicate.not(field -> ReflectUtil.isPrimitiveBox(field.getType())))//
.filter(Predicate.not(field -> ReflectUtil.isPrimitive(field.getType())))//
.filter(field -> field.getType() != String.class)//
.filter(field -> field.getType() != void.class && field.getType() != Void.class)//
.filter(field -> !Modifier.isFinal(field.getType().getModifiers()))//
.sorted(Comparator.comparing(o -> o.getType().getName()))//
.map(field -> new VariableFieldInfo(field, jfireSE))//
.toList();
List<FieldInfo> list = new LinkedList<>();
list.addAll(primitiveFieldInfos);
list.addAll(boxedFieldInfos);
list.addAll(finalFieldInfos);
list.addAll(variableFieldInfos);
fieldInfos = list.toArray(FieldInfo[]::new);
}
@Override
public void writeBytes(ByteArray byteArray, Object instance)
{
for (FieldInfo each : fieldInfos)
{
each.write(byteArray, instance);
}
}
}

View File

@ -0,0 +1,31 @@
package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.baseutil.reflect.ValueAccessor;
import com.jfirer.se2.ByteArray;
import java.lang.reflect.Field;
public class PrimitiveFieldInfo extends FieldInfo
{
public PrimitiveFieldInfo(Field field)
{
super(ReflectUtil.getClassId(field.getType()), new ValueAccessor(field));
}
public void write(ByteArray byteArray, Object instance)
{
switch (classId)
{
case ReflectUtil.PRIMITIVE_BYTE -> byteArray.put(accessor.getByte(instance));
case ReflectUtil.PRIMITIVE_INT -> byteArray.writeVarInt(accessor.getInt(instance));
case ReflectUtil.PRIMITIVE_SHORT -> byteArray.writeVarInt(accessor.getShort(instance));
case ReflectUtil.PRIMITIVE_LONG -> byteArray.writeVarLong(accessor.getLong(instance));
case ReflectUtil.PRIMITIVE_FLOAT -> byteArray.writeFloat(accessor.getFloat(instance));
case ReflectUtil.PRIMITIVE_DOUBLE -> byteArray.writeDouble(accessor.getDouble(instance));
case ReflectUtil.PRIMITIVE_BOOL -> byteArray.writeBoolean(accessor.getBoolean(instance));
case ReflectUtil.PRIMITIVE_CHAR -> byteArray.writeChar(accessor.getChar(instance));
default -> throw new RuntimeException("不支持的类型");
}
}
}

View File

@ -0,0 +1,46 @@
package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.baseutil.reflect.ValueAccessor;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.classinfo.ClassInfo;
import java.lang.reflect.Field;
public class VariableFieldInfo extends FieldInfo
{
private final JfireSEImpl jfireSE;
private ClassInfo classInfo;
public VariableFieldInfo(Field field, JfireSEImpl jfireSE)
{
super(ReflectUtil.getClassId(field.getType()), new ValueAccessor(field));
classInfo = jfireSE.getForSerialize(field.getType());
this.jfireSE = jfireSE;
}
@Override
public void write(ByteArray byteArray, Object instance)
{
Object obj = accessor.get(instance);
if (obj == null)
{
byteArray.put(JfireSE.NULL);
}
else
{
Class<?> objClass = obj.getClass();
if (objClass == classInfo.getClazz())
{
classInfo.write(byteArray, obj);
}
else
{
classInfo = jfireSE.getForSerialize(objClass);
classInfo.write(byteArray, instance);
}
}
}
}

View File

@ -2,7 +2,7 @@ package org.example;
import com.jfirer.fse.ByteArray;
import com.jfirer.fse.Fse;
import com.jfirer.se.JfireSE;
import com.jfirer.se2.JfireSE;
import io.fury.Fury;
import io.fury.config.Language;
import org.openjdk.jmh.annotations.*;
@ -28,7 +28,7 @@ public class BenchMark
Fury fury = Fury.builder().withLanguage(Language.JAVA)//
.requireClassRegistration(false)//
.withRefTracking(true).build();
JfireSE jfireSE = new JfireSE();
JfireSE jfireSE = JfireSE.build();
@Benchmark
public void testNoCompile()
@ -53,7 +53,7 @@ public class BenchMark
@Benchmark
public void testJfireSE()
{
jfireSE.writeBytes(data);
jfireSE.write(data);
}
public static void main(String[] args) throws RunnerException

View File

@ -1,43 +0,0 @@
package org.example;
import io.github.karlatemp.unsafeaccessor.Unsafe;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 2, time = 1)
@Measurement(iterations = 3, time = 10)
@OutputTimeUnit(TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Benchmark)
public class BenchMarkUnsafe
{
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
char c = '你';
char Rec = Character.reverseBytes(c);
private byte[] array = new byte[2];
private long offset = UNSAFE.arrayBaseOffset(byte[].class);
@Benchmark
public void write()
{
UNSAFE.putChar(array, offset, c);
}
@Benchmark
public void writeRe()
{
UNSAFE.putChar(array, offset, Rec);
}
public static void main(String[] args) throws RunnerException
{
Options opt = new OptionsBuilder().include(BenchMarkUnsafe.class.getSimpleName()).build();
new Runner(opt).run();
}
}

View File

@ -1,6 +1,6 @@
package org.example;
import com.jfirer.se.ByteArray;
import com.jfirer.se2.ByteArray;
import org.junit.Assert;
import org.junit.Test;

View File

@ -1,7 +1,10 @@
package org.example;
import lombok.Data;
import java.io.Serializable;
@Data
public class TestData implements Serializable
{
private int a = 213212312;
@ -12,7 +15,7 @@ public class TestData implements Serializable
private long f = 1213124131312321L;
private double g = 231321.2132;
private float h = (float) 4986.2;
// private String i = "123452312316789a";
private String i = "123452312316789a";
// private int[] j = new int[]{1, 2, 4, 5};
// private boolean[] k = new boolean[]{true, false, true, false, false, false, true};
// private char[] l = new char[]{'a', 'v', 'q', 'j', 'h', 'e', 'f'};