master
commit
41f69f0769
|
@ -0,0 +1,38 @@
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,48 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.example</groupId>
|
||||||
|
<artifactId>JfireSE</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>JfireSE</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jfirer</groupId>
|
||||||
|
<artifactId>baseutil</artifactId>
|
||||||
|
<version>1.1.7-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.30</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</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>
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.jfirer.se;
|
||||||
|
|
||||||
|
public class ByteArray
|
||||||
|
{
|
||||||
|
protected byte[] array;
|
||||||
|
protected int writePosi = 0;
|
||||||
|
protected int readIndex = 0;
|
||||||
|
protected boolean needCheck = true;
|
||||||
|
|
||||||
|
protected ByteArray(int size)
|
||||||
|
{
|
||||||
|
array = new byte[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ByteArray(byte[] array)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ByteArray allocate(int size)
|
||||||
|
{
|
||||||
|
return new InternalByteArray(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ByteArray allocate()
|
||||||
|
{
|
||||||
|
return new InternalByteArray(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ByteArray wrap(byte[] array)
|
||||||
|
{
|
||||||
|
return new InternalByteArray(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNeedCheck(boolean needCheck)
|
||||||
|
{
|
||||||
|
this.needCheck = needCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ensureCapacity(int len)
|
||||||
|
{
|
||||||
|
if (needCheck && len > array.length - writePosi)
|
||||||
|
{
|
||||||
|
int newLen = len + writePosi > (array.length << 1) ? len + writePosi + array.length : (array.length << 1);
|
||||||
|
byte[] tmp = new byte[newLen];
|
||||||
|
System.arraycopy(array, 0, tmp, 0, array.length);
|
||||||
|
array = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
writePosi = readIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(byte value)
|
||||||
|
{
|
||||||
|
ensureCapacity(1);
|
||||||
|
array[writePosi] = value;
|
||||||
|
writePosi += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByte(int off, byte b)
|
||||||
|
{
|
||||||
|
array[off] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(byte[] data)
|
||||||
|
{
|
||||||
|
ensureCapacity(data.length);
|
||||||
|
System.arraycopy(data, 0, array, writePosi, data.length);
|
||||||
|
writePosi += data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte get()
|
||||||
|
{
|
||||||
|
byte result = array[readIndex];
|
||||||
|
readIndex += 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toArray()
|
||||||
|
{
|
||||||
|
byte[] result = new byte[writePosi];
|
||||||
|
System.arraycopy(array, 0, result, 0, writePosi);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWritePosi()
|
||||||
|
{
|
||||||
|
return writePosi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWritePosi(int writePosi)
|
||||||
|
{
|
||||||
|
this.writePosi = writePosi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReadPosi(int readPosi)
|
||||||
|
{
|
||||||
|
this.readIndex = readPosi;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
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[] refTracking;
|
||||||
|
private int refTrackingIndex = 0;
|
||||||
|
|
||||||
|
public void writeBytes(InternalByteArray byteArray, Object instance, boolean knownClazz)
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (serializer == null)
|
||||||
|
{
|
||||||
|
serializer = jfireSE.getSerializer(clazz);
|
||||||
|
}
|
||||||
|
if (knownClazz)
|
||||||
|
{
|
||||||
|
if (jfireSE.isCycleSupport())
|
||||||
|
{
|
||||||
|
int tracking = addTracking(instance);
|
||||||
|
if (tracking == -1)
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 7);
|
||||||
|
serializer.writeBytes(byteArray, instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 9);
|
||||||
|
byteArray.writeVarInt(tracking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 8);
|
||||||
|
serializer.writeBytes(byteArray, instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (jfireSE.isCycleSupport())
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
classId = ClassInfoResolver.NO_CLASS_ID;
|
||||||
|
refTrackingIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int addTracking(Object instance)
|
||||||
|
{
|
||||||
|
if (refTracking == null)
|
||||||
|
{
|
||||||
|
refTracking = new Object[4];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < refTrackingIndex; i++)
|
||||||
|
{
|
||||||
|
if (refTracking[i] == instance)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (refTrackingIndex == refTracking.length)
|
||||||
|
{
|
||||||
|
Object[] newRefTracking = new Object[refTracking.length * 2];
|
||||||
|
System.arraycopy(refTracking, 0, newRefTracking, 0, refTracking.length);
|
||||||
|
refTracking = newRefTracking;
|
||||||
|
}
|
||||||
|
refTracking[refTrackingIndex++] = instance;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.jfirer.se;
|
||||||
|
|
||||||
|
import com.jfirer.se.serializer.SerializerResolver;
|
||||||
|
|
||||||
|
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 currentClassId = 1;
|
||||||
|
private int fixedClassId = 1;
|
||||||
|
private ClassInfo[] tracking = new ClassInfo[32];
|
||||||
|
private JfireSE jfireSE;
|
||||||
|
private SerializerResolver resolver;
|
||||||
|
|
||||||
|
public ClassInfoResolver(SerializerResolver resolver, JfireSE jfireSE)
|
||||||
|
{
|
||||||
|
this.resolver = resolver;
|
||||||
|
this.jfireSE = jfireSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getClassId(ClassInfo classInfo)
|
||||||
|
{
|
||||||
|
if (currentClassId > tracking.length)
|
||||||
|
{
|
||||||
|
ClassInfo[] newTracking = new ClassInfo[tracking.length << 1];
|
||||||
|
System.arraycopy(tracking, 0, newTracking, 0, tracking.length);
|
||||||
|
tracking = newTracking;
|
||||||
|
}
|
||||||
|
tracking[currentClassId] = classInfo;
|
||||||
|
classInfo.setClassId(currentClassId);
|
||||||
|
currentClassId += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
for (int i = currentClassId - 1; i > fixedClassId; i--)
|
||||||
|
{
|
||||||
|
tracking[i].reset();
|
||||||
|
}
|
||||||
|
currentClassId = fixedClassId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassInfo getClassInfo(Class clazz)
|
||||||
|
{
|
||||||
|
ClassInfo classInfo = store.get(clazz);
|
||||||
|
if (classInfo == null)
|
||||||
|
{
|
||||||
|
classInfo = new ClassInfo().setClassName(clazz.getName()).setJfireSE(jfireSE).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).setClazz(clazz);
|
||||||
|
store.put(clazz, classInfo);
|
||||||
|
}
|
||||||
|
for (int i = 1; i < fixedClassId; i++)
|
||||||
|
{
|
||||||
|
if (tracking[i].getClazz() == clazz)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fixedClassId > tracking.length)
|
||||||
|
{
|
||||||
|
ClassInfo[] newTracking = new ClassInfo[tracking.length << 1];
|
||||||
|
System.arraycopy(tracking, 0, newTracking, 0, tracking.length);
|
||||||
|
tracking = newTracking;
|
||||||
|
}
|
||||||
|
tracking[fixedClassId] = classInfo;
|
||||||
|
classInfo.setClassId(fixedClassId++);
|
||||||
|
currentClassId = fixedClassId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,539 @@
|
||||||
|
package com.jfirer.se;
|
||||||
|
|
||||||
|
public class InternalByteArray extends ByteArray
|
||||||
|
{
|
||||||
|
public InternalByteArray(int size)
|
||||||
|
{
|
||||||
|
super(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InternalByteArray(byte[] array)
|
||||||
|
{
|
||||||
|
super(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeVarInt(int i)
|
||||||
|
{
|
||||||
|
if (i >= -120 && i <= 127)
|
||||||
|
{
|
||||||
|
ensureCapacity(1);
|
||||||
|
array[writePosi] = (byte) i;
|
||||||
|
writePosi += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int head = -120;
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
i = ~i;
|
||||||
|
head = -124;
|
||||||
|
}
|
||||||
|
if (i <= 255)
|
||||||
|
{
|
||||||
|
ensureCapacity(2);
|
||||||
|
array[writePosi] = (byte) (head - 1);
|
||||||
|
array[writePosi + 1] = (byte) i;
|
||||||
|
writePosi += 2;
|
||||||
|
}
|
||||||
|
else if (i <= 65535)
|
||||||
|
{
|
||||||
|
ensureCapacity(3);
|
||||||
|
array[writePosi] = (byte) (head - 2);
|
||||||
|
array[writePosi + 1] = (byte) (i >>> 8);
|
||||||
|
array[writePosi + 2] = (byte) i;
|
||||||
|
writePosi += 3;
|
||||||
|
}
|
||||||
|
else if (i <= 16777215)
|
||||||
|
{
|
||||||
|
ensureCapacity(4);
|
||||||
|
array[writePosi] = (byte) (head - 3);
|
||||||
|
array[writePosi + 1] = (byte) (i >>> 16);
|
||||||
|
array[writePosi + 2] = (byte) (i >>> 8);
|
||||||
|
array[writePosi + 3] = (byte) i;
|
||||||
|
writePosi += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensureCapacity(5);
|
||||||
|
array[writePosi] = (byte) (head - 4);
|
||||||
|
array[writePosi + 1] = (byte) (i >>> 24);
|
||||||
|
array[writePosi + 2] = (byte) (i >>> 16);
|
||||||
|
array[writePosi + 3] = (byte) (i >>> 8);
|
||||||
|
array[writePosi + 4] = (byte) i;
|
||||||
|
writePosi += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readVarInt()
|
||||||
|
{
|
||||||
|
byte b = array[readIndex++];
|
||||||
|
if (b >= -120 && b <= 127)
|
||||||
|
{
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (b)
|
||||||
|
{
|
||||||
|
case -128:
|
||||||
|
return ~((array[readIndex++] & 255) << 24 | (array[readIndex++] & 255) << 16 | (array[readIndex++] & 255) << 8 | array[readIndex++] & 255);
|
||||||
|
case -127:
|
||||||
|
return ~((array[readIndex++] & 255) << 16 | (array[readIndex++] & 255) << 8 | array[readIndex++] & 255);
|
||||||
|
case -126:
|
||||||
|
return ~((array[readIndex++] & 255) << 8 | array[readIndex++] & 255);
|
||||||
|
case -125:
|
||||||
|
return ~(array[readIndex++] & 255);
|
||||||
|
case -124:
|
||||||
|
return (array[readIndex++] & 255) << 24 | (array[readIndex++] & 255) << 16 | (array[readIndex++] & 255) << 8 | array[readIndex++] & 255;
|
||||||
|
case -123:
|
||||||
|
return (array[readIndex++] & 255) << 16 | (array[readIndex++] & 255) << 8 | array[readIndex++] & 255;
|
||||||
|
case -122:
|
||||||
|
return (array[readIndex++] & 255) << 8 | array[readIndex++] & 255;
|
||||||
|
case -121:
|
||||||
|
return array[readIndex++] & 255;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("not here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeVarLong(long i)
|
||||||
|
{
|
||||||
|
if (i >= -112L && i <= 127L)
|
||||||
|
{
|
||||||
|
ensureCapacity(1);
|
||||||
|
array[writePosi] = (byte) ((int) i);
|
||||||
|
writePosi += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int head = -112;
|
||||||
|
if (i < 0L)
|
||||||
|
{
|
||||||
|
i = ~i;
|
||||||
|
head = -120;
|
||||||
|
}
|
||||||
|
if (i <= 255L)
|
||||||
|
{
|
||||||
|
ensureCapacity(2);
|
||||||
|
array[writePosi] = (byte) (head - 1);
|
||||||
|
array[writePosi + 1] = (byte) ((int) i);
|
||||||
|
writePosi += 2;
|
||||||
|
}
|
||||||
|
else if (i <= 65535L)
|
||||||
|
{
|
||||||
|
ensureCapacity(3);
|
||||||
|
array[writePosi] = (byte) (head - 2);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 2] = (byte) ((int) i);
|
||||||
|
writePosi += 3;
|
||||||
|
}
|
||||||
|
else if (i <= 16777215L)
|
||||||
|
{
|
||||||
|
ensureCapacity(4);
|
||||||
|
array[writePosi] = (byte) (head - 3);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 16));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 3] = (byte) ((int) i);
|
||||||
|
writePosi += 4;
|
||||||
|
}
|
||||||
|
else if (i <= -1L)
|
||||||
|
{
|
||||||
|
ensureCapacity(5);
|
||||||
|
array[writePosi] = (byte) (head - 4);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 24));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (i >>> 16));
|
||||||
|
array[writePosi + 3] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 4] = (byte) ((int) i);
|
||||||
|
writePosi += 5;
|
||||||
|
}
|
||||||
|
else if (i <= 1099511627775L)
|
||||||
|
{
|
||||||
|
ensureCapacity(6);
|
||||||
|
array[writePosi] = (byte) (head - 5);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 32));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (i >>> 24));
|
||||||
|
array[writePosi + 3] = (byte) ((int) (i >>> 16));
|
||||||
|
array[writePosi + 4] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 5] = (byte) ((int) i);
|
||||||
|
writePosi += 6;
|
||||||
|
}
|
||||||
|
else if (i <= 281474976710655L)
|
||||||
|
{
|
||||||
|
ensureCapacity(7);
|
||||||
|
array[writePosi] = (byte) (head - 6);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 40));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (i >>> 32));
|
||||||
|
array[writePosi + 3] = (byte) ((int) (i >>> 24));
|
||||||
|
array[writePosi + 4] = (byte) ((int) (i >>> 16));
|
||||||
|
array[writePosi + 5] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 6] = (byte) ((int) i);
|
||||||
|
writePosi += 7;
|
||||||
|
}
|
||||||
|
else if (i <= 72057594037927935L)
|
||||||
|
{
|
||||||
|
ensureCapacity(8);
|
||||||
|
array[writePosi] = (byte) (head - 7);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 48));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (i >>> 40));
|
||||||
|
array[writePosi + 3] = (byte) ((int) (i >>> 32));
|
||||||
|
array[writePosi + 4] = (byte) ((int) (i >>> 24));
|
||||||
|
array[writePosi + 5] = (byte) ((int) (i >>> 16));
|
||||||
|
array[writePosi + 6] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 7] = (byte) ((int) i);
|
||||||
|
writePosi += 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensureCapacity(9);
|
||||||
|
array[writePosi] = (byte) (head - 8);
|
||||||
|
array[writePosi + 1] = (byte) ((int) (i >>> 56));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (i >>> 48));
|
||||||
|
array[writePosi + 3] = (byte) ((int) (i >>> 40));
|
||||||
|
array[writePosi + 4] = (byte) ((int) (i >>> 32));
|
||||||
|
array[writePosi + 5] = (byte) ((int) (i >>> 24));
|
||||||
|
array[writePosi + 6] = (byte) ((int) (i >>> 16));
|
||||||
|
array[writePosi + 7] = (byte) ((int) (i >>> 8));
|
||||||
|
array[writePosi + 8] = (byte) ((int) i);
|
||||||
|
writePosi += 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readVarLong()
|
||||||
|
{
|
||||||
|
byte b = array[readIndex++];
|
||||||
|
if (b >= -112 && b <= 127)
|
||||||
|
{
|
||||||
|
return (long) b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (b)
|
||||||
|
{
|
||||||
|
case -128:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 56 | ((long) array[readIndex++] & 255L) << 48 | ((long) array[readIndex++] & 255L) << 40 | ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -127:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 48 | ((long) array[readIndex++] & 255L) << 40 | ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -126:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 40 | ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -125:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -124:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -123:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -122:
|
||||||
|
return ~(((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L);
|
||||||
|
case -121:
|
||||||
|
return ~((long) array[readIndex++] & 255L);
|
||||||
|
case -120:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 56 | ((long) array[readIndex++] & 255L) << 48 | ((long) array[readIndex++] & 255L) << 40 | ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -119:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 48 | ((long) array[readIndex++] & 255L) << 40 | ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -118:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 40 | ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -117:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 32 | ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -116:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 24 | ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -115:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 16 | ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -114:
|
||||||
|
return ((long) array[readIndex++] & 255L) << 8 | (long) array[readIndex++] & 255L;
|
||||||
|
case -113:
|
||||||
|
return (long) array[readIndex++] & 255L;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("not here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeVarCharWithoutCheck(char c)
|
||||||
|
{
|
||||||
|
if (c <= 251)
|
||||||
|
{
|
||||||
|
array[writePosi] = (byte) c;
|
||||||
|
writePosi += 1;
|
||||||
|
}
|
||||||
|
else if (c <= 255)
|
||||||
|
{
|
||||||
|
array[writePosi] = -4;
|
||||||
|
array[writePosi + 1] = (byte) c;
|
||||||
|
writePosi += 2;
|
||||||
|
}
|
||||||
|
else if (c <= '\uffff')
|
||||||
|
{
|
||||||
|
array[writePosi] = -3;
|
||||||
|
array[writePosi + 1] = (byte) (c >>> 8);
|
||||||
|
array[writePosi + 2] = (byte) c;
|
||||||
|
writePosi += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeVarChar(char c)
|
||||||
|
{
|
||||||
|
if (c <= 251)
|
||||||
|
{
|
||||||
|
ensureCapacity(1);
|
||||||
|
array[writePosi] = (byte) c;
|
||||||
|
++writePosi;
|
||||||
|
}
|
||||||
|
else if (c <= 255)
|
||||||
|
{
|
||||||
|
ensureCapacity(2);
|
||||||
|
array[writePosi] = -4;
|
||||||
|
array[writePosi + 1] = (byte) c;
|
||||||
|
writePosi += 2;
|
||||||
|
}
|
||||||
|
else if (c <= '\uffff')
|
||||||
|
{
|
||||||
|
ensureCapacity(3);
|
||||||
|
array[writePosi] = -3;
|
||||||
|
array[writePosi + 1] = (byte) (c >>> 8);
|
||||||
|
array[writePosi + 2] = (byte) c;
|
||||||
|
writePosi += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readVarChar()
|
||||||
|
{
|
||||||
|
int length = array[readIndex++] & 255;
|
||||||
|
if (length <= 251)
|
||||||
|
{
|
||||||
|
return (char) length;
|
||||||
|
}
|
||||||
|
else if (length == 252)
|
||||||
|
{
|
||||||
|
length = array[readIndex++] & 255;
|
||||||
|
return (char) length;
|
||||||
|
}
|
||||||
|
else if (length == 253)
|
||||||
|
{
|
||||||
|
length = (array[readIndex++] & 255) << 8;
|
||||||
|
length |= array[readIndex++] & 255;
|
||||||
|
return (char) length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("not here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writePositive(int positive)
|
||||||
|
{
|
||||||
|
if (positive < 0)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (positive <= 251)
|
||||||
|
{
|
||||||
|
ensureCapacity(1);
|
||||||
|
array[writePosi] = (byte) positive;
|
||||||
|
++writePosi;
|
||||||
|
}
|
||||||
|
else if (positive <= 255)
|
||||||
|
{
|
||||||
|
ensureCapacity(2);
|
||||||
|
array[writePosi] = -4;
|
||||||
|
array[writePosi + 1] = (byte) positive;
|
||||||
|
writePosi += 2;
|
||||||
|
}
|
||||||
|
else if (positive <= 65535)
|
||||||
|
{
|
||||||
|
ensureCapacity(3);
|
||||||
|
array[writePosi] = -3;
|
||||||
|
array[writePosi + 1] = (byte) (positive >>> 8);
|
||||||
|
array[writePosi + 2] = (byte) positive;
|
||||||
|
writePosi += 3;
|
||||||
|
}
|
||||||
|
else if (positive <= 16777215)
|
||||||
|
{
|
||||||
|
ensureCapacity(4);
|
||||||
|
array[writePosi] = -2;
|
||||||
|
array[writePosi + 1] = (byte) (positive >>> 16);
|
||||||
|
array[writePosi + 2] = (byte) (positive >>> 8);
|
||||||
|
array[writePosi + 3] = (byte) positive;
|
||||||
|
writePosi += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensureCapacity(5);
|
||||||
|
array[writePosi] = -1;
|
||||||
|
array[writePosi + 1] = (byte) (positive >>> 24);
|
||||||
|
array[writePosi + 2] = (byte) (positive >>> 16);
|
||||||
|
array[writePosi + 3] = (byte) (positive >>> 8);
|
||||||
|
array[writePosi + 4] = (byte) positive;
|
||||||
|
writePosi += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readPositive()
|
||||||
|
{
|
||||||
|
int length = array[readIndex++] & 255;
|
||||||
|
if (length <= 251)
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else if (length == 252)
|
||||||
|
{
|
||||||
|
length = array[readIndex++] & 255;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else if (length == 253)
|
||||||
|
{
|
||||||
|
length = (array[readIndex++] & 255) << 8;
|
||||||
|
length |= array[readIndex++] & 255;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else if (length == 254)
|
||||||
|
{
|
||||||
|
length = (array[readIndex++] & 255) << 16;
|
||||||
|
length |= (array[readIndex++] & 255) << 8;
|
||||||
|
length |= array[readIndex++] & 255;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else if (length == 255)
|
||||||
|
{
|
||||||
|
length = (array[readIndex++] & 255) << 24;
|
||||||
|
length |= (array[readIndex++] & 255) << 16;
|
||||||
|
length |= (array[readIndex++] & 255) << 8;
|
||||||
|
length |= array[readIndex++] & 255;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new RuntimeException("wrong data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInt(int i)
|
||||||
|
{
|
||||||
|
ensureCapacity(4);
|
||||||
|
array[writePosi] = (byte) (i >> 24);
|
||||||
|
array[writePosi + 1] = (byte) (i >> 16);
|
||||||
|
array[writePosi + 2] = (byte) (i >> 8);
|
||||||
|
array[writePosi + 3] = (byte) i;
|
||||||
|
writePosi += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeShort(short s)
|
||||||
|
{
|
||||||
|
ensureCapacity(2);
|
||||||
|
array[writePosi] = (byte) (s >> 8);
|
||||||
|
array[writePosi + 1] = (byte) s;
|
||||||
|
writePosi += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeLong(long l)
|
||||||
|
{
|
||||||
|
ensureCapacity(8);
|
||||||
|
array[writePosi] = (byte) ((int) (l >> 56));
|
||||||
|
array[writePosi + 1] = (byte) ((int) (l >> 48));
|
||||||
|
array[writePosi + 2] = (byte) ((int) (l >> 40));
|
||||||
|
array[writePosi + 3] = (byte) ((int) (l >> 32));
|
||||||
|
array[writePosi + 4] = (byte) ((int) (l >> 24));
|
||||||
|
array[writePosi + 5] = (byte) ((int) (l >> 16));
|
||||||
|
array[writePosi + 6] = (byte) ((int) (l >> 8));
|
||||||
|
array[writePosi + 7] = (byte) ((int) l);
|
||||||
|
writePosi += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt()
|
||||||
|
{
|
||||||
|
int i = (array[readIndex] & 255) << 24;
|
||||||
|
i |= (array[readIndex + 1] & 255) << 16;
|
||||||
|
i |= (array[readIndex + 2] & 255) << 8;
|
||||||
|
i |= array[readIndex + 3] & 255;
|
||||||
|
this.readIndex += 4;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short readShort()
|
||||||
|
{
|
||||||
|
short s = (short) ((array[readIndex] & 255) << 8);
|
||||||
|
s = (short) (s | array[readIndex + 1] & 255);
|
||||||
|
this.readIndex += 2;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readLong()
|
||||||
|
{
|
||||||
|
long l = (long) array[readIndex] << 56 | ((long) array[readIndex + 1] & 255L) << 48 | ((long) array[readIndex + 2] & 255L) << 40 | ((long) array[readIndex + 3] & 255L) << 32 | ((long) array[readIndex + 4] & 255L) << 24 | ((long) array[readIndex + 5] & 255L) << 16 | ((long) array[readIndex + 6] & 255L) << 8 | (long) array[readIndex + 7] & 255L;
|
||||||
|
this.readIndex += 8;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeFloat(float f)
|
||||||
|
{
|
||||||
|
writeInt(Float.floatToRawIntBits(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeDouble(double d)
|
||||||
|
{
|
||||||
|
writeLong(Double.doubleToRawLongBits(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
public float readFloat()
|
||||||
|
{
|
||||||
|
int i = readInt();
|
||||||
|
return Float.intBitsToFloat(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double readDouble()
|
||||||
|
{
|
||||||
|
long l = readLong();
|
||||||
|
return Double.longBitsToDouble(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipWrite(int len)
|
||||||
|
{
|
||||||
|
ensureCapacity(len);
|
||||||
|
writePosi += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeString(String value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writeVarInt(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int length = value.length();
|
||||||
|
writeVarInt(length);
|
||||||
|
ensureCapacity(3 * length);
|
||||||
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
writeVarCharWithoutCheck(value.charAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readString()
|
||||||
|
{
|
||||||
|
int length = readVarInt();
|
||||||
|
if (length == -1)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char[] src = new char[length];
|
||||||
|
for (int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
src[i] = this.readVarChar();
|
||||||
|
}
|
||||||
|
return new String(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remainRead()
|
||||||
|
{
|
||||||
|
return readIndex < writePosi;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.jfirer.se;
|
||||||
|
|
||||||
|
import com.jfirer.se.serializer.Serializer;
|
||||||
|
import com.jfirer.se.serializer.SerializerResolver;
|
||||||
|
|
||||||
|
public class JfireSE
|
||||||
|
{
|
||||||
|
public static final byte NULL = 0;
|
||||||
|
private boolean CYCLE_SUPPORT = true;
|
||||||
|
private SerializerResolver serializerResolver;
|
||||||
|
private ClassInfoResolver classInfoResolver;
|
||||||
|
private int depth = 1;
|
||||||
|
|
||||||
|
public boolean isCycleSupport()
|
||||||
|
{
|
||||||
|
return CYCLE_SUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Serializer getSerializer(Class clazz)
|
||||||
|
{
|
||||||
|
return serializerResolver.getSerializer(clazz, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassInfo getClassInfo(Class clazz)
|
||||||
|
{
|
||||||
|
return classInfoResolver.getClassInfo(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getClassId(ClassInfo classInfo)
|
||||||
|
{
|
||||||
|
classInfoResolver.getClassId(classInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrDepth()
|
||||||
|
{
|
||||||
|
if (depth++ > 256)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("序列化深度超过256,可能存在循环引用,请开启循环引用设置");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reduceDepth()
|
||||||
|
{
|
||||||
|
depth--;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.jfirer.se.serializer;
|
||||||
|
|
||||||
|
import com.jfirer.se.InternalByteArray;
|
||||||
|
|
||||||
|
public interface Serializer
|
||||||
|
{
|
||||||
|
void writeBytes(InternalByteArray byteArray, Object instance);
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.jfirer.se.serializer;
|
||||||
|
|
||||||
|
import com.jfirer.se.JfireSE;
|
||||||
|
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SerializerResolver
|
||||||
|
{
|
||||||
|
private Map<Class, Serializer> store = new IdentityHashMap<>();
|
||||||
|
|
||||||
|
public Serializer getSerializer(Class clazz, JfireSE jfireSE)
|
||||||
|
{
|
||||||
|
Serializer serializer = store.get(clazz);
|
||||||
|
if (serializer != null)
|
||||||
|
{
|
||||||
|
return serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void registerSerializer(Class clazz, Serializer serializer)
|
||||||
|
{
|
||||||
|
store.put(clazz, serializer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
package com.jfirer.se.serializer.impl;
|
||||||
|
|
||||||
|
import com.jfirer.baseutil.reflect.ReflectUtil;
|
||||||
|
import com.jfirer.baseutil.reflect.ValueAccessor;
|
||||||
|
import com.jfirer.se.ClassInfo;
|
||||||
|
import com.jfirer.se.InternalByteArray;
|
||||||
|
import com.jfirer.se.JfireSE;
|
||||||
|
import com.jfirer.se.serializer.Serializer;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class ObjectSerializer implements Serializer
|
||||||
|
{
|
||||||
|
private FieldInfo[] primitiveFieldInfos;
|
||||||
|
private FieldInfo[] boxFieldInfos;
|
||||||
|
private FinalFieldInfo[] finalFieldInfos;
|
||||||
|
private JfireSE jfireSE;
|
||||||
|
private Class clazz;
|
||||||
|
|
||||||
|
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.getComponentType();
|
||||||
|
}
|
||||||
|
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() != 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeBytes(InternalByteArray byteArray, Object instance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
class FieldInfo
|
||||||
|
{
|
||||||
|
int classId;
|
||||||
|
ValueAccessor accessor;
|
||||||
|
|
||||||
|
FieldInfo(Field field)
|
||||||
|
{
|
||||||
|
classId = ReflectUtil.getClassId(field.getType());
|
||||||
|
accessor = new ValueAccessor(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(InternalByteArray 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.writePositive(accessor.getBoolean(instance) ? 1 : 0);
|
||||||
|
case ReflectUtil.PRIMITIVE_CHAR -> byteArray.writeVarChar(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((byte) 01);
|
||||||
|
byteArray.writeVarInt(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_LONG ->
|
||||||
|
{
|
||||||
|
Long value = accessor.getLongObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writeVarLong(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_FLOAT ->
|
||||||
|
{
|
||||||
|
Float value = accessor.getFloatObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writeFloat(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_DOUBLE ->
|
||||||
|
{
|
||||||
|
Double value = accessor.getDoubleObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writeDouble(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_BOOL ->
|
||||||
|
{
|
||||||
|
Boolean value = accessor.getBooleanObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writePositive(value ? 1 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_CHAR ->
|
||||||
|
{
|
||||||
|
Character value = accessor.getCharObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writeVarChar(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_SHORT ->
|
||||||
|
{
|
||||||
|
Short value = accessor.getShortObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writeShort(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_BYTE ->
|
||||||
|
{
|
||||||
|
Byte value = accessor.getByteObject(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.put(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ReflectUtil.CLASS_STRING ->
|
||||||
|
{
|
||||||
|
String value = (String) accessor.get(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 01);
|
||||||
|
byteArray.writeString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FinalFieldInfo
|
||||||
|
{
|
||||||
|
ValueAccessor accessor;
|
||||||
|
ClassInfo classInfo;
|
||||||
|
|
||||||
|
FinalFieldInfo(Field field)
|
||||||
|
{
|
||||||
|
accessor = new ValueAccessor(field);
|
||||||
|
classInfo = jfireSE.getClassInfo(field.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(InternalByteArray byteArray, Object instance)
|
||||||
|
{
|
||||||
|
Object value = accessor.get(instance);
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
byteArray.put(JfireSE.NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byteArray.put((byte) 07);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VariableFieldInfo
|
||||||
|
{
|
||||||
|
ValueAccessor accessor;
|
||||||
|
ClassInfo classInfo;
|
||||||
|
|
||||||
|
VariableFieldInfo(Field field)
|
||||||
|
{
|
||||||
|
accessor = new ValueAccessor(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.example;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the test case
|
||||||
|
*
|
||||||
|
* @param testName name of the test case
|
||||||
|
*/
|
||||||
|
public AppTest( String testName )
|
||||||
|
{
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the suite of tests being tested
|
||||||
|
*/
|
||||||
|
public static Test suite()
|
||||||
|
{
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rigourous Test :-)
|
||||||
|
*/
|
||||||
|
public void testApp()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue