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