mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-09-02 08:21:24 +00:00
init project
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol;
|
||||
|
||||
/**
|
||||
* 所有协议类都必须实现这个接口
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IPacket {
|
||||
|
||||
/**
|
||||
* 这个类的协议号
|
||||
*
|
||||
* @return 协议号Id
|
||||
*/
|
||||
short protocolId();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,574 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.exception.RunException;
|
||||
import com.zfoo.protocol.exception.UnknownException;
|
||||
import com.zfoo.protocol.generate.GenerateOperation;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolDocument;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolFile;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolModule;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.*;
|
||||
import com.zfoo.protocol.serializer.*;
|
||||
import com.zfoo.protocol.serializer.cs.GenerateCsUtils;
|
||||
import com.zfoo.protocol.serializer.js.GenerateJsUtils;
|
||||
import com.zfoo.protocol.serializer.lua.GenerateLuaUtils;
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import com.zfoo.protocol.xml.XmlProtocols;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.NotFoundException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ProtocolManager {
|
||||
|
||||
|
||||
/**
|
||||
* 包体的头部的长度,一个int字节长度
|
||||
*/
|
||||
public static final int PROTOCOL_HEAD_LENGTH = 4;
|
||||
public static final String PROTOCOL_ID = "PROTOCOL_ID";
|
||||
public static final short MAX_PROTOCOL_NUM = Short.MAX_VALUE;
|
||||
public static final byte MAX_MODULE_NUM = Byte.MAX_VALUE;
|
||||
private static final Comparator<Field> PACKET_FIELD_COMPARATOR = (a, b) -> a.getName().compareTo(b.getName());
|
||||
|
||||
private static final IProtocolRegistration[] protocols = new IProtocolRegistration[MAX_PROTOCOL_NUM];
|
||||
private static final ProtocolModule[] modules = new ProtocolModule[MAX_MODULE_NUM];
|
||||
|
||||
// 临时变量,启动完成就会销毁,协议名称保留字符,即协议的名称不能用以下名称命名
|
||||
private static Set<String> tempProtocolReserved = Set.of("Buffer", "ByteBuf", "ByteBuffer", "LittleEndianByteBuffer", "NormalByteBuffer"
|
||||
, "IPacket", "IProtocolRegistration", "ProtocolManager", "IFieldRegistration"
|
||||
, "ByteBufUtils", "ArrayUtils", "CollectionUtils"
|
||||
, "Boolean", "Byte", "Short", "Integer", "Long", "Float", "Double", "String", "Character", "Object");
|
||||
|
||||
// 临时变量,启动完成就会销毁,是一个基本类型序列化器
|
||||
private static Map<Class<?>, ISerializer> tempBaseSerializerMap = new HashMap<>();
|
||||
|
||||
// 临时变量,启动完成就会销毁,协议下包含的子协议,只包含一层子协议
|
||||
private static Map<Short, Set<Short>> tempSubProtocolIdMap = new HashMap<>();
|
||||
|
||||
|
||||
static {
|
||||
// 初始化默认协议模块
|
||||
modules[0] = ProtocolModule.DEFAULT_PROTOCOL_MODULE;
|
||||
|
||||
// 初始化基础类型序列化器
|
||||
tempBaseSerializerMap.put(boolean.class, BooleanSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Boolean.class, BooleanSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(byte.class, ByteSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Byte.class, ByteSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(short.class, ShortSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Short.class, ShortSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(int.class, IntSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Integer.class, IntSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(long.class, LongSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Long.class, LongSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(float.class, FloatSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Float.class, FloatSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(double.class, DoubleSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Double.class, DoubleSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(char.class, CharSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(Character.class, CharSerializer.getInstance());
|
||||
tempBaseSerializerMap.put(String.class, StringSerializer.getInstance());
|
||||
}
|
||||
|
||||
public static void write(ByteBuf buffer, IPacket packet) {
|
||||
var protocolId = packet.protocolId();
|
||||
// 写入协议号
|
||||
ByteBufUtils.writeShort(buffer, protocolId);
|
||||
// 写入包体
|
||||
protocols[protocolId].write(buffer, packet);
|
||||
}
|
||||
|
||||
public static IPacket read(ByteBuf buffer) {
|
||||
return (IPacket) protocols[ByteBufUtils.readShort(buffer)].read(buffer);
|
||||
}
|
||||
|
||||
public static IProtocolRegistration getProtocol(short id) {
|
||||
var protocol = protocols[id];
|
||||
if (protocol == null) {
|
||||
throw new RunException("[protocolId:{}]协议不存在", id);
|
||||
}
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public static ProtocolModule moduleByProtocolId(short id) {
|
||||
return modules[protocols[id].module()];
|
||||
}
|
||||
|
||||
public static ProtocolModule moduleByModuleId(byte moduleId) {
|
||||
var module = modules[moduleId];
|
||||
AssertionUtils.notNull(module, "[moduleId:{}]不存在", moduleId);
|
||||
return module;
|
||||
}
|
||||
|
||||
public static ProtocolModule moduleByModuleName(String name) {
|
||||
var moduleOptional = Arrays.stream(modules)
|
||||
.filter(it -> Objects.nonNull(it))
|
||||
.filter(it -> it.getName().equals(name))
|
||||
.findFirst();
|
||||
if (moduleOptional.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return moduleOptional.get();
|
||||
}
|
||||
|
||||
|
||||
public static synchronized void initProtocol(Set<Class<?>> protocolClassSet) {
|
||||
initProtocol(protocolClassSet, GenerateOperation.NO_OPERATION);
|
||||
}
|
||||
|
||||
public static synchronized void initProtocol(Set<Class<?>> protocolClassSet, GenerateOperation generateOperation) {
|
||||
AssertionUtils.notNull(tempSubProtocolIdMap, "[{}]已经初始完成,只能parseProtocol一次,请不要重复初始化", ProtocolManager.class.getSimpleName());
|
||||
try {
|
||||
for (var protocolClass : protocolClassSet) {
|
||||
try {
|
||||
var registration = parseProtocolRegistration(protocolClass, ProtocolModule.DEFAULT_PROTOCOL_MODULE);
|
||||
// 注册协议
|
||||
protocols[registration.protocolId()] = registration;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(StringUtils.format("解析协议[class:{}]异常", protocolClass), e);
|
||||
}
|
||||
}
|
||||
|
||||
enhanceProtocolBefore(generateOperation);
|
||||
|
||||
// 通过指定类注册的协议,全部使用字节码增强
|
||||
enhanceProtocolRegistration(Arrays.stream(protocols).filter(it -> Objects.nonNull(it)).collect(Collectors.toList()));
|
||||
|
||||
enhanceProtocolAfter();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static synchronized void initProtocol(XmlProtocols xmlProtocols, GenerateOperation generateOperation) {
|
||||
AssertionUtils.notNull(tempSubProtocolIdMap, "[{}]已经初始完成,只能parseProtocol一次,请不要重复初始化", ProtocolManager.class.getSimpleName());
|
||||
try {
|
||||
var enhanceList = new ArrayList<IProtocolRegistration>();
|
||||
|
||||
for (var moduleDefinition : xmlProtocols.getModules()) {
|
||||
var module = new ProtocolModule(moduleDefinition.getId(), moduleDefinition.getName(), moduleDefinition.getVersion());
|
||||
|
||||
AssertionUtils.isTrue(module.getId() > 0, "[module:{}] [id:{}] 模块必须大于等于1", module.getName(), module.getId());
|
||||
AssertionUtils.isNull(modules[module.getId()], "duplicate [module:{}] [id:{}] Exception!", module.getName(), module.getId());
|
||||
AssertionUtils.notNull(moduleDefinition.getProtocols(), "[module:{}] does not have any protocols", module.getName());
|
||||
|
||||
modules[module.getId()] = module;
|
||||
|
||||
for (var protocolDefinition : moduleDefinition.getProtocols()) {
|
||||
var id = protocolDefinition.getId();
|
||||
var location = protocolDefinition.getLocation();
|
||||
var clazz = Class.forName(location);
|
||||
|
||||
AssertionUtils.isTrue(id >= moduleDefinition.getMinId(), "模块[{}]中的协议[{}]的协议号必须大于或者等于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMinId());
|
||||
AssertionUtils.isTrue(id < moduleDefinition.getMaxId(), "模块[{}]中的协议[{}]的协议号必须小于[{}]", moduleDefinition.getName(), clazz.getSimpleName(), moduleDefinition.getMaxId());
|
||||
AssertionUtils.isNull(protocols[id], "duplicate definition [id:{}] Exception!", id);
|
||||
|
||||
var packet = (IPacket) ReflectionUtils.newInstance(clazz);
|
||||
|
||||
// 协议号是否和id是否相等
|
||||
AssertionUtils.isTrue(packet.protocolId() == id, "[class:{}]协议序列号[{}]和协议文件里的协议序列号不相等", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
|
||||
try {
|
||||
var registration = parseProtocolRegistration(clazz, module);
|
||||
if (protocolDefinition.isEnhance()) {
|
||||
enhanceList.add(registration);
|
||||
}
|
||||
// 注册协议
|
||||
protocols[id] = registration;
|
||||
} catch (Exception e) {
|
||||
throw new UnknownException(e, "解析协议[id:{}][class:{}]异常", id, clazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enhanceProtocolBefore(generateOperation);
|
||||
|
||||
enhanceProtocolRegistration(enhanceList);
|
||||
|
||||
enhanceProtocolAfter();
|
||||
} catch (Exception e) {
|
||||
throw new UnknownException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void enhanceProtocolRegistration(List<IProtocolRegistration> enhanceList) throws NoSuchMethodException, IllegalAccessException, InstantiationException, CannotCompileException, NotFoundException, InvocationTargetException, NoSuchFieldException {
|
||||
// 字节码增强
|
||||
for (var registration : enhanceList) {
|
||||
protocols[registration.protocolId()] = EnhanceUtils.createProtocolRegistration((ProtocolRegistration) registration);
|
||||
}
|
||||
|
||||
// 字节码增强过后,初始化各个子协议成员变量
|
||||
for (var registration : enhanceList) {
|
||||
var enhanceProtocolRegistration = protocols[registration.protocolId()];
|
||||
var subProtocolIds = getAllSubProtocolIds(registration.protocolId());
|
||||
for (var subProtocolId : subProtocolIds) {
|
||||
var protocolRegistrationField = enhanceProtocolRegistration.getClass().getDeclaredField(EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(subProtocolId));
|
||||
ReflectionUtils.makeAccessible(protocolRegistrationField);
|
||||
ReflectionUtils.setField(protocolRegistrationField, enhanceProtocolRegistration, protocols[subProtocolId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void enhanceProtocolBefore(GenerateOperation generateOperation) throws IOException {
|
||||
// 检查协议格式
|
||||
checkAllProtocolClass();
|
||||
|
||||
// 检查模块格式
|
||||
checkAllModules();
|
||||
|
||||
// 生成协议
|
||||
GenerateProtocolFile.generate(protocols, generateOperation);
|
||||
}
|
||||
|
||||
private static void enhanceProtocolAfter() {
|
||||
tempSubProtocolIdMap.clear();
|
||||
tempSubProtocolIdMap = null;
|
||||
|
||||
tempProtocolReserved = null;
|
||||
|
||||
tempBaseSerializerMap.clear();
|
||||
tempBaseSerializerMap = null;
|
||||
|
||||
GenerateProtocolDocument.clear();
|
||||
GenerateProtocolPath.clear();
|
||||
GenerateCsUtils.clear();
|
||||
GenerateJsUtils.clear();
|
||||
GenerateLuaUtils.clear();
|
||||
GenerateUtils.clear();
|
||||
|
||||
EnhanceUtils.clear();
|
||||
}
|
||||
|
||||
|
||||
private static short checkProtocol(Class<?> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
// 是否为一个简单的javabean
|
||||
AssertionUtils.isTrue(clazz.getSuperclass().equals(Object.class), "[class:{}]不是简单的javabean,不能继承别的类", clazz.getCanonicalName());
|
||||
// 是否实现了IPacket接口
|
||||
AssertionUtils.isTrue(IPacket.class.isAssignableFrom(clazz), "[class:{}]没有实现接口[IPacket:{}]", clazz.getCanonicalName(), IPacket.class.getCanonicalName());
|
||||
// 不能是泛型类
|
||||
AssertionUtils.isTrue(CollectionUtils.isEmpty(clazz.getTypeParameters()), "[class:{}]不能是泛型类", clazz.getCanonicalName());
|
||||
|
||||
Field protocolIdField;
|
||||
try {
|
||||
protocolIdField = clazz.getDeclaredField(PROTOCOL_ID);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new UnknownException(e, "[class:{}]没有[{}]协议序列号", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
}
|
||||
|
||||
// 是否被public修饰
|
||||
AssertionUtils.isTrue(Modifier.isPublic(protocolIdField.getModifiers()), "[class:{}]协议序列号[{}]没有被public修饰", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
// 是否被static修饰
|
||||
AssertionUtils.isTrue(Modifier.isStatic(protocolIdField.getModifiers()), "[class:{}]协议序列号[{}]没有被static修饰", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
// 是否被final修饰
|
||||
AssertionUtils.isTrue(Modifier.isFinal(protocolIdField.getModifiers()), "[class:{}]协议序列号[{}]没有被final修饰", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
// 是否被transient修饰
|
||||
AssertionUtils.isTrue(Modifier.isTransient(protocolIdField.getModifiers()), "[class:{}]协议序列号[{}]没有被transient修饰", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
// 命名只能包含字母,数字,下划线
|
||||
AssertionUtils.isTrue(clazz.getSimpleName().matches("[a-zA-Z0-9_]*"), "[class:{}]的命名只能包含字母,数字,下划线", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
|
||||
// 必须要有一个空的构造器
|
||||
Constructor<?> constructor;
|
||||
try {
|
||||
constructor = clazz.getDeclaredConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new UnknownException(e, "[class:{}]协议序列号[{}]必须有一个空的构造器", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(protocolIdField);
|
||||
IPacket packet = (IPacket) constructor.newInstance();
|
||||
|
||||
// 验证protocol()方法的返回是否和PROTOCOL_ID相等
|
||||
AssertionUtils.isTrue(Short.valueOf(packet.protocolId()).equals(protocolIdField.get(null)), "[class:{}]的protocolId返回的值和协议号的静态变量[{}]不相等", clazz.getCanonicalName(), PROTOCOL_ID);
|
||||
return packet.protocolId();
|
||||
}
|
||||
|
||||
|
||||
public static short getProtocolIdByClass(Class<?> clazz) {
|
||||
var protocolIdField = ReflectionUtils.getFieldByNameInPOJOClass(clazz, PROTOCOL_ID);
|
||||
ReflectionUtils.makeAccessible(protocolIdField);
|
||||
return (short) ReflectionUtils.getField(protocolIdField, null);
|
||||
}
|
||||
|
||||
private static void checkAllModules() {
|
||||
// 模块id不能重复
|
||||
var moduleIdSet = new HashSet<Byte>();
|
||||
Arrays.stream(modules)
|
||||
.filter(it -> Objects.nonNull(it))
|
||||
.peek(it -> AssertionUtils.isTrue(!moduleIdSet.contains(it.getId()), "模块[{}]存在重复的id,模块的id不能重复", it))
|
||||
.forEach(it -> moduleIdSet.add(it.getId()));
|
||||
|
||||
// 模块名称不能重复
|
||||
var moduleNameSet = new HashSet<String>();
|
||||
Arrays.stream(modules)
|
||||
.filter(it -> Objects.nonNull(it))
|
||||
.peek(it -> AssertionUtils.isTrue(!moduleNameSet.contains(it.getName()), "模块[{}]存在重复的name,模块名称不能重复", it))
|
||||
.forEach(it -> moduleNameSet.add(it.getName()));
|
||||
}
|
||||
|
||||
private static void checkAllProtocolClass() {
|
||||
// 检查协议格式
|
||||
|
||||
// 协议的名称不能重复
|
||||
var allProtocolNameMap = new HashMap<String, Class<?>>();
|
||||
for (var protocolRegistration : protocols) {
|
||||
if (protocolRegistration == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var protocolClass = protocolRegistration.protocolConstructor().getDeclaringClass();
|
||||
var protocolName = protocolClass.getSimpleName();
|
||||
if (allProtocolNameMap.containsKey(protocolName)) {
|
||||
throw new RunException("[class:{}]和[class:{}]协议名称重复,协议不能含有重复的名称", protocolClass.getCanonicalName(), allProtocolNameMap.get(protocolName).getCanonicalName());
|
||||
}
|
||||
|
||||
if (tempProtocolReserved.stream().anyMatch(it -> it.equalsIgnoreCase(protocolName))) {
|
||||
throw new RunException("协议的名称[class:{}]不能是保留名称[{}]", protocolClass.getCanonicalName(), protocolName);
|
||||
}
|
||||
|
||||
allProtocolNameMap.put(protocolName, protocolClass);
|
||||
}
|
||||
|
||||
|
||||
// 检查循环协议
|
||||
for (var protocolEntry : tempSubProtocolIdMap.entrySet()) {
|
||||
var protocolId = protocolEntry.getKey();
|
||||
var subProtocolSet = protocolEntry.getValue();
|
||||
if (subProtocolSet.contains(protocolId)) {
|
||||
var protocolClass = protocols[protocolId].protocolConstructor().getDeclaringClass();
|
||||
throw new RunException("[class:{}]在第一层包含循环引用协议[class:{}]", protocolClass.getSimpleName(), protocolClass.getSimpleName());
|
||||
}
|
||||
|
||||
getAllSubProtocolIds(protocolId);
|
||||
}
|
||||
}
|
||||
|
||||
private static ProtocolRegistration parseProtocolRegistration(Class<?> clazz, ProtocolModule module) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException {
|
||||
var protocolId = checkProtocol(clazz);
|
||||
|
||||
if (protocols[protocolId] != null) {
|
||||
throw new RunException("[{}][{}]协议号[protocolId:{}]重复", protocols[protocolId].protocolConstructor().getDeclaringClass().getCanonicalName(), clazz.getCanonicalName(), protocolId);
|
||||
}
|
||||
|
||||
var fields = new ArrayList<Field>();
|
||||
for (var field : clazz.getDeclaredFields()) {
|
||||
var modifiers = field.getModifiers();
|
||||
if (Modifier.isTransient(modifiers) || Modifier.isStatic(modifiers)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Modifier.isFinal(modifiers)) {
|
||||
throw new RunException("[{}]协议号[protocolId:{}]中的[filed:{}]属性的访问修饰符不能为final"
|
||||
, clazz.getCanonicalName(), protocolId, field.getName());
|
||||
}
|
||||
|
||||
if (!Modifier.isPublic(modifiers) && !Modifier.isPrivate(modifiers)) {
|
||||
throw new RunException("[{}]协议号[protocolId:{}]中的[filed:{}]属性的访问修饰符必须是public或者private"
|
||||
, clazz.getCanonicalName(), protocolId, field.getName());
|
||||
}
|
||||
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
fields.add(field);
|
||||
}
|
||||
|
||||
// 按变量名称从小到大排序
|
||||
fields.sort(PACKET_FIELD_COMPARATOR);
|
||||
|
||||
var registrationList = new ArrayList<IFieldRegistration>();
|
||||
for (var field : fields) {
|
||||
registrationList.add(toRegistration(clazz, field));
|
||||
}
|
||||
|
||||
var constructor = clazz.getDeclaredConstructor();
|
||||
ReflectionUtils.makeAccessible(constructor);
|
||||
var protocol = new ProtocolRegistration();
|
||||
protocol.setId(protocolId);
|
||||
protocol.setConstructor(constructor);
|
||||
protocol.setFields(fields.toArray(new Field[fields.size()]));
|
||||
protocol.setFieldRegistrations(registrationList.toArray(new IFieldRegistration[registrationList.size()]));
|
||||
protocol.setModule(module.getId());
|
||||
return protocol;
|
||||
}
|
||||
|
||||
private static IFieldRegistration toRegistration(Class<?> clazz, Field field) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<?> fieldTypeClazz = field.getType();
|
||||
|
||||
ISerializer serializer = tempBaseSerializerMap.get(fieldTypeClazz);
|
||||
|
||||
// 是一个基本类型变量
|
||||
if (serializer != null) {
|
||||
return BaseField.valueOf(serializer);
|
||||
} else if (fieldTypeClazz.getComponentType() != null) {
|
||||
// 是一个数组
|
||||
Class<?> arrayClazz = fieldTypeClazz.getComponentType();
|
||||
|
||||
IFieldRegistration registration = typeToRegistration(clazz, arrayClazz);
|
||||
return ArrayField.valueOf(field, registration);
|
||||
} else if (Set.class.isAssignableFrom(fieldTypeClazz)) {
|
||||
if (!fieldTypeClazz.equals(Set.class)) {
|
||||
throw new RunException("[class:{}]类型声明不正确,必须是Set接口类型", clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
Type type = field.getGenericType();
|
||||
|
||||
if (!(type instanceof ParameterizedType)) {
|
||||
throw new RunException("[class:{}]类型声明不正确,不是泛型类[field:{}]", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
|
||||
if (types.length != 1) {
|
||||
throw new RunException("[class:{}]中Set类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
IFieldRegistration registration = typeToRegistration(clazz, types[0]);
|
||||
return SetField.valueOf(registration, type);
|
||||
} else if (List.class.isAssignableFrom(fieldTypeClazz)) {
|
||||
// 是一个List
|
||||
if (!fieldTypeClazz.equals(List.class)) {
|
||||
throw new RunException("[class:{}]类型声明不正确,必须是List接口类型", clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
Type type = field.getGenericType();
|
||||
|
||||
if (!(type instanceof ParameterizedType)) {
|
||||
throw new RunException("[class:{}]类型声明不正确,不是泛型类[field:{}]", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
|
||||
if (types.length != 1) {
|
||||
throw new RunException("[class:{}]中List类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
IFieldRegistration registration = typeToRegistration(clazz, types[0]);
|
||||
return ListField.valueOf(registration, (ParameterizedType) type);
|
||||
|
||||
} else if (Map.class.isAssignableFrom(fieldTypeClazz)) {
|
||||
if (!fieldTypeClazz.equals(Map.class)) {
|
||||
throw new RunException("[class:{}]类型声明不正确,必须是Map接口类型", clazz.getCanonicalName());
|
||||
}
|
||||
|
||||
Type type = field.getGenericType();
|
||||
|
||||
if (!(type instanceof ParameterizedType)) {
|
||||
throw new RunException("[class:{}]中数组类型声明不正确,[field:{}]不是泛型类", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
Type[] types = ((ParameterizedType) type).getActualTypeArguments();
|
||||
|
||||
if (types.length != 2) {
|
||||
throw new RunException("[class:{}]中数组类型声明不正确,[field:{}]必须声明泛型类", clazz.getCanonicalName(), field.getName());
|
||||
}
|
||||
|
||||
IFieldRegistration keyRegistration = typeToRegistration(clazz, types[0]);
|
||||
IFieldRegistration valueRegistration = typeToRegistration(clazz, types[1]);
|
||||
|
||||
return MapField.valueOf(keyRegistration, valueRegistration, type);
|
||||
} else {
|
||||
// 是一个协议引用变量
|
||||
var referenceProtocolId = getProtocolIdByClass(field.getType());
|
||||
tempSubProtocolIdMap.computeIfAbsent(getProtocolIdByClass(clazz), it -> new HashSet<>()).add(referenceProtocolId);
|
||||
return ObjectProtocolField.valueOf(referenceProtocolId);
|
||||
}
|
||||
}
|
||||
|
||||
private static IFieldRegistration typeToRegistration(Class<?> currentProtocolClass, Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
// 泛型类
|
||||
Class<?> clazz = (Class<?>) ((ParameterizedType) type).getRawType();
|
||||
if (Set.class.equals(clazz)) {
|
||||
// Set<Set<String>>
|
||||
IFieldRegistration registration = typeToRegistration(currentProtocolClass, ((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
return SetField.valueOf(registration, type);
|
||||
} else if (List.class.equals(clazz)) {
|
||||
// List<List<String>>
|
||||
IFieldRegistration registration = typeToRegistration(currentProtocolClass, ((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
return ListField.valueOf(registration, (ParameterizedType) type);
|
||||
} else if (Map.class.equals(clazz)) {
|
||||
// Map<List<String>, List<String>>
|
||||
IFieldRegistration keyRegistration = typeToRegistration(currentProtocolClass, ((ParameterizedType) type).getActualTypeArguments()[0]);
|
||||
IFieldRegistration valueRegistration = typeToRegistration(currentProtocolClass, ((ParameterizedType) type).getActualTypeArguments()[1]);
|
||||
return MapField.valueOf(keyRegistration, valueRegistration, type);
|
||||
}
|
||||
} else if (type instanceof Class) {
|
||||
Class<?> clazz = ((Class<?>) type);
|
||||
ISerializer serializer = tempBaseSerializerMap.get(clazz);
|
||||
if (serializer != null) {
|
||||
// 基础类型
|
||||
return BaseField.valueOf(serializer);
|
||||
} else if (clazz.getComponentType() != null) {
|
||||
// 是一个二维以上数组
|
||||
throw new RunException("不支持多维数组或集合嵌套数组[type:{}]类型,仅支持一维数组", type);
|
||||
} else if (clazz.equals(List.class) || clazz.equals(Set.class) || clazz.equals(Map.class)) {
|
||||
throw new RunException("不支持数组和集合联合使用[type:{}]类型", type);
|
||||
} else {
|
||||
// 是一个协议引用变量
|
||||
var referenceProtocolId = getProtocolIdByClass(clazz);
|
||||
tempSubProtocolIdMap.computeIfAbsent(getProtocolIdByClass(currentProtocolClass), it -> new HashSet<>()).add(referenceProtocolId);
|
||||
return ObjectProtocolField.valueOf(referenceProtocolId);
|
||||
}
|
||||
}
|
||||
throw new RunException("[type:{}]类型不正确", type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 此方法仅在生成协议的时候调用,一旦运行,不能调用
|
||||
*/
|
||||
public static Set<Short> getAllSubProtocolIds(short protocolId) {
|
||||
AssertionUtils.notNull(tempSubProtocolIdMap, "[{}]已经初始完成,初始化完成过后不能调用getAllSubProtocolIds", ProtocolManager.class.getSimpleName());
|
||||
|
||||
if (!tempSubProtocolIdMap.containsKey(protocolId)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
var protocolClass = protocols[protocolId].protocolConstructor().getDeclaringClass();
|
||||
|
||||
var queue = new LinkedList<>(tempSubProtocolIdMap.get(protocolId));
|
||||
var allSubProtocolIdSet = new HashSet<>(queue);
|
||||
while (!queue.isEmpty()) {
|
||||
var firstSubProtocolId = queue.poll();
|
||||
if (tempSubProtocolIdMap.containsKey(firstSubProtocolId)) {
|
||||
for (var subClassId : tempSubProtocolIdMap.get(firstSubProtocolId)) {
|
||||
if (subClassId == protocolId) {
|
||||
throw new RunException("[class:{}]在下层协议[class:{}]包含循环引用协议[class:{}]", protocolClass.getSimpleName(), protocols[firstSubProtocolId].protocolConstructor().getDeclaringClass(), protocolClass.getSimpleName());
|
||||
}
|
||||
|
||||
if (!allSubProtocolIdSet.contains(subClassId)) {
|
||||
allSubProtocolIdSet.add(subClassId);
|
||||
queue.offer(subClassId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return allSubProtocolIdSet;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection;
|
||||
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class ArrayUtils {
|
||||
/**
|
||||
* length
|
||||
*/
|
||||
public static int length(boolean[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(byte[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(short[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(int[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(long[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(float[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(double[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static int length(char[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
public static <T> int length(T[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* toList
|
||||
*/
|
||||
public static List<Boolean> toList(boolean[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Boolean>();
|
||||
for (var value : array) {
|
||||
list.add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Byte> toList(byte[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Byte>();
|
||||
for (var value : array) {
|
||||
list.add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Short> toList(short[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Short>();
|
||||
for (var value : array) {
|
||||
list.add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Integer> toList(int[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Integer>();
|
||||
for (var j : array) {
|
||||
list.add(j);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Long> toList(long[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Long>();
|
||||
for (var j : array) {
|
||||
list.add(j);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Float> toList(float[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Float>();
|
||||
for (var j : array) {
|
||||
list.add(j);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Double> toList(double[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Double>();
|
||||
for (var j : array) {
|
||||
list.add(j);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Character> toList(char[] array) {
|
||||
if (array == null || array.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var list = new ArrayList<Character>();
|
||||
for (var j : array) {
|
||||
list.add(j);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <T> List<T> toList(T[] array) {
|
||||
if (CollectionUtils.isEmpty(array)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
|
||||
|
||||
public static <T> T[] listToArray(List<T> list, Class<T> clazz) {
|
||||
AssertionUtils.notNull(list);
|
||||
AssertionUtils.notNull(clazz);
|
||||
|
||||
var length = list.size();
|
||||
var objectArray = Array.newInstance(clazz, length);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
Array.set(objectArray, i, list.get(i));
|
||||
}
|
||||
|
||||
return (T[]) objectArray;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection;
|
||||
|
||||
|
||||
import com.zfoo.protocol.collection.model.NaturalComparator;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class CollectionUtils {
|
||||
|
||||
/**
|
||||
* Return {@code true} if the supplied Collection is {@code null} or empty.
|
||||
* Otherwise, return {@code false}.
|
||||
*
|
||||
* @param collection the Collection to check
|
||||
* @return whether the given Collection is empty
|
||||
*/
|
||||
public static boolean isEmpty(Collection<?> collection) {
|
||||
return (collection == null || collection.isEmpty());
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Collection<?> collection) {
|
||||
return !isEmpty(collection);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Object[] array) {
|
||||
return (array == null || array.length == 0);
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Object[] array) {
|
||||
return !isEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the supplied Map is {@code null} or empty.
|
||||
* Otherwise, return {@code false}.
|
||||
*
|
||||
* @param map the Map to check
|
||||
* @return whether the given Map is empty
|
||||
*/
|
||||
public static boolean isEmpty(Map<?, ?> map) {
|
||||
return (map == null || map.isEmpty());
|
||||
}
|
||||
|
||||
public static boolean isNotEmpty(Map<?, ?> map) {
|
||||
return !isEmpty(map);
|
||||
}
|
||||
|
||||
|
||||
public static int size(Collection<?> collection) {
|
||||
return collection == null ? 0 : collection.size();
|
||||
}
|
||||
|
||||
public static int size(Map<?, ?> map) {
|
||||
return map == null ? 0 : map.size();
|
||||
}
|
||||
|
||||
public static <T> Iterator<T> iterator(Collection<T> collection) {
|
||||
return isEmpty(collection) ? Collections.emptyIterator() : collection.iterator();
|
||||
}
|
||||
|
||||
public static <K, V> Iterator<Map.Entry<K, V>> iterator(Map<K, V> map) {
|
||||
return isEmpty(map) ? Collections.emptyIterator() : map.entrySet().iterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 固定大小集合,如果初始化容量为0,则后续无法继续增加集合容量
|
||||
*/
|
||||
public static List<?> newFixedList(int size) {
|
||||
return size <= 0 ? Collections.EMPTY_LIST : new ArrayList<>(size);
|
||||
}
|
||||
|
||||
public static Set<?> newFixedSet(int size) {
|
||||
return size <= 0 ? Collections.EMPTY_SET : new HashSet<>(comfortableCapacity(size));
|
||||
}
|
||||
|
||||
public static Map<?, ?> newFixedMap(int size) {
|
||||
return size <= 0 ? Collections.EMPTY_MAP : new HashMap<>(comfortableCapacity(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* The largest power of two that can be represented as an {@code int}.
|
||||
*/
|
||||
public static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
|
||||
|
||||
/**
|
||||
* 计算HashMap初始化合适的大小
|
||||
* <p>
|
||||
* from com.google.common.collect.Maps.capacity()
|
||||
*/
|
||||
public static int comfortableCapacity(int expectedSize) {
|
||||
if (expectedSize < 3) {
|
||||
return expectedSize + 1;
|
||||
}
|
||||
|
||||
if (expectedSize < MAX_POWER_OF_TWO) {
|
||||
return (int) ((float) expectedSize / 0.75F + 1.0F);
|
||||
}
|
||||
|
||||
// any large value
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// ----------------------------------归并排序----------------------------------
|
||||
|
||||
/**
|
||||
* Merges two sorted Collections, a and b, into a single, sorted List
|
||||
* such that the natural ordering of the elements is retained.
|
||||
* <p>
|
||||
* Uses the standard O(n) merge algorithm for combining two sorted lists.
|
||||
* </p>
|
||||
*
|
||||
* @param aList the first collection, must not be null
|
||||
* @param bList the second collection, must not be null
|
||||
* @return a new sorted List, containing the elements of Collection a and b
|
||||
*/
|
||||
public static <T extends Comparable<? super T>> List<T> collate(List<? extends T> aList, List<? extends T> bList) {
|
||||
return collate(aList, bList, NaturalComparator.getInstance(), true);
|
||||
}
|
||||
|
||||
public static <T extends Comparable<? super T>> List<T> collate(List<? extends T> aList, List<? extends T> bList, boolean includeDuplicates) {
|
||||
return collate(aList, bList, NaturalComparator.getInstance(), includeDuplicates);
|
||||
}
|
||||
|
||||
public static <T> List<T> collate(List<T> aList, List<T> bList, Comparator<T> comparator) {
|
||||
return collate(aList, bList, comparator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two sorted Collections, a and b, into a single, sorted List
|
||||
* such that the ordering of the elements according to Comparator c is retained.
|
||||
* <p>
|
||||
* Uses the standard O(n) merge algorithm for combining two sorted lists.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the element type
|
||||
* @param aList the first collection, must not be null
|
||||
* @param bList the second collection, must not be null
|
||||
* @param comparator the comparator to use for the merge.
|
||||
* @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise
|
||||
* they will be removed in the output collection
|
||||
* @return a new sorted List, containing the elements of Collection a and b
|
||||
*/
|
||||
public static <T> List<T> collate(List<? extends T> aList, List<? extends T> bList, Comparator<? super T> comparator, boolean includeDuplicates) {
|
||||
|
||||
if (aList == null || bList == null) {
|
||||
throw new NullPointerException("The collections must not be null");
|
||||
}
|
||||
if (comparator == null) {
|
||||
throw new NullPointerException("The comparator must not be null");
|
||||
}
|
||||
|
||||
var totalSize = aList.size() + bList.size();
|
||||
|
||||
var mergedList = new ArrayList<T>(totalSize);
|
||||
|
||||
var aIndex = 0;
|
||||
var bIndex = 0;
|
||||
|
||||
T lastItem = null;
|
||||
while (aIndex < aList.size() && bIndex < bList.size()) {
|
||||
var a = aList.get(aIndex);
|
||||
var b = bList.get(bIndex);
|
||||
if (a == null) {
|
||||
aIndex++;
|
||||
continue;
|
||||
}
|
||||
if (b == null) {
|
||||
bIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (comparator.compare(a, b) >= 0) {
|
||||
bIndex++;
|
||||
if (!includeDuplicates && lastItem != null && lastItem.equals(b)) {
|
||||
continue;
|
||||
}
|
||||
mergedList.add(b);
|
||||
lastItem = b;
|
||||
} else {
|
||||
aIndex++;
|
||||
if (!includeDuplicates && lastItem != null && lastItem.equals(a)) {
|
||||
continue;
|
||||
}
|
||||
mergedList.add(a);
|
||||
lastItem = a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (aIndex < aList.size()) {
|
||||
for (var i = aIndex; i < aList.size(); i++) {
|
||||
var value = aList.get(i);
|
||||
|
||||
if (!includeDuplicates && lastItem != null && lastItem.equals(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mergedList.add(value);
|
||||
lastItem = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (bIndex < bList.size()) {
|
||||
for (var i = bIndex; i < bList.size(); i++) {
|
||||
var value = bList.get(i);
|
||||
|
||||
if (!includeDuplicates && lastItem != null && lastItem.equals(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mergedList.add(value);
|
||||
lastItem = value;
|
||||
}
|
||||
}
|
||||
|
||||
mergedList.trimToSize();
|
||||
return mergedList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* list合并
|
||||
*
|
||||
* @param exclusive 元素是否是独占的,也就是说是否可以重复
|
||||
* @param pairs 需要被合并的pairs集合,第一个参数是步数,第二个参数是集合
|
||||
* @return 返回合并后的list
|
||||
*/
|
||||
public static <T> List<T> listJoinList(boolean exclusive, Pair<Integer, List<T>>... pairs) {
|
||||
return listJoinList(exclusive, List.of(pairs));
|
||||
}
|
||||
|
||||
public static <T> List<T> listJoinList(boolean exclusive, List<Pair<Integer, List<T>>> pairs) {
|
||||
var iteratorList = new ArrayList<List<T>>();
|
||||
var iteratorMap = new HashMap<List<T>, Iterator<T>>();
|
||||
var stepMap = new HashMap<List<T>, Integer>();
|
||||
for (var pair : pairs) {
|
||||
var step = pair.getKey();
|
||||
var list = pair.getValue();
|
||||
AssertionUtils.ge1(step);
|
||||
if (isNotEmpty(list)) {
|
||||
var iterator = list.iterator();
|
||||
iteratorList.add(list);
|
||||
iteratorMap.put(list, iterator);
|
||||
stepMap.put(list, step);
|
||||
}
|
||||
}
|
||||
|
||||
var result = new ArrayList<T>();
|
||||
|
||||
while (iteratorMap.values().stream().anyMatch(it -> it.hasNext())) {
|
||||
for (var list : iteratorList) {
|
||||
var iterator = iteratorMap.get(list);
|
||||
var step = stepMap.get(list);
|
||||
for (var i = 0; i < step && iterator.hasNext(); i++) {
|
||||
var element = iterator.next();
|
||||
if (exclusive && result.contains(element)) {
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
result.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合的最后几个元素
|
||||
*/
|
||||
public static <T> List<T> subListLast(List<T> list, int num) {
|
||||
if (isEmpty(list)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
var startIndex = list.size() - num;
|
||||
if (startIndex <= 0) {
|
||||
return new ArrayList<>(list);
|
||||
}
|
||||
|
||||
var result = new ArrayList<T>();
|
||||
|
||||
|
||||
for (T element : list) {
|
||||
startIndex--;
|
||||
if (startIndex < 0) {
|
||||
result.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ConcurrentArrayList<E> implements List<E> {
|
||||
|
||||
private ReentrantLock lock;
|
||||
|
||||
private ArrayList<E> list;
|
||||
|
||||
public ConcurrentArrayList() {
|
||||
this.lock = new ReentrantLock();
|
||||
this.list = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ConcurrentArrayList(int initialCapacity) {
|
||||
this.lock = new ReentrantLock();
|
||||
this.list = new ArrayList<>(initialCapacity);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
public List<E> clearAndReturn() {
|
||||
lock.lock();
|
||||
try {
|
||||
var newList = (ArrayList<E>) list.clone();
|
||||
list.clear();
|
||||
return newList;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.contains(o);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
lock.lock();
|
||||
try {
|
||||
var newList = (ArrayList<E>) list.clone();
|
||||
return newList.iterator();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.toArray();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.toArray(a);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.add(e);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.remove(o);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.containsAll(c);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.addAll(c);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.addAll(index, c);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.removeAll(c);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.retainAll(c);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
lock.lock();
|
||||
try {
|
||||
list.clear();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.set(index, element);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
lock.lock();
|
||||
try {
|
||||
list.add(index, element);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.remove(index);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.indexOf(o);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.lastIndexOf(o);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator() {
|
||||
lock.lock();
|
||||
try {
|
||||
var newList = (ArrayList<E>) list.clone();
|
||||
return newList.listIterator();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
lock.lock();
|
||||
try {
|
||||
var newList = (ArrayList<E>) list.clone();
|
||||
return newList.listIterator(index);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
lock.lock();
|
||||
try {
|
||||
return list.subList(fromIndex, toIndex);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this != o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return list.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ConcurrentHashSet<E> extends AbstractSet<E> {
|
||||
|
||||
private Map<E, Boolean> map;
|
||||
|
||||
public ConcurrentHashSet() {
|
||||
this.map = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public ConcurrentHashSet(int initialCapacity) {
|
||||
this.map = new ConcurrentHashMap<>(initialCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return map.keySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return map.containsKey(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
return map.put(e, Boolean.TRUE) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return map.remove(o) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection.model;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class NaturalComparator<E extends Comparable<? super E>> implements Comparator<E> {
|
||||
|
||||
|
||||
/**
|
||||
* The singleton instance.
|
||||
*/
|
||||
private static final NaturalComparator<?> INSTANCE = new NaturalComparator<>();
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructor whose use should be avoided.
|
||||
* <p>
|
||||
* Please use the {@link #getInstance()} method whenever possible.
|
||||
*/
|
||||
public NaturalComparator() {
|
||||
super();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the singleton instance of a ComparableComparator.
|
||||
* <p>
|
||||
* Developers are encouraged to use the comparator returned from this method
|
||||
* instead of constructing a new instance to reduce allocation and GC overhead
|
||||
* when multiple comparable comparators may be used in the same VM.
|
||||
*
|
||||
* @param <E> the element type
|
||||
* @return the singleton ComparableComparator
|
||||
*/
|
||||
public static <E extends Comparable<? super E>> NaturalComparator<E> getInstance() {
|
||||
return (NaturalComparator<E>) INSTANCE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compare the two {@link Comparable Comparable} arguments.
|
||||
* This method is equivalent to:
|
||||
* <pre>((Comparable)obj1).compareTo(obj2)</pre>
|
||||
*
|
||||
* @param a the first object to compare
|
||||
* @param b the second object to compare
|
||||
* @return negative if obj1 is less, positive if greater, zero if equal
|
||||
* @throws NullPointerException if <i>obj1</i> is <code>null</code>,
|
||||
* or when <code>((Comparable)obj1).compareTo(obj2)</code> does
|
||||
* @throws ClassCastException if <i>obj1</i> is not a <code>Comparable</code>,
|
||||
* or when <code>((Comparable)obj1).compareTo(obj2)</code> does
|
||||
*/
|
||||
@Override
|
||||
public int compare(final E a, final E b) {
|
||||
return a.compareTo(b);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection.tree;
|
||||
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 多叉树
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class GeneralTree<T> {
|
||||
|
||||
private TreeNode<T> rootNode = new TreeNode<>(null, null);
|
||||
|
||||
public TreeNode<T> getRootNode() {
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
public TreeNode<T> getNodeByPath(String path) {
|
||||
var current = rootNode;
|
||||
var splitPath = splitPath(path);
|
||||
for (var nodeName : splitPath) {
|
||||
current = current.childByName(nodeName);
|
||||
if (current == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
public void addNode(String path, T data) {
|
||||
var current = rootNode;
|
||||
|
||||
var splitPath = splitPath(path);
|
||||
for (var nodeName : splitPath) {
|
||||
current = current.getOrAddChild(nodeName);
|
||||
}
|
||||
current.setData(data);
|
||||
}
|
||||
|
||||
public void removeNode(String path) {
|
||||
var current = rootNode;
|
||||
var parent = current.getParent();
|
||||
var splitPath = splitPath(path);
|
||||
for (var nodeName : splitPath) {
|
||||
parent = current;
|
||||
current = current.childByName(nodeName);
|
||||
if (current == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent != null) {
|
||||
parent.removeChild(current.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除所有数据结点
|
||||
*/
|
||||
public void clear() {
|
||||
rootNode.clear();
|
||||
}
|
||||
|
||||
private String[] splitPath(String path) {
|
||||
if (StringUtils.isBlank(path)) {
|
||||
return StringUtils.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
if (!path.contains(StringUtils.PERIOD)) {
|
||||
return new String[]{path};
|
||||
}
|
||||
|
||||
return path.split(StringUtils.PERIOD_REGEX);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.collection.tree;
|
||||
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class TreeNode<T> {
|
||||
|
||||
private String name;
|
||||
private T data;
|
||||
private TreeNode<T> parent;
|
||||
private List<TreeNode<T>> children;
|
||||
|
||||
|
||||
/**
|
||||
* 创建树的结点
|
||||
*
|
||||
* @param name 数据结点名称
|
||||
* @param parent 父数据结点
|
||||
*/
|
||||
|
||||
TreeNode(String name, TreeNode<T> parent) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测数据结点名称是否合法
|
||||
*/
|
||||
private static void checkName(String name) {
|
||||
if (StringUtils.isBlank(name) || name.contains(StringUtils.PERIOD)) {
|
||||
throw new RuntimeException("Name of tree node is invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取数据结点的完整名称。
|
||||
*/
|
||||
public String fullName() {
|
||||
if (parent == null) {
|
||||
return name;
|
||||
}
|
||||
|
||||
var parentName = parent.fullName();
|
||||
if (parentName == null) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return StringUtils.format("{}{}{}", parentName, StringUtils.PERIOD, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称检查是否存在子数据结点
|
||||
*
|
||||
* @param name 子数据结点名称
|
||||
* @return 是否存在子数据结点
|
||||
*/
|
||||
public boolean hasChild(String name) {
|
||||
checkName(name);
|
||||
|
||||
if (children == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
if (child.name.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名称获取子数据结点
|
||||
*
|
||||
* @param name 子数据结点名称
|
||||
* @return 指定名称的子数据结点,如果没有找到,则返回空
|
||||
*/
|
||||
public TreeNode<T> childByName(String name) {
|
||||
checkName(name);
|
||||
|
||||
if (children == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
if (child.name.equals(name)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有子节点,包括父节点和子节点的子节点
|
||||
*/
|
||||
public List<TreeNode<T>> flatTreeNodes() {
|
||||
var result = new ArrayList<TreeNode<T>>();
|
||||
result.add(this);
|
||||
|
||||
if (CollectionUtils.isEmpty(children)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var queue = new LinkedList<>(children);
|
||||
result.addAll(queue);
|
||||
while (!queue.isEmpty()) {
|
||||
var childTreeNode = queue.poll();
|
||||
var childChildren = childTreeNode.getChildren();
|
||||
if (CollectionUtils.isEmpty(childChildren)) {
|
||||
continue;
|
||||
}
|
||||
for (var subClassId : childTreeNode.getChildren()) {
|
||||
result.add(subClassId);
|
||||
queue.offer(subClassId);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称获取或增加子数据结点
|
||||
*
|
||||
* @param name 子数据结点名称
|
||||
* @return 指定名称的子数据结点,如果对应名称的子数据结点已存在,则返回已存在的子数据结点,否则增加子数据结点
|
||||
*/
|
||||
public TreeNode<T> getOrAddChild(String name) {
|
||||
var node = childByName(name);
|
||||
if (node != null) {
|
||||
return node;
|
||||
}
|
||||
|
||||
node = new TreeNode<>(name, this);
|
||||
|
||||
if (children == null) {
|
||||
children = new ArrayList<>();
|
||||
}
|
||||
|
||||
children.add(node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称移除子数据结点
|
||||
*
|
||||
* @param name 子数据结点名称
|
||||
*/
|
||||
public void removeChild(String name) {
|
||||
var node = childByName(name);
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
children.remove(node);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
name = null;
|
||||
data = null;
|
||||
parent = null;
|
||||
children = null;
|
||||
}
|
||||
|
||||
public int childCount() {
|
||||
if (CollectionUtils.isEmpty(children)) {
|
||||
return 0;
|
||||
}
|
||||
return children.size();
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<TreeNode<T>> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public TreeNode<T> getParent() {
|
||||
return parent;
|
||||
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.format("[{}]:[{}]", fullName(), data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.exception;
|
||||
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class AssertException extends RuntimeException {
|
||||
|
||||
public AssertException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AssertException(String template, Object... args) {
|
||||
super(StringUtils.format(template, args));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.exception;
|
||||
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class ExceptionUtils {
|
||||
|
||||
/**
|
||||
* 获取异常全部信息,格式是:
|
||||
* <p>
|
||||
* 类名称: 异常信息
|
||||
* 异常堆栈
|
||||
* </p>
|
||||
*
|
||||
* @param throwable the throwable to get a message for, null returns empty string
|
||||
* @return 异常的信息
|
||||
*/
|
||||
public static String getMessage(final Throwable throwable) {
|
||||
if (throwable == null) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
final String className = throwable.getClass().getName();
|
||||
return className + ": " + throwable.getMessage() + FileUtils.LS
|
||||
+ getStackTrace(throwable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Gets the stack trace from a Throwable as a String.</p>
|
||||
* <p>The result of this method vary by JDK version as this method uses {@link Throwable#printStackTrace(java.io.PrintWriter)}.
|
||||
*
|
||||
* @param throwable the <code>Throwable</code> to be examined
|
||||
* @return the stack trace as generated by the exception's
|
||||
*/
|
||||
public static String getStackTrace(final Throwable throwable) {
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw, true);
|
||||
throwable.printStackTrace(pw);
|
||||
return sw.getBuffer().toString();
|
||||
}
|
||||
|
||||
public static String getCurrentStackTrace() {
|
||||
var builder = new StringBuilder();
|
||||
var stackTraces = Thread.currentThread().getStackTrace();
|
||||
Arrays.stream(stackTraces).forEach(it -> builder.append(it.toString()).append(FileUtils.LS));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.exception;
|
||||
|
||||
/**
|
||||
* 不是一个POJO对象,POJO对象不应该继承别的类
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class POJOException extends RuntimeException {
|
||||
|
||||
private static final String MESSAGE = "not a POJO object, can't extend other object";
|
||||
|
||||
private static final String HYPHEN = "-";//连接号,连接号与破折号的区别是,连接号的两头不用空格
|
||||
|
||||
private static final String LEFT_SQUARE_BRACKET = "[";//左方括号
|
||||
|
||||
private static final String RIGHT_SQUARE_BRACKET = "]";//右方括号
|
||||
|
||||
public POJOException() {
|
||||
super(POJOException.MESSAGE);
|
||||
}
|
||||
|
||||
public POJOException(String message) {
|
||||
super(POJOException.MESSAGE + POJOException.HYPHEN + POJOException.LEFT_SQUARE_BRACKET + message + POJOException.RIGHT_SQUARE_BRACKET);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.exception;
|
||||
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class RunException extends RuntimeException {
|
||||
|
||||
public RunException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public RunException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public RunException(String template, Object... args) {
|
||||
super(StringUtils.format(template, args));
|
||||
}
|
||||
|
||||
public RunException(Throwable cause, String message) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public RunException(Throwable cause, String template, Object... args) {
|
||||
super(StringUtils.format(template, args), cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.exception;
|
||||
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class UnknownException extends RuntimeException {
|
||||
|
||||
public UnknownException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public UnknownException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UnknownException(String template, Object... args) {
|
||||
super(StringUtils.format(template, args));
|
||||
}
|
||||
|
||||
public UnknownException(Throwable cause, String message) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public UnknownException(Throwable cause, String template, Object... args) {
|
||||
super(StringUtils.format(template, args), cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.generate;
|
||||
|
||||
/**
|
||||
* 创建协议文件的操作类
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class GenerateOperation {
|
||||
|
||||
/**
|
||||
* 不创建任何协议文件
|
||||
*/
|
||||
public static final GenerateOperation NO_OPERATION = new GenerateOperation();
|
||||
|
||||
/**
|
||||
* 折叠协议,生成协议文件会和Java源文件保持相同的目录结构
|
||||
*/
|
||||
private boolean foldProtocol;
|
||||
|
||||
/**
|
||||
* 生成协议文件的后缀名称,如果不指定,用语言约定的默认名称
|
||||
*/
|
||||
private String protocolParam;
|
||||
|
||||
/**
|
||||
* 生成javascript协议文件
|
||||
*/
|
||||
private boolean generateJsProtocol;
|
||||
|
||||
/**
|
||||
* 生成C#协议文件
|
||||
*/
|
||||
private boolean generateCsharpProtocol;
|
||||
|
||||
/**
|
||||
* 生成Lua协议文件
|
||||
*/
|
||||
private boolean generateLuaProtocol;
|
||||
|
||||
public boolean isFoldProtocol() {
|
||||
return foldProtocol;
|
||||
}
|
||||
|
||||
public void setFoldProtocol(boolean foldProtocol) {
|
||||
this.foldProtocol = foldProtocol;
|
||||
}
|
||||
|
||||
public String getProtocolParam() {
|
||||
return protocolParam;
|
||||
}
|
||||
|
||||
public void setProtocolParam(String protocolParam) {
|
||||
this.protocolParam = protocolParam;
|
||||
}
|
||||
|
||||
public boolean isGenerateJsProtocol() {
|
||||
return generateJsProtocol;
|
||||
}
|
||||
|
||||
public void setGenerateJsProtocol(boolean generateJsProtocol) {
|
||||
this.generateJsProtocol = generateJsProtocol;
|
||||
}
|
||||
|
||||
public boolean isGenerateCsharpProtocol() {
|
||||
return generateCsharpProtocol;
|
||||
}
|
||||
|
||||
public void setGenerateCsharpProtocol(boolean generateCsharpProtocol) {
|
||||
this.generateCsharpProtocol = generateCsharpProtocol;
|
||||
}
|
||||
|
||||
public boolean isGenerateLuaProtocol() {
|
||||
return generateLuaProtocol;
|
||||
}
|
||||
|
||||
public void setGenerateLuaProtocol(boolean generateLuaProtocol) {
|
||||
this.generateLuaProtocol = generateLuaProtocol;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.generate;
|
||||
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* 生成协议的时候,协议的文档注释和字段注释会使用这个类
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateProtocolDocument {
|
||||
|
||||
// 临时变量,启动完成就会销毁,协议的文档,外层map的key为协议类;pair的key为总的注释,value为属性字段的注释,value表示的map的key为属性名称
|
||||
// 比如在Test中的ComplexObject生成的pari是如下格式
|
||||
/**
|
||||
* key docTitle:
|
||||
* // 复杂的对象
|
||||
* // 包括了各种复杂的结构,数组,List,Set,Map
|
||||
* //
|
||||
* // @author jaysunxiao
|
||||
* // @version 1.0
|
||||
* <p>
|
||||
* value aa:
|
||||
* // byte的包装类型
|
||||
* // 优先使用基础类型,包装类型会有装箱拆箱
|
||||
*/
|
||||
private static Map<Short, Pair<String, Map<String, String>>> tempProtocolDocumentMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void clear() {
|
||||
tempProtocolDocumentMap.clear();
|
||||
tempProtocolDocumentMap = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 此方法仅在生成协议的时候调用,一旦运行,不能调用
|
||||
*/
|
||||
public static Pair<String, Map<String, String>> getProtocolDocument(short protocolId) {
|
||||
AssertionUtils.notNull(tempProtocolDocumentMap, "[{}]已经初始完成,初始化完成过后不能调用getProtocolDocument", GenerateProtocolDocument.class.getSimpleName());
|
||||
|
||||
var protocolDocument = tempProtocolDocumentMap.get(protocolId);
|
||||
if (protocolDocument == null) {
|
||||
return new Pair<>(StringUtils.EMPTY, Collections.emptyMap());
|
||||
}
|
||||
return protocolDocument;
|
||||
}
|
||||
|
||||
|
||||
public static void initProtocolDocument(List<IProtocolRegistration> protocolRegistrations) {
|
||||
AssertionUtils.notNull(tempProtocolDocumentMap, "[{}]已经初始完成,初始化完成过后不能调用initProtocolDocument", GenerateProtocolDocument.class.getSimpleName());
|
||||
|
||||
for (var protocolRegistration : protocolRegistrations) {
|
||||
var protocolClazzName = protocolRegistration.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
// 文件的注释生成
|
||||
var proAbsFile = new File(FileUtils.getProAbsPath());
|
||||
var list = FileUtils.getAllReadableFiles(proAbsFile.getParentFile() == null ? proAbsFile : proAbsFile.getParentFile());
|
||||
var protocolFile = list.stream()
|
||||
.filter(it -> it.getName().equals(StringUtils.format("{}.java", protocolClazzName)))
|
||||
.findFirst();
|
||||
|
||||
// 如果搜索不到协议文件则直接返回
|
||||
if (protocolFile.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var docFieldMap = new HashMap<String, String>();
|
||||
var docTitle = StringUtils.EMPTY;
|
||||
|
||||
var protocolStringList = FileUtils.readFileToStringList(protocolFile.get())
|
||||
.stream()
|
||||
.dropWhile(it -> !it.startsWith("package")) // 过滤掉package之上的版权信息
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 搜索包名,报名不匹配则直接返回
|
||||
var protocolClassTitle = StringUtils.format("public class {}", protocolClazzName);
|
||||
if (protocolStringList.stream().noneMatch(it -> it.contains(protocolClassTitle))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
protocolStringList = protocolStringList.stream()
|
||||
.dropWhile(it -> !it.startsWith("package"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
var docBuilder = new StringBuilder();
|
||||
var docTitleBuilder = new StringBuilder();
|
||||
for (var line : protocolStringList) {
|
||||
var startLineStr = line.trim();
|
||||
|
||||
// 排除java的包头
|
||||
if (startLineStr.startsWith("package") || startLineStr.startsWith("import")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (startLineStr.startsWith("public class ")) {
|
||||
if (docTitleBuilder != null) {
|
||||
docTitle = docTitleBuilder.toString();
|
||||
docTitle = docTitle.replace("/**", StringUtils.EMPTY);
|
||||
docTitle = docTitle.replace(" */", StringUtils.EMPTY);
|
||||
docTitle = docTitle.replace(" *", "//");
|
||||
docTitle = docTitle.trim();
|
||||
docBuilder = new StringBuilder();
|
||||
docTitleBuilder = null;
|
||||
}
|
||||
} else {
|
||||
if (docTitleBuilder != null) {
|
||||
docTitleBuilder.append(line).append(LS);
|
||||
}
|
||||
}
|
||||
|
||||
// 保留注释
|
||||
if (startLineStr.startsWith("*/")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startLineStr.startsWith("//") || startLineStr.startsWith("*")) {
|
||||
startLineStr = startLineStr.replaceFirst("//", StringUtils.EMPTY);
|
||||
startLineStr = startLineStr.replaceFirst("\\*", StringUtils.EMPTY);
|
||||
docBuilder.append("//").append(startLineStr).append(LS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startLineStr.startsWith("private static ")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startLineStr.contains(" transient ")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startLineStr.startsWith("public void set") || startLineStr.startsWith("public bool equals")
|
||||
|| startLineStr.startsWith("public int hashCode") || startLineStr.startsWith("@Override")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startLineStr.endsWith("{") || startLineStr.startsWith("return ") || startLineStr.startsWith("}")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!startLineStr.endsWith(";")) {
|
||||
continue;
|
||||
}
|
||||
if (!(startLineStr.startsWith("private ") || startLineStr.startsWith("public "))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var fieldName = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(startLineStr, StringUtils.SPACE), StringUtils.SEMICOLON).trim();
|
||||
docFieldMap.put(fieldName, docBuilder.toString());
|
||||
docBuilder = new StringBuilder();
|
||||
}
|
||||
|
||||
tempProtocolDocumentMap.put(protocolRegistration.protocolId(), new Pair<>(docTitle, docFieldMap));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.generate;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.serializer.cs.GenerateCsUtils;
|
||||
import com.zfoo.protocol.serializer.js.GenerateJsUtils;
|
||||
import com.zfoo.protocol.serializer.lua.GenerateLuaUtils;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateProtocolFile {
|
||||
|
||||
/**
|
||||
* 生成协议的过滤器,默认不过滤
|
||||
*/
|
||||
public static Predicate<IProtocolRegistration> generateProtocolFilter = registration -> true;
|
||||
|
||||
|
||||
public static void generate(IProtocolRegistration[] protocols, GenerateOperation generateOperation) throws IOException {
|
||||
|
||||
// 如果没有需要生成的协议则直接返回
|
||||
var generateProtocolFlag = Arrays.stream(generateOperation.getClass().getDeclaredFields())
|
||||
.filter(it -> it.getName().startsWith("generate"))
|
||||
.peek(it -> ReflectionUtils.makeAccessible(it))
|
||||
.map(it -> ReflectionUtils.getField(it, generateOperation))
|
||||
.filter(it -> it instanceof Boolean)
|
||||
.anyMatch(it -> ((Boolean) it).booleanValue() == true);
|
||||
|
||||
if (!generateProtocolFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 外层需要生成的协议
|
||||
var outsideGenerateProtocols = Arrays.stream(protocols)
|
||||
.filter(it -> Objects.nonNull(it))
|
||||
.filter(it -> generateProtocolFilter.test(it))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 需要生成的子协议,因为外层协议的内部有其它协议
|
||||
var insideGenerateProtocols = outsideGenerateProtocols.stream()
|
||||
.map(it -> ProtocolManager.getAllSubProtocolIds(it.protocolId()))
|
||||
.flatMap(it -> it.stream())
|
||||
.map(it -> protocols[it])
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
var allGenerateProtocols = new HashSet<IProtocolRegistration>();
|
||||
allGenerateProtocols.addAll(outsideGenerateProtocols);
|
||||
allGenerateProtocols.addAll(insideGenerateProtocols);
|
||||
|
||||
// 通过协议号,从小到大排序
|
||||
var allSortedGenerateProtocols = allGenerateProtocols.stream()
|
||||
.sorted((a, b) -> a.protocolId() - b.protocolId())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 解析协议的文档注释
|
||||
GenerateProtocolDocument.initProtocolDocument(allSortedGenerateProtocols);
|
||||
|
||||
|
||||
// 计算协议生成的路径
|
||||
if (generateOperation.isFoldProtocol()) {
|
||||
GenerateProtocolPath.initProtocolPath(allSortedGenerateProtocols);
|
||||
}
|
||||
|
||||
// 生成C#协议
|
||||
if (generateOperation.isGenerateCsharpProtocol()) {
|
||||
GenerateCsUtils.init();
|
||||
GenerateCsUtils.createProtocolManager();
|
||||
allSortedGenerateProtocols.forEach(it -> GenerateCsUtils.createCsProtocolFile((ProtocolRegistration) it));
|
||||
}
|
||||
|
||||
// 生成Javascript协议
|
||||
if (generateOperation.isGenerateJsProtocol()) {
|
||||
GenerateJsUtils.init();
|
||||
allSortedGenerateProtocols.forEach(it -> GenerateJsUtils.createJsProtocolFile((ProtocolRegistration) it));
|
||||
GenerateJsUtils.createProtocolManager(allSortedGenerateProtocols);
|
||||
}
|
||||
|
||||
// 生成Lua协议
|
||||
if (generateOperation.isGenerateLuaProtocol()) {
|
||||
GenerateLuaUtils.init();
|
||||
GenerateLuaUtils.createProtocolManager(allSortedGenerateProtocols);
|
||||
allSortedGenerateProtocols.forEach(it -> GenerateLuaUtils.createLuaProtocolFile((ProtocolRegistration) it));
|
||||
}
|
||||
|
||||
// 参数,以后可能会用,比如给Lua修改一个后缀名称
|
||||
var protocolParam = generateOperation.getProtocolParam();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.generate;
|
||||
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.collection.tree.GeneralTree;
|
||||
import com.zfoo.protocol.collection.tree.TreeNode;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 生成协议的时候,协议的最终生成路径会使用这个类
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateProtocolPath {
|
||||
|
||||
// 临时变量,启动完成就会销毁,协议生成的路径
|
||||
private static Map<Short, String> tempProtocolPathMap = new HashMap<>();
|
||||
|
||||
|
||||
public static void clear() {
|
||||
tempProtocolPathMap.clear();
|
||||
tempProtocolPathMap = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取协议生成的路径
|
||||
*/
|
||||
public static String getProtocolPath(short protocolId) {
|
||||
AssertionUtils.notNull(tempProtocolPathMap, "[{}]已经初始完成,初始化完成过后不能调用getProtocolPath", GenerateProtocolPath.class.getSimpleName());
|
||||
|
||||
var protocolPath = tempProtocolPathMap.get(protocolId);
|
||||
if (StringUtils.isBlank(protocolPath)) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
return protocolPath.replaceAll(StringUtils.PERIOD_REGEX, StringUtils.SLASH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取协议生成的首字母大写的路径
|
||||
*/
|
||||
public static String getCapitalizeProtocolPath(short protocolId) {
|
||||
return StringUtils.joinWith(StringUtils.SLASH, Arrays.stream(getProtocolPath(protocolId).split(StringUtils.SLASH)).map(it -> StringUtils.capitalize(it)).toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析协议的路径
|
||||
*
|
||||
* @param protocolRegistrations 需要解析的路径
|
||||
*/
|
||||
public static void initProtocolPath(List<IProtocolRegistration> protocolRegistrations) {
|
||||
AssertionUtils.notNull(tempProtocolPathMap, "[{}]已经初始完成,初始化完成过后不能调用initProtocolPath", GenerateProtocolPath.class.getSimpleName());
|
||||
|
||||
// 将需要生成的协议的路径添加到多叉树中
|
||||
var protocolPathTree = new GeneralTree<IProtocolRegistration>();
|
||||
protocolRegistrations.forEach(it -> protocolPathTree.addNode(it.protocolConstructor().getDeclaringClass().getCanonicalName(), it));
|
||||
|
||||
var rootTreeNode = protocolPathTree.getRootNode();
|
||||
|
||||
if (CollectionUtils.isEmpty(rootTreeNode.getChildren())) {
|
||||
return;
|
||||
}
|
||||
|
||||
var queue = new LinkedList<>(rootTreeNode.getChildren());
|
||||
while (!queue.isEmpty()) {
|
||||
var childTreeNode = queue.poll();
|
||||
var childChildren = childTreeNode.getChildren();
|
||||
// 如果子节点为空,则以当前节点为路径
|
||||
if (CollectionUtils.isEmpty(childChildren)) {
|
||||
toProtocolPath(childTreeNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果子节点的协议数据有一个不为空的,则以当前节点为路径
|
||||
if (childChildren.stream().anyMatch(it -> it.getData() != null)) {
|
||||
toProtocolPath(childTreeNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 继续深度便利子节点的路径
|
||||
for (var subClassId : childTreeNode.getChildren()) {
|
||||
queue.offer(subClassId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void toProtocolPath(TreeNode<IProtocolRegistration> protocolTreeNode) {
|
||||
var allChildren = protocolTreeNode.flatTreeNodes()
|
||||
.stream()
|
||||
.filter(it -> it.getData() != null)
|
||||
.collect(Collectors.toList());
|
||||
var pathBefore = StringUtils.substringBeforeLast(protocolTreeNode.fullName(), StringUtils.PERIOD);
|
||||
for (var child : allChildren) {
|
||||
var protocolSimpleName = child.getData().protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var splits = Arrays.stream(StringUtils.substringBeforeLast(StringUtils.substringAfterFirst(child.fullName(), pathBefore), protocolSimpleName)
|
||||
.split(StringUtils.PERIOD_REGEX))
|
||||
.filter(it -> !StringUtils.isBlank(it))
|
||||
.toArray();
|
||||
tempProtocolPathMap.put(child.getData().protocolId(), StringUtils.joinWith(StringUtils.PERIOD, splits));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.model;
|
||||
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 键值对对象,只能在构造时传入键值
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class Pair<K, V> {
|
||||
|
||||
private K key;
|
||||
private V value;
|
||||
|
||||
public Pair() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public Pair(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取键
|
||||
*
|
||||
* @return 键
|
||||
*/
|
||||
public K getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取值
|
||||
*
|
||||
* @return 值
|
||||
*/
|
||||
public V getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Pair<?, ?> pair = (Pair<?, ?>) o;
|
||||
return Objects.equals(key, pair.key) && Objects.equals(value, pair.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pair [key=" + key + ", value=" + value + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.model;
|
||||
|
||||
|
||||
/**
|
||||
* T cardinal number that is the sum of three and one.
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class Quaternion<A, B, C, D> {
|
||||
|
||||
private A a;
|
||||
private B b;
|
||||
private C c;
|
||||
private D d;
|
||||
|
||||
public Quaternion() {
|
||||
}
|
||||
|
||||
public Quaternion(A a, B b, C c, D d) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
public A getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public B getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public C getC() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public D getD() {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.model;
|
||||
|
||||
|
||||
/**
|
||||
* A triple consisting of three elements. It refers to the elements as 'left', 'middle' and 'right'.
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class Triple<L, M, R> {
|
||||
|
||||
private L left;
|
||||
private M middle;
|
||||
private R right;
|
||||
|
||||
public Triple() {
|
||||
}
|
||||
|
||||
public Triple(L left, M middle, R right) {
|
||||
this.left = left;
|
||||
this.middle = middle;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public L getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public M getMiddle() {
|
||||
return middle;
|
||||
}
|
||||
|
||||
public R getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.collection.ArrayUtils;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.*;
|
||||
import com.zfoo.protocol.serializer.enhance.*;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import javassist.*;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 对应于ProtocolRegistration
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class EnhanceUtils {
|
||||
|
||||
// 临时变量,是一个基本类型序列化器对应的增强类型序列化器
|
||||
private static Map<ISerializer, IEnhanceSerializer> tempEnhanceSerializerMap = new HashMap<>();
|
||||
|
||||
public static String byteBufUtils = ByteBufUtils.class.getSimpleName();
|
||||
public static String byteBufUtilsWriteBooleanFalse = byteBufUtils + ".writeBoolean($1, false);";
|
||||
public static String byteBufUtilsWriteBooleanTrue = byteBufUtils + ".writeBoolean($1, true);";
|
||||
public static String byteBufUtilsReadBoolean = byteBufUtils + ".readBoolean($1)";
|
||||
public static String byteBufUtilsWriteInt0 = byteBufUtils + ".writeInt($1, 0);";
|
||||
|
||||
static {
|
||||
var classArray = new Class<?>[]{
|
||||
IPacket.class,
|
||||
IProtocolRegistration.class,
|
||||
IFieldRegistration.class,
|
||||
ByteBuf.class
|
||||
};
|
||||
|
||||
var classPool = ClassPool.getDefault();
|
||||
|
||||
// 导入需要的包
|
||||
classPool.importPackage(IPacket.class.getCanonicalName());
|
||||
classPool.importPackage(ByteBufUtils.class.getCanonicalName());
|
||||
classPool.importPackage(Collections.class.getCanonicalName());
|
||||
classPool.importPackage(CollectionUtils.class.getCanonicalName());
|
||||
classPool.importPackage(ArrayUtils.class.getCanonicalName());
|
||||
classPool.importPackage(Iterator.class.getCanonicalName());
|
||||
classPool.importPackage(List.class.getCanonicalName());
|
||||
classPool.importPackage(ArrayList.class.getCanonicalName());
|
||||
classPool.importPackage(Map.class.getCanonicalName());
|
||||
classPool.importPackage(HashMap.class.getCanonicalName());
|
||||
classPool.importPackage(Set.class.getCanonicalName());
|
||||
classPool.importPackage(HashSet.class.getCanonicalName());
|
||||
|
||||
// 增加类的路径
|
||||
for (var clazz : classArray) {
|
||||
if (classPool.find(clazz.getCanonicalName()) == null) {
|
||||
ClassClassPath classPath = new ClassClassPath(clazz);
|
||||
classPool.insertClassPath(classPath);
|
||||
}
|
||||
}
|
||||
|
||||
tempEnhanceSerializerMap.put(BooleanSerializer.getInstance(), new EnhanceBooleanSerializer());
|
||||
tempEnhanceSerializerMap.put(ByteSerializer.getInstance(), new EnhanceByteSerializer());
|
||||
tempEnhanceSerializerMap.put(ShortSerializer.getInstance(), new EnhanceShortSerializer());
|
||||
tempEnhanceSerializerMap.put(IntSerializer.getInstance(), new EnhanceIntSerializer());
|
||||
tempEnhanceSerializerMap.put(LongSerializer.getInstance(), new EnhanceLongSerializer());
|
||||
tempEnhanceSerializerMap.put(FloatSerializer.getInstance(), new EnhanceFloatSerializer());
|
||||
tempEnhanceSerializerMap.put(DoubleSerializer.getInstance(), new EnhanceDoubleSerializer());
|
||||
tempEnhanceSerializerMap.put(CharSerializer.getInstance(), new EnhanceCharSerializer());
|
||||
tempEnhanceSerializerMap.put(StringSerializer.getInstance(), new EnhanceStringSerializer());
|
||||
tempEnhanceSerializerMap.put(ObjectProtocolSerializer.getInstance(), new EnhanceObjectProtocolSerializer());
|
||||
tempEnhanceSerializerMap.put(ListSerializer.getInstance(), new EnhanceListSerializer());
|
||||
tempEnhanceSerializerMap.put(SetSerializer.getInstance(), new EnhanceSetSerializer());
|
||||
tempEnhanceSerializerMap.put(MapSerializer.getInstance(), new EnhanceMapSerializer());
|
||||
tempEnhanceSerializerMap.put(ArraySerializer.getInstance(), new EnhanceArraySerializer());
|
||||
}
|
||||
|
||||
public static IEnhanceSerializer enhanceSerializer(ISerializer serializer) {
|
||||
return tempEnhanceSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
tempEnhanceSerializerMap.clear();
|
||||
tempEnhanceSerializerMap = null;
|
||||
|
||||
byteBufUtils = null;
|
||||
byteBufUtilsWriteBooleanFalse = null;
|
||||
byteBufUtilsWriteBooleanTrue = null;
|
||||
byteBufUtilsReadBoolean = null;
|
||||
byteBufUtilsWriteInt0 = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param registration 需要增强的类
|
||||
* @return 返回类的名称格式:EnhanceUtilsProtocolRegistration1
|
||||
*/
|
||||
public static IProtocolRegistration createProtocolRegistration(ProtocolRegistration registration) throws NotFoundException, CannotCompileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
var classPool = ClassPool.getDefault();
|
||||
|
||||
GenerateUtils.index.set(0);
|
||||
|
||||
short protocolId = registration.getId();
|
||||
IFieldRegistration[] packetFields = registration.getFieldRegistrations();
|
||||
|
||||
// 定义类名称
|
||||
CtClass enhanceClazz = classPool.makeClass(ProtocolRegistration.class.getCanonicalName() + protocolId);
|
||||
enhanceClazz.addInterface(classPool.get(IProtocolRegistration.class.getCanonicalName()));
|
||||
|
||||
// 定义类中的一个成员
|
||||
CtField constructorFiled = new CtField(classPool.get(Constructor.class.getCanonicalName()), "constructor", enhanceClazz);
|
||||
constructorFiled.setModifiers(Modifier.PRIVATE);
|
||||
enhanceClazz.addField(constructorFiled);
|
||||
|
||||
// 定义类所包含的所有子协议成员
|
||||
var allSubProtocolIds = ProtocolManager.getAllSubProtocolIds(protocolId)
|
||||
.stream()
|
||||
.sorted((a, b) -> Short.compare(a, b))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (var subProtocolId : allSubProtocolIds) {
|
||||
var protocolRegistrationField = new CtField(classPool.get(IProtocolRegistration.class.getCanonicalName()), getProtocolRegistrationFieldNameByProtocolId(subProtocolId), enhanceClazz);
|
||||
constructorFiled.setModifiers(Modifier.PRIVATE);
|
||||
enhanceClazz.addField(protocolRegistrationField);
|
||||
}
|
||||
|
||||
// 定义类的构造器
|
||||
CtConstructor constructor = new CtConstructor(classPool.get(new String[]{Constructor.class.getCanonicalName()}), enhanceClazz);
|
||||
constructor.setBody("{this.constructor=$1;}");
|
||||
constructor.setModifiers(Modifier.PUBLIC);
|
||||
enhanceClazz.addConstructor(constructor);
|
||||
|
||||
// 定义类实现的接口方法
|
||||
CtMethod protocolIdMethod = new CtMethod(classPool.get(short.class.getCanonicalName()), "protocolId", null, enhanceClazz);
|
||||
protocolIdMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
|
||||
protocolIdMethod.setBody("{return " + registration.protocolId() + ";}");
|
||||
enhanceClazz.addMethod(protocolIdMethod);
|
||||
|
||||
CtMethod protocolConstructorMethod = new CtMethod(classPool.get(Constructor.class.getCanonicalName()), "protocolConstructor", null, enhanceClazz);
|
||||
protocolConstructorMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
|
||||
protocolConstructorMethod.setBody("{return this.constructor;}");
|
||||
enhanceClazz.addMethod(protocolConstructorMethod);
|
||||
|
||||
CtMethod moduleMethod = new CtMethod(classPool.get(byte.class.getCanonicalName()), "module", null, enhanceClazz);
|
||||
moduleMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
|
||||
moduleMethod.setBody("{return " + registration.module() + ";}");
|
||||
enhanceClazz.addMethod(moduleMethod);
|
||||
|
||||
CtMethod writeMethod = new CtMethod(classPool.get(void.class.getCanonicalName()), "write", classPool.get(new String[]{ByteBuf.class.getCanonicalName(), IPacket.class.getCanonicalName()}), enhanceClazz);
|
||||
writeMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
|
||||
writeMethod.setBody(writeMethodBody(registration));
|
||||
enhanceClazz.addMethod(writeMethod);
|
||||
|
||||
CtMethod readMethod = new CtMethod(classPool.get(Object.class.getCanonicalName()), "read", classPool.get(new String[]{ByteBuf.class.getCanonicalName()}), enhanceClazz);
|
||||
readMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
|
||||
readMethod.setBody(readMethodBody(registration));
|
||||
enhanceClazz.addMethod(readMethod);
|
||||
|
||||
// 释放缓存
|
||||
enhanceClazz.detach();
|
||||
|
||||
Class<?> resultClazz = enhanceClazz.toClass(IProtocolRegistration.class);
|
||||
Constructor<?> resultConstructor = resultClazz.getConstructor(Constructor.class);
|
||||
|
||||
return (IProtocolRegistration) resultConstructor.newInstance(registration.protocolConstructor());
|
||||
}
|
||||
|
||||
// see: ProtocolRegistration.write()
|
||||
private static String writeMethodBody(ProtocolRegistration registration) {
|
||||
short protocolId = registration.getId();
|
||||
Constructor<?> constructor = registration.getConstructor();
|
||||
Field[] fields = registration.getFields();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
|
||||
Class<?> packetClazz = constructor.getDeclaringClass();
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("{");
|
||||
builder.append(packetClazz.getCanonicalName() + " packet = (" + packetClazz.getCanonicalName() + ")$2;");
|
||||
builder.append("if(ByteBufUtils.writePacketFlag($1, packet)){")
|
||||
.append("return;}");
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
if (Modifier.isPublic(field.getModifiers())) {
|
||||
enhanceSerializer(fieldRegistration.serializer())
|
||||
.writeObject(builder, StringUtils.format("packet.{}", field.getName()), field, fieldRegistration);
|
||||
} else {
|
||||
enhanceSerializer(fieldRegistration.serializer())
|
||||
.writeObject(builder, StringUtils.format("packet.{}()", ReflectionUtils.fieldToGetMethod(packetClazz, field)), field, fieldRegistration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
// see: ProtocolRegistration.read()
|
||||
private static String readMethodBody(ProtocolRegistration registration) throws NoSuchMethodException {
|
||||
short protocolId = registration.getId();
|
||||
Constructor<?> constructor = registration.getConstructor();
|
||||
Field[] fields = registration.getFields();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("{");
|
||||
builder.append("if(!" + EnhanceUtils.byteBufUtilsReadBoolean + "){")
|
||||
.append("return null;}");
|
||||
Class<?> packetClazz = constructor.getDeclaringClass();
|
||||
builder.append(packetClazz.getCanonicalName() + " packet=new " + packetClazz.getCanonicalName() + "();");
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
String readObject = enhanceSerializer(fieldRegistration.serializer()).readObject(builder, field, fieldRegistration);
|
||||
|
||||
if (Modifier.isPublic(field.getModifiers())) {
|
||||
builder.append(StringUtils.format("packet.{}={};", field.getName(), readObject));
|
||||
} else {
|
||||
builder.append(StringUtils.format("packet.{}({});", ReflectionUtils.fieldToSetMethod(packetClazz, field), readObject));
|
||||
}
|
||||
}
|
||||
|
||||
builder.append("return packet;}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String getProtocolRegistrationFieldNameByProtocolId(short id) {
|
||||
return StringUtils.format("{}{}", StringUtils.uncapitalize(ProtocolRegistration.class.getSimpleName()), id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IProtocolRegistration {
|
||||
|
||||
short protocolId();
|
||||
|
||||
byte module();
|
||||
|
||||
Constructor<?> protocolConstructor();
|
||||
|
||||
Object read(ByteBuf buffer);
|
||||
|
||||
void write(ByteBuf buffer, IPacket packet);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration;
|
||||
|
||||
import com.zfoo.protocol.util.AssertionUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ProtocolModule {
|
||||
|
||||
public static final ProtocolModule DEFAULT_PROTOCOL_MODULE = new ProtocolModule((byte) 0, "default", "1.0.0");
|
||||
|
||||
private byte id;
|
||||
|
||||
private String name;
|
||||
/**
|
||||
* 1.xxx.xxx,将1.0.0转化为1000000
|
||||
*/
|
||||
private int version;
|
||||
|
||||
private transient int hash;
|
||||
|
||||
|
||||
public ProtocolModule(byte id, String name, String version) {
|
||||
if (id < 0) {
|
||||
throw new IllegalArgumentException(StringUtils.format("模块[{}]的id[{}]必须大于0", name, id));
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.version = versionStrToNum(version);
|
||||
this.perfectHash();
|
||||
}
|
||||
|
||||
public ProtocolModule(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static void assertVersion(String version) {
|
||||
if (!version.matches("[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}")) {
|
||||
throw new IllegalArgumentException(StringUtils
|
||||
.format("[version:{}] must like xxx.xxx.xxx", version));
|
||||
}
|
||||
}
|
||||
|
||||
public static int versionStrToNum(String version) {
|
||||
assertVersion(version);
|
||||
var splits = version.split("\\" + StringUtils.PERIOD);
|
||||
var versionNum = Integer.parseInt(splits[0]) * 1_000_000 + Integer.parseInt(splits[1]) * 1_000 + Integer.parseInt(splits[2]);
|
||||
|
||||
var newVersionStr = versionNumToStr(versionNum);
|
||||
AssertionUtils.isTrue(version.equals(newVersionStr), "版本号转换前[{}]和转换后不相等[{}]", version, newVersionStr);
|
||||
return versionNum;
|
||||
}
|
||||
|
||||
public static String versionNumToStr(int version) {
|
||||
var versionStr = version / 1_000_000 + StringUtils.PERIOD +
|
||||
version / 1_000 % 1_000 + StringUtils.PERIOD +
|
||||
version % 1_000;
|
||||
assertVersion(versionStr);
|
||||
return versionStr;
|
||||
}
|
||||
|
||||
public void perfectHash() {
|
||||
this.hash = id * 1_000_000 + this.version;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ProtocolModule module = (ProtocolModule) o;
|
||||
return id == module.id && version == module.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.format("[id:{}][name:{}][version:{}][hash:{}]", id, name, version, hash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
import com.zfoo.protocol.util.ReflectionUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* 协议必须为一个简单的POJO对象,必须有一个标识为private static final transient的PROTOCOL_ID号
|
||||
* 必须实现IPacket接口,返回的protocolId必须和PROTOCOL_ID号一致
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ProtocolRegistration implements IProtocolRegistration {
|
||||
|
||||
|
||||
private short id;
|
||||
private byte module;
|
||||
private Constructor<?> constructor;
|
||||
|
||||
private Field[] fields;
|
||||
|
||||
|
||||
/**
|
||||
* 所有的协议里的发送顺序都是按字段名称排序
|
||||
*/
|
||||
private IFieldRegistration[] fieldRegistrations;
|
||||
|
||||
public ProtocolRegistration() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public short protocolId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte module() {
|
||||
return module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Constructor<?> protocolConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object read(ByteBuf buffer) {
|
||||
if (!ByteBufUtils.readBoolean(buffer)) {
|
||||
return null;
|
||||
}
|
||||
Object object = ReflectionUtils.newInstance(constructor);
|
||||
|
||||
for (int i = 0, length = fields.length; i < length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration packetFieldRegistration = fieldRegistrations[i];
|
||||
ISerializer serializer = packetFieldRegistration.serializer();
|
||||
Object fieldValue = serializer.readObject(buffer, packetFieldRegistration);
|
||||
ReflectionUtils.setField(field, object, fieldValue);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, IPacket packet) {
|
||||
if (packet == null) {
|
||||
ByteBufUtils.writeBoolean(buffer, false);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBufUtils.writeBoolean(buffer, true);
|
||||
|
||||
for (int i = 0, length = fields.length; i < length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration packetFieldRegistration = fieldRegistrations[i];
|
||||
ISerializer serializer = packetFieldRegistration.serializer();
|
||||
Object fieldValue = ReflectionUtils.getField(field, packet);
|
||||
serializer.writeObject(buffer, fieldValue, packetFieldRegistration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public short getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(short id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public byte getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public void setModule(byte module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public Field[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void setFields(Field[] fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public IFieldRegistration[] getFieldRegistrations() {
|
||||
return fieldRegistrations;
|
||||
}
|
||||
|
||||
public void setFieldRegistrations(IFieldRegistration[] fieldRegistrations) {
|
||||
this.fieldRegistrations = fieldRegistrations;
|
||||
}
|
||||
|
||||
public Constructor<?> getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
public void setConstructor(Constructor<?> constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ArraySerializer;
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ArrayField implements IFieldRegistration {
|
||||
|
||||
private IFieldRegistration arrayElementRegistration;
|
||||
private Field field;
|
||||
|
||||
public static ArrayField valueOf(Field field, IFieldRegistration arrayElementRegistration) {
|
||||
ArrayField arrayField = new ArrayField();
|
||||
arrayField.field = field;
|
||||
arrayField.arrayElementRegistration = arrayElementRegistration;
|
||||
return arrayField;
|
||||
}
|
||||
|
||||
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ISerializer serializer() {
|
||||
return ArraySerializer.getInstance();
|
||||
}
|
||||
|
||||
public IFieldRegistration getArrayElementRegistration() {
|
||||
return arrayElementRegistration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
|
||||
/**
|
||||
* 一个包里所包含的变量还有这个变量的序列化器
|
||||
* 描述boolean,byte,short,int,long,float,double,char,String等基本序列化器
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class BaseField implements IFieldRegistration {
|
||||
|
||||
private ISerializer serializer;
|
||||
|
||||
public static BaseField valueOf(ISerializer serializer) {
|
||||
BaseField packetField = new BaseField();
|
||||
packetField.serializer = serializer;
|
||||
return packetField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISerializer serializer() {
|
||||
return serializer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
|
||||
/**
|
||||
* 标记性接口,所有协议里描述变量都要实现这个接口
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IFieldRegistration {
|
||||
|
||||
ISerializer serializer();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
import com.zfoo.protocol.serializer.ListSerializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ListField implements IFieldRegistration {
|
||||
|
||||
private IFieldRegistration listElementRegistration;
|
||||
private Type type;
|
||||
|
||||
public static ListField valueOf(IFieldRegistration listElementRegistration, Type type) {
|
||||
ListField listField = new ListField();
|
||||
listField.listElementRegistration = listElementRegistration;
|
||||
listField.type = type;
|
||||
return listField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISerializer serializer() {
|
||||
return ListSerializer.getInstance();
|
||||
}
|
||||
|
||||
public IFieldRegistration getListElementRegistration() {
|
||||
return listElementRegistration;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
import com.zfoo.protocol.serializer.MapSerializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class MapField implements IFieldRegistration {
|
||||
|
||||
private IFieldRegistration mapKeyRegistration;
|
||||
private IFieldRegistration mapValueRegistration;
|
||||
|
||||
private Type type;
|
||||
|
||||
public static MapField valueOf(IFieldRegistration mapKeyRegistration, IFieldRegistration mapValueRegistration, Type type) {
|
||||
MapField mapField = new MapField();
|
||||
mapField.mapKeyRegistration = mapKeyRegistration;
|
||||
mapField.mapValueRegistration = mapValueRegistration;
|
||||
mapField.type = type;
|
||||
return mapField;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ISerializer serializer() {
|
||||
return MapSerializer.getInstance();
|
||||
}
|
||||
|
||||
public IFieldRegistration getMapKeyRegistration() {
|
||||
return mapKeyRegistration;
|
||||
}
|
||||
|
||||
public IFieldRegistration getMapValueRegistration() {
|
||||
return mapValueRegistration;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
import com.zfoo.protocol.serializer.ObjectProtocolSerializer;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ObjectProtocolField implements IFieldRegistration {
|
||||
|
||||
/**
|
||||
* 协议序列号是ProtocolRegistration的id
|
||||
*/
|
||||
private short protocolId;
|
||||
|
||||
public static ObjectProtocolField valueOf(short protocolId) {
|
||||
ObjectProtocolField objectProtocolField = new ObjectProtocolField();
|
||||
objectProtocolField.protocolId = protocolId;
|
||||
return objectProtocolField;
|
||||
}
|
||||
|
||||
public short getProtocolId() {
|
||||
return protocolId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISerializer serializer() {
|
||||
return ObjectProtocolSerializer.getInstance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.registration.field;
|
||||
|
||||
import com.zfoo.protocol.serializer.ISerializer;
|
||||
import com.zfoo.protocol.serializer.SetSerializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class SetField implements IFieldRegistration {
|
||||
|
||||
private IFieldRegistration setElementRegistration;
|
||||
private Type type;
|
||||
|
||||
public static SetField valueOf(IFieldRegistration listElementRegistration, Type type) {
|
||||
SetField setField = new SetField();
|
||||
setField.setElementRegistration = listElementRegistration;
|
||||
setField.type = type;
|
||||
return setField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISerializer serializer() {
|
||||
return SetSerializer.getInstance();
|
||||
}
|
||||
|
||||
public IFieldRegistration getSetElementRegistration() {
|
||||
return setElementRegistration;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.ArrayField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ArraySerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final ArraySerializer SERIALIZER = new ArraySerializer();
|
||||
|
||||
private ArraySerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static ArraySerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
|
||||
int length = Array.getLength(object);
|
||||
if (length == 0) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBufUtils.writeInt(buffer, length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object element = Array.get(object, i);
|
||||
arrayField.getArrayElementRegistration().serializer().writeObject(buffer, element, arrayField.getArrayElementRegistration());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
var length = ByteBufUtils.readInt(buffer);
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
if (length <= 0) {
|
||||
return Array.newInstance(arrayField.getField().getType().getComponentType(), 0);
|
||||
}
|
||||
|
||||
Object array = Array.newInstance(arrayField.getField().getType().getComponentType(), length);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
Object value = arrayField.getArrayElementRegistration().serializer().readObject(buffer, arrayField.getArrayElementRegistration());
|
||||
Array.set(array, i, value);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class BooleanSerializer implements ISerializer {
|
||||
|
||||
private static final BooleanSerializer SERIALIZER = new BooleanSerializer();
|
||||
|
||||
private BooleanSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static BooleanSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeBoolean(buffer, Boolean.FALSE);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeBoolean(buffer, (Boolean) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readBoolean(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ByteSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final ByteSerializer SERIALIZER = new ByteSerializer();
|
||||
|
||||
private ByteSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static ByteSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeByte(buffer, (byte) 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeByte(buffer, (Byte) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readByte(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CharSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final CharSerializer SERIALIZER = new CharSerializer();
|
||||
|
||||
private CharSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static CharSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeChar(buffer, Character.MIN_VALUE);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeChar(buffer, (Character) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readChar(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class DoubleSerializer implements ISerializer {
|
||||
|
||||
private static final DoubleSerializer SERIALIZER = new DoubleSerializer();
|
||||
|
||||
private DoubleSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static DoubleSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeDouble(buffer, 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeDouble(buffer, (Double) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readDouble(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class FloatSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final FloatSerializer SERIALIZER = new FloatSerializer();
|
||||
|
||||
private FloatSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static FloatSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeFloat(buffer, 0F);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeFloat(buffer, (Float) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readFloat(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateUtils {
|
||||
|
||||
public static AtomicInteger index = new AtomicInteger();
|
||||
|
||||
public static StringBuilder addTab(StringBuilder builder, int deep) {
|
||||
builder.append(TAB.repeat(Math.max(0, deep)));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
index = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface ISerializer {
|
||||
|
||||
void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration);
|
||||
|
||||
Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class IntSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final IntSerializer SERIALIZER = new IntSerializer();
|
||||
|
||||
private IntSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static IntSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeInt(buffer, (Integer) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readInt(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ListField;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ListSerializer implements ISerializer {
|
||||
|
||||
private static final ListSerializer SERIALIZER = new ListSerializer();
|
||||
|
||||
|
||||
private ListSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static ListSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
List<?> list = (List<?>) object;
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
|
||||
int size = list.size();
|
||||
if (size == 0) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeInt(buffer, size);
|
||||
|
||||
for (Object element : list) {
|
||||
listField.getListElementRegistration().serializer().writeObject(buffer, element, listField.getListElementRegistration());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
int size = ByteBufUtils.readInt(buffer);
|
||||
if (size <= 0) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
List<Object> list = new ArrayList<>(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Object value = listField.getListElementRegistration().serializer().readObject(buffer, listField.getListElementRegistration());
|
||||
list.add(value);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class LongSerializer implements ISerializer {
|
||||
|
||||
private static final LongSerializer SERIALIZER = new LongSerializer();
|
||||
|
||||
private LongSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static LongSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeLong(buffer, 0L);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeLong(buffer, (Long) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readLong(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.MapField;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class MapSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final MapSerializer SERIALIZER = new MapSerializer();
|
||||
|
||||
|
||||
private MapSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static MapSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Map<?, ?> map = (Map<?, ?>) object;
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
|
||||
int size = map.size();
|
||||
if (size == 0) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeInt(buffer, size);
|
||||
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
mapField.getMapKeyRegistration().serializer().writeObject(buffer, entry.getKey(), mapField.getMapKeyRegistration());
|
||||
|
||||
mapField.getMapValueRegistration().serializer().writeObject(buffer, entry.getValue(), mapField.getMapValueRegistration());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
int size = ByteBufUtils.readInt(buffer);
|
||||
if (size <= 0) {
|
||||
return Collections.EMPTY_MAP;
|
||||
}
|
||||
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
Map<Object, Object> map = new HashMap<>(CollectionUtils.comfortableCapacity(size));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Object key = mapField.getMapKeyRegistration().serializer().readObject(buffer, mapField.getMapKeyRegistration());
|
||||
|
||||
Object value = mapField.getMapValueRegistration().serializer().readObject(buffer, mapField.getMapValueRegistration());
|
||||
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.IPacket;
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* 只要是protocol都是使用FieldSerializer
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ObjectProtocolSerializer implements ISerializer {
|
||||
|
||||
private static final ObjectProtocolSerializer SERIALIZER = new ObjectProtocolSerializer();
|
||||
|
||||
private ObjectProtocolSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static ObjectProtocolSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param buffer ByteBuf
|
||||
* @param object 必须继承IPacket接口
|
||||
*/
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
IProtocolRegistration protocol = ProtocolManager.getProtocol(objectProtocolField.getProtocolId());
|
||||
protocol.write(buffer, (IPacket) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
IProtocolRegistration protocol = ProtocolManager.getProtocol(objectProtocolField.getProtocolId());
|
||||
return protocol.read(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.SetField;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class SetSerializer implements ISerializer {
|
||||
|
||||
private static final SetSerializer SERIALIZER = new SetSerializer();
|
||||
|
||||
|
||||
private SetSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static SetSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<?> set = (Set<?>) object;
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
|
||||
int size = set.size();
|
||||
if (size == 0) {
|
||||
ByteBufUtils.writeInt(buffer, 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeInt(buffer, size);
|
||||
|
||||
for (Object element : set) {
|
||||
setField.getSetElementRegistration().serializer().writeObject(buffer, element, setField.getSetElementRegistration());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
int size = ByteBufUtils.readInt(buffer);
|
||||
if (size <= 0) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
Set<Object> set = new HashSet<>(CollectionUtils.comfortableCapacity(size));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
Object value = setField.getSetElementRegistration().serializer().readObject(buffer, setField.getSetElementRegistration());
|
||||
set.add(value);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class ShortSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final ShortSerializer SERIALIZER = new ShortSerializer();
|
||||
|
||||
private ShortSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static ShortSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
if (object == null) {
|
||||
ByteBufUtils.writeShort(buffer, (short) 0);
|
||||
return;
|
||||
}
|
||||
ByteBufUtils.writeShort(buffer, (Short) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readShort(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer;
|
||||
|
||||
import com.zfoo.protocol.buffer.ByteBufUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class StringSerializer implements ISerializer {
|
||||
|
||||
|
||||
private static final StringSerializer SERIALIZER = new StringSerializer();
|
||||
|
||||
private StringSerializer() {
|
||||
|
||||
}
|
||||
|
||||
public static StringSerializer getInstance() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ByteBuf buffer, Object object, IFieldRegistration fieldRegistration) {
|
||||
ByteBufUtils.writeString(buffer, (String) object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(ByteBuf buffer, IFieldRegistration fieldRegistration) {
|
||||
return ByteBufUtils.readString(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.ArrayField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsArraySerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if (({} == null) || ({}.Length == 0))", objectStr, objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("buffer.WriteInt(0);").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("else").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.WriteInt({}.Length);", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
String length = "length" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {} = {}.Length;", length, objectStr)).append(LS);
|
||||
|
||||
String i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++)", i, i, length, i)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
String element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("{} {} = {}[{}];", GenerateCsUtils.toCsClassName(arrayField.getField().getType().getComponentType().getSimpleName()), element, objectStr, i)).append(LS);
|
||||
|
||||
GenerateCsUtils.csSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
var arrayField = (ArrayField) fieldRegistration;
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCsUtils.toCsClassName(arrayField.getField().getType().getComponentType().getSimpleName());
|
||||
|
||||
var i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("int {} = buffer.ReadInt();", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("{}[] {} = new {}[{}];", typeName, result, typeName, size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0)", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++)", i, i, size, i)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
var readObject = GenerateCsUtils.csSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}[{}] = {};", result, i, readObject));
|
||||
builder.append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsBooleanSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteBool({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("bool {} = buffer.ReadBool();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsByteSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteByte({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byte {} = buffer.ReadByte();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsCharSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteChar({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("char {} = buffer.ReadChar();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsDoubleSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteDouble({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("double {} = buffer.ReadDouble();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsFloatSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteFloat({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("float {} = buffer.ReadFloat();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsIntSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteInt({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("int {} = buffer.ReadInt();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ListField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsListSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} == null)", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("buffer.WriteInt(0);").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("else").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.WriteInt({}.Count);", objectStr)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
String length = "length" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {} = {}.Count;", length, objectStr)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
String i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++)", i, i, length, i)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
String element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("var {} = {}[{}];", element, objectStr, i)).append(LS);
|
||||
|
||||
GenerateCsUtils.csSerializer(listField.getListElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, listField.getListElementRegistration());
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
var listField = (ListField) fieldRegistration;
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCsUtils.toCsClassName(listField.getType().toString());
|
||||
|
||||
var i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
|
||||
builder.append(StringUtils.format("int {} = buffer.ReadInt();", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("var {} = new {}({});", result, typeName, size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0)", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++)", i, i, size, i)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
var readObject = GenerateCsUtils.csSerializer(listField.getListElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, listField.getListElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.Add({});", result, readObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsLongSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteLong({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("long {} = buffer.ReadLong();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.MapField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsMapSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if (({} == null) || ({}.Count == 0))", objectStr, objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("buffer.WriteInt(0);").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("else").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.WriteInt({}.Count);", objectStr)).append(LS);
|
||||
|
||||
|
||||
String i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("foreach (var {} in {})", i, objectStr)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
String key = "keyElement" + GenerateUtils.index.getAndIncrement();
|
||||
String value = "valueElement" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("var {} = {}.Key;", key, i)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("var {} = {}.Value;", value, i)).append(LS);
|
||||
|
||||
GenerateCsUtils.csSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.writeObject(builder, key, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
GenerateCsUtils.csSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.writeObject(builder, value, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCsUtils.toCsClassName(mapField.getType().toString());
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
String size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {} = buffer.ReadInt();", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("var {} = new {}({});", result, typeName, size)).append(LS);
|
||||
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0)", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
String i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (var {} = 0; {} < {}; {}++)", i, i, size, i)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
String keyObject = GenerateCsUtils.csSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
|
||||
|
||||
String valueObject = GenerateCsUtils.csSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
|
||||
builder.append(StringUtils.format("{}[{}] = {};", result, keyObject, valueObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsObjectProtocolSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("ProtocolManager.GetProtocol({}).Write(buffer, {});", objectProtocolField.getProtocolId(), objectStr))
|
||||
.append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("{} {} = ({}) ProtocolManager.GetProtocol({}).Read(buffer);", getProtocolSimpleName(objectProtocolField), result, getProtocolSimpleName(objectProtocolField), objectProtocolField.getProtocolId()))
|
||||
.append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getProtocolSimpleName(ObjectProtocolField objectProtocolField) {
|
||||
return ProtocolManager.getProtocol(objectProtocolField.getProtocolId()).protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.SetField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsSetSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} == null)", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("buffer.WriteInt(0);").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("else").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("buffer.WriteInt({}.Count);", objectStr)).append(LS);
|
||||
|
||||
String element = "i" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("foreach (var {} in {})", element, objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateCsUtils.csSerializer(setField.getSetElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, setField.getSetElementRegistration());
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
var typeName = GenerateCsUtils.toCsClassName(setField.getType().toString());
|
||||
|
||||
var i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("int {} = buffer.ReadInt();", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
// unity里不支持HashSet的初始化大小
|
||||
// builder.append("var " + result + " = new " + typeName + "(" + size + ");" + LS);
|
||||
builder.append(StringUtils.format("var {} = new {}();", result, typeName)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0)", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (int {} = 0; {} < {}; {}++)", i, i, size, i)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("{").append(LS);
|
||||
|
||||
var readObject = GenerateCsUtils.csSerializer(setField.getSetElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, setField.getSetElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.Add({});", result, readObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsShortSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteShort({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("short {} = buffer.ReadShort();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class CsStringSerializer implements ICsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("buffer.WriteString({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("string {} = buffer.ReadString();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.generate.GenerateProtocolDocument;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.model.Pair;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateCsUtils {
|
||||
|
||||
private static final String PROTOCOL_OUTPUT_ROOT_PATH = "CsProtocol/";
|
||||
|
||||
private static Map<ISerializer, ICsSerializer> csSerializerMap;
|
||||
|
||||
public static ICsSerializer csSerializer(ISerializer serializer) {
|
||||
return csSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
FileUtils.deleteFile(new File(PROTOCOL_OUTPUT_ROOT_PATH));
|
||||
FileUtils.createDirectory(PROTOCOL_OUTPUT_ROOT_PATH);
|
||||
|
||||
csSerializerMap = new HashMap<>();
|
||||
csSerializerMap.put(BooleanSerializer.getInstance(), new CsBooleanSerializer());
|
||||
csSerializerMap.put(ByteSerializer.getInstance(), new CsByteSerializer());
|
||||
csSerializerMap.put(ShortSerializer.getInstance(), new CsShortSerializer());
|
||||
csSerializerMap.put(IntSerializer.getInstance(), new CsIntSerializer());
|
||||
csSerializerMap.put(LongSerializer.getInstance(), new CsLongSerializer());
|
||||
csSerializerMap.put(FloatSerializer.getInstance(), new CsFloatSerializer());
|
||||
csSerializerMap.put(DoubleSerializer.getInstance(), new CsDoubleSerializer());
|
||||
csSerializerMap.put(CharSerializer.getInstance(), new CsCharSerializer());
|
||||
csSerializerMap.put(StringSerializer.getInstance(), new CsStringSerializer());
|
||||
csSerializerMap.put(ArraySerializer.getInstance(), new CsArraySerializer());
|
||||
csSerializerMap.put(ListSerializer.getInstance(), new CsListSerializer());
|
||||
csSerializerMap.put(SetSerializer.getInstance(), new CsSetSerializer());
|
||||
csSerializerMap.put(MapSerializer.getInstance(), new CsMapSerializer());
|
||||
csSerializerMap.put(ObjectProtocolSerializer.getInstance(), new CsObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
csSerializerMap = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成协议依赖的工具类
|
||||
*/
|
||||
public static void createProtocolManager() throws IOException {
|
||||
var list = List.of("cs/ProtocolManager.cs"
|
||||
, "cs/IProtocolRegistration.cs"
|
||||
, "cs/IPacket.cs"
|
||||
, "cs/Buffer/ByteBuffer.cs"
|
||||
, "cs/Buffer/LittleEndianByteBuffer.cs"
|
||||
, "cs/Buffer/BigEndianByteBuffer.cs");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}{}", PROTOCOL_OUTPUT_ROOT_PATH, StringUtils.substringAfterFirst(fileName, "cs/")));
|
||||
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成协议类
|
||||
*/
|
||||
public static void createCsProtocolFile(ProtocolRegistration registration) {
|
||||
GenerateUtils.index.set(0);
|
||||
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
|
||||
|
||||
var csBuilder = new StringBuilder();
|
||||
csBuilder.append("using System;").append(LS);
|
||||
csBuilder.append("using System.Collections.Generic;").append(LS);
|
||||
csBuilder.append("using CsProtocol.Buffer;").append(LS).append(LS);
|
||||
csBuilder.append("namespace CsProtocol").append(LS);
|
||||
csBuilder.append("{").append(LS);
|
||||
|
||||
|
||||
// protocol object
|
||||
csBuilder.append(protocolClass(registration));
|
||||
|
||||
csBuilder.append(TAB).append(StringUtils.format("public class {}Registration : IProtocolRegistration", protocolClazzName)).append(LS);
|
||||
csBuilder.append(TAB).append("{").append(LS);
|
||||
|
||||
// ProtocolId method
|
||||
csBuilder.append(packetProtocolId(registration));
|
||||
|
||||
// writeObject method
|
||||
csBuilder.append(writeObject(registration));
|
||||
|
||||
// readObject method
|
||||
csBuilder.append(readObject(registration));
|
||||
|
||||
csBuilder.append(TAB).append("}").append(LS);
|
||||
csBuilder.append("}").append(LS);
|
||||
|
||||
var protocolOutputPath = StringUtils.format("{}{}/{}.cs"
|
||||
, PROTOCOL_OUTPUT_ROOT_PATH
|
||||
, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId)
|
||||
, protocolClazzName);
|
||||
FileUtils.writeStringToFile(new File(protocolOutputPath), csBuilder.toString());
|
||||
}
|
||||
|
||||
|
||||
public static String toCsClassName(String typeName) {
|
||||
typeName = typeName.replaceAll("java.util.|java.lang.", StringUtils.EMPTY);
|
||||
typeName = typeName.replaceAll("com\\.[a-zA-Z0-9_.]*\\.", StringUtils.EMPTY);
|
||||
|
||||
// CSharp不适用基础类型的泛型,会影响性能
|
||||
switch (typeName) {
|
||||
case "boolean":
|
||||
case "Boolean":
|
||||
typeName = "bool";
|
||||
return typeName;
|
||||
case "Byte":
|
||||
typeName = "byte";
|
||||
return typeName;
|
||||
case "Short":
|
||||
typeName = "short";
|
||||
return typeName;
|
||||
case "Integer":
|
||||
typeName = "int";
|
||||
return typeName;
|
||||
case "Long":
|
||||
typeName = "long";
|
||||
return typeName;
|
||||
case "Float":
|
||||
typeName = "float";
|
||||
return typeName;
|
||||
case "Double":
|
||||
typeName = "double";
|
||||
return typeName;
|
||||
case "Character":
|
||||
typeName = "char";
|
||||
return typeName;
|
||||
case "String":
|
||||
typeName = "string";
|
||||
return typeName;
|
||||
default:
|
||||
}
|
||||
|
||||
// 将boolean转为bool
|
||||
typeName = typeName.replace(" boolean ", " bool ");
|
||||
typeName = typeName.replace(" Boolean ", " bool ");
|
||||
typeName = typeName.replaceAll("[B|b]oolean\\[", "bool[");
|
||||
typeName = typeName.replace("<Boolean", "<bool");
|
||||
typeName = typeName.replace("Boolean>", "bool>");
|
||||
|
||||
// 将Byte转为byte
|
||||
typeName = typeName.replace(" Byte ", " byte ");
|
||||
typeName = typeName.replace("Byte[", "byte[");
|
||||
typeName = typeName.replace("Byte>", "byte>");
|
||||
typeName = typeName.replace("<Byte", "<byte");
|
||||
|
||||
// 将Short转为short
|
||||
typeName = typeName.replace(" Short ", " short ");
|
||||
typeName = typeName.replace("Short[", "short[");
|
||||
typeName = typeName.replace("Short>", "short>");
|
||||
typeName = typeName.replace("<Short", "<short");
|
||||
|
||||
// 将Integer转为int
|
||||
typeName = typeName.replace(" Integer ", " int ");
|
||||
typeName = typeName.replace("Integer[", "int[");
|
||||
typeName = typeName.replace("Integer>", "int>");
|
||||
typeName = typeName.replace("<Integer", "<int");
|
||||
|
||||
|
||||
// 将Long转为long
|
||||
typeName = typeName.replace(" Long ", " long ");
|
||||
typeName = typeName.replace("Long[", "long[");
|
||||
typeName = typeName.replace("Long>", "long>");
|
||||
typeName = typeName.replace("<Long", "<long");
|
||||
|
||||
// 将Float转为float
|
||||
typeName = typeName.replace(" Float ", " float ");
|
||||
typeName = typeName.replace("Float[", "float[");
|
||||
typeName = typeName.replace("Float>", "float>");
|
||||
typeName = typeName.replace("<Float", "<float");
|
||||
|
||||
// 将Double转为double
|
||||
typeName = typeName.replace(" Double ", " double ");
|
||||
typeName = typeName.replace("Double[", "double[");
|
||||
typeName = typeName.replace("Double>", "double>");
|
||||
typeName = typeName.replace("<Double", "<double");
|
||||
|
||||
// 将Character转为Char
|
||||
typeName = typeName.replace(" Character ", " char ");
|
||||
typeName = typeName.replace("Character[", "char[");
|
||||
typeName = typeName.replace("Character>", "char>");
|
||||
typeName = typeName.replace("<Character", "<char");
|
||||
|
||||
// 将String转为string
|
||||
typeName = typeName.replace("String ", "string ");
|
||||
typeName = typeName.replace("String[", "string[");
|
||||
typeName = typeName.replace("String>", "string>");
|
||||
typeName = typeName.replace("<String", "<string");
|
||||
|
||||
// 将Map转为Dictionary
|
||||
typeName = typeName.replace("Map<", "Dictionary<");
|
||||
|
||||
// 将Set转为HashSet
|
||||
typeName = typeName.replace("Set<", "HashSet<");
|
||||
|
||||
// 将private转为public
|
||||
typeName = typeName.replace(" private ", " public ");
|
||||
|
||||
return typeName;
|
||||
}
|
||||
|
||||
private static String protocolClass(ProtocolRegistration registration) {
|
||||
short protocolId = registration.getId();
|
||||
Field[] fields = registration.getFields();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
|
||||
var docTitle = protocolDocument.getKey();
|
||||
var docFieldMap = protocolDocument.getValue();
|
||||
|
||||
var csBuilder = new StringBuilder();
|
||||
if (!StringUtils.isBlank(docTitle)) {
|
||||
Arrays.stream(docTitle.split(LS)).forEach(it -> csBuilder.append(TAB).append(it).append(LS));
|
||||
}
|
||||
csBuilder.append(TAB)
|
||||
.append(StringUtils.format("public class {} : IPacket", protocolClazzName))
|
||||
.append(LS);
|
||||
csBuilder.append(TAB).append("{").append(LS);
|
||||
|
||||
// 协议的属性生成
|
||||
var filedList = new ArrayList<Pair<String, String>>();
|
||||
for (var field : fields) {
|
||||
var propertyType = toCsClassName(field.getGenericType().getTypeName());
|
||||
var propertyName = field.getName();
|
||||
|
||||
var propertyFullName = StringUtils.format("public {} {};", propertyType, propertyName);
|
||||
// 生成注释
|
||||
var doc = docFieldMap.get(propertyName);
|
||||
if (!StringUtils.isBlank(doc)) {
|
||||
Arrays.stream(doc.split(LS)).forEach(it -> csBuilder.append(TAB + TAB).append(it).append(LS));
|
||||
}
|
||||
|
||||
csBuilder.append(TAB + TAB).append(propertyFullName).append(LS);
|
||||
filedList.add(new Pair<>(propertyType, propertyName));
|
||||
}
|
||||
|
||||
csBuilder.append(LS);
|
||||
|
||||
// ValueOf()方法
|
||||
var valueOfParams = filedList.stream()
|
||||
.map(it -> StringUtils.format("{} {}", it.getKey(), it.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
csBuilder.append(TAB + TAB)
|
||||
.append(StringUtils.format("public static {} ValueOf({})", protocolClazzName, StringUtils.joinWith(StringUtils.COMMA + " ", valueOfParams.toArray())))
|
||||
.append(LS);
|
||||
|
||||
csBuilder.append(TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB)
|
||||
.append(StringUtils.format("var packet = new {}();", protocolClazzName))
|
||||
.append(LS);
|
||||
filedList.forEach(it -> csBuilder.append(TAB + TAB + TAB).append(StringUtils.format("packet.{} = {};", it.getValue(), it.getValue())).append(LS));
|
||||
csBuilder.append(TAB + TAB + TAB).append("return packet;").append(LS);
|
||||
csBuilder.append(TAB + TAB).append("}").append(LS);
|
||||
csBuilder.append(LS).append(LS);
|
||||
|
||||
// ProtocolId()方法
|
||||
csBuilder.append(TAB + TAB).append("public short ProtocolId()").append(LS);
|
||||
csBuilder.append(TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append(StringUtils.format("return {};", registration.protocolId())).append(LS);
|
||||
csBuilder.append(TAB + TAB).append("}").append(LS);
|
||||
csBuilder.append(TAB).append("}").append(LS);
|
||||
csBuilder.append(LS).append(LS);
|
||||
|
||||
return csBuilder.toString();
|
||||
}
|
||||
|
||||
private static String packetProtocolId(ProtocolRegistration registration) {
|
||||
var csBuilder = new StringBuilder();
|
||||
csBuilder.append(TAB + TAB).append("public short ProtocolId()").append(LS);
|
||||
csBuilder.append(TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append(StringUtils.format("return {};", registration.protocolId())).append(LS);
|
||||
csBuilder.append(TAB + TAB).append("}");
|
||||
csBuilder.append(LS).append(LS);
|
||||
return csBuilder.toString();
|
||||
}
|
||||
|
||||
private static String writeObject(ProtocolRegistration registration) {
|
||||
Field[] fields = registration.getFields();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var csBuilder = new StringBuilder();
|
||||
csBuilder.append(TAB + TAB).append("public void Write(ByteBuffer buffer, IPacket packet)").append(LS);
|
||||
csBuilder.append(TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append("if (packet == null)").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB + TAB).append("buffer.WriteBool(false);").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB + TAB).append("return;").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB + "}").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append("buffer.WriteBool(true);").append(LS);
|
||||
|
||||
csBuilder.append(TAB + TAB + TAB)
|
||||
.append(StringUtils.format("{} message = ({}) packet;", protocolClazzName, protocolClazzName))
|
||||
.append(LS);
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
csSerializer(fieldRegistration.serializer()).writeObject(csBuilder, "message." + field.getName(), 3, field, fieldRegistration);
|
||||
}
|
||||
|
||||
csBuilder.append(TAB + TAB + "}").append(LS).append(LS);
|
||||
return csBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String readObject(ProtocolRegistration registration) {
|
||||
Field[] fields = registration.getFields();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var csBuilder = new StringBuilder();
|
||||
csBuilder.append(TAB + TAB).append("public IPacket Read(ByteBuffer buffer)").append(LS);
|
||||
csBuilder.append(TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append("if (!buffer.ReadBool())").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append("{").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB + TAB).append("return null;").append(LS);
|
||||
csBuilder.append(TAB + TAB + TAB).append("}").append(LS);
|
||||
|
||||
csBuilder.append(TAB + TAB + TAB)
|
||||
.append(StringUtils.format("{} packet = new {}();", protocolClazzName, protocolClazzName))
|
||||
.append(LS);
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
String readObject = csSerializer(fieldRegistration.serializer()).readObject(csBuilder, 3, field, fieldRegistration);
|
||||
csBuilder.append(TAB + TAB + TAB)
|
||||
.append(StringUtils.format("packet.{} = {};", field.getName(), readObject))
|
||||
.append(LS);
|
||||
}
|
||||
|
||||
csBuilder.append(TAB + TAB + TAB).append("return packet;").append(LS);
|
||||
|
||||
csBuilder.append(TAB + TAB).append("}").append(LS);
|
||||
|
||||
return csBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.cs;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface ICsSerializer {
|
||||
|
||||
void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.ArrayField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceArraySerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
var arrayField = (ArrayField) fieldRegistration;
|
||||
var arrayName = getArrayClassName(arrayField);
|
||||
|
||||
switch (arrayName) {
|
||||
case "boolean":
|
||||
builder.append(StringUtils.format("{}.writeBooleanArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Boolean":
|
||||
builder.append(StringUtils.format("{}.writeBooleanBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "byte":
|
||||
builder.append(StringUtils.format("{}.writeByteArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Byte":
|
||||
builder.append(StringUtils.format("{}.writeByteBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "short":
|
||||
builder.append(StringUtils.format("{}.writeShortArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Short":
|
||||
builder.append(StringUtils.format("{}.writeShortBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "int":
|
||||
builder.append(StringUtils.format("{}.writeIntArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Integer":
|
||||
builder.append(StringUtils.format("{}.writeIntBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "long":
|
||||
builder.append(StringUtils.format("{}.writeLongArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Long":
|
||||
builder.append(StringUtils.format("{}.writeLongBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "float":
|
||||
builder.append(StringUtils.format("{}.writeFloatArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Float":
|
||||
builder.append(StringUtils.format("{}.writeFloatBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "double":
|
||||
builder.append(StringUtils.format("{}.writeDoubleArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Double":
|
||||
builder.append(StringUtils.format("{}.writeDoubleBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "String":
|
||||
builder.append(StringUtils.format("{}.writeStringArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "char":
|
||||
builder.append(StringUtils.format("{}.writeCharArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "Character":
|
||||
builder.append(StringUtils.format("{}.writeCharBoxArray($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
default:
|
||||
}
|
||||
|
||||
var array = "array" + GenerateUtils.index.getAndIncrement();
|
||||
var length = "length" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("{}[] {} = {};", arrayName, array, objectStr));
|
||||
builder.append(StringUtils.format("int {} = ArrayUtils.length({});", length, array));
|
||||
builder.append(StringUtils.format("{}.writeInt($1,{});", EnhanceUtils.byteBufUtils, length));
|
||||
|
||||
var i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for(int {}=0; {}<{}; {}++){", i, i, length, i));
|
||||
|
||||
var element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("{} {} = {}[{}];", arrayName, element, array, i));
|
||||
|
||||
EnhanceUtils.enhanceSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, arrayField.getField(), arrayField.getArrayElementRegistration());
|
||||
|
||||
builder.append("}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var arrayField = (ArrayField) fieldRegistration;
|
||||
var arrayName = getArrayClassName(arrayField);
|
||||
|
||||
var array = "array" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
switch (arrayName) {
|
||||
case "boolean":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readBooleanArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Boolean":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readBooleanBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "byte":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readByteArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Byte":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readByteBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "short":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readShortArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Short":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readShortBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "int":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readIntArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Integer":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readIntBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "long":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readLongArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Long":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readLongBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "float":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readFloatArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Float":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readFloatBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "double":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readDoubleArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Double":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readDoubleBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "String":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readStringArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "char":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readCharArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
case "Character":
|
||||
builder.append(StringUtils.format("{}[] {} = {}.readCharBoxArray($1);", arrayName, array, EnhanceUtils.byteBufUtils));
|
||||
return array;
|
||||
default:
|
||||
}
|
||||
|
||||
var length = "length" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {} = {}.readInt($1);", length, EnhanceUtils.byteBufUtils));
|
||||
|
||||
builder.append(StringUtils.format("{}[] {} = new {}[{}];", arrayName, array, arrayName, length));
|
||||
|
||||
var i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for(int {}=0; {} < {}; {}++){", i, i, length, i));
|
||||
var readObject = EnhanceUtils.enhanceSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, arrayField.getField(), arrayField.getArrayElementRegistration());
|
||||
builder.append(StringUtils.format("{}[{}] = {};}", array, i, readObject));
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
private String getArrayClassName(ArrayField arrayField) {
|
||||
// 去掉包装类型的前缀java.lang
|
||||
return arrayField.getField().getType().getComponentType().getCanonicalName().replaceFirst("java.lang.", StringUtils.EMPTY);
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceBooleanSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeBoolean($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeBooleanBox($1, (Boolean){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("boolean {} = {}.readBoolean($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Boolean {} = {}.readBooleanBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceByteSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeByte($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeByteBox($1, (Byte){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("byte {} = {}.readByte($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Byte {} = {}.readByteBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceCharSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeChar($1,{});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeCharBox($1, (Character){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("char {} = {}.readChar($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Character {} = {}.readCharBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceDoubleSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeDouble($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeDoubleBox($1, (Double){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("double {} = {}.readDouble($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Double {} = {}.readDoubleBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceFloatSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeFloat($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeFloatBox($1, (Float){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("float {} = {}.readFloat($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Float {} = {}.readFloatBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceIntSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeInt($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeIntBox($1, (Integer){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("int {} = {}.readInt($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Integer {} = {}.readIntBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ListField;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceListSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
var listField = (ListField) fieldRegistration;
|
||||
|
||||
switch (listField.getType().getTypeName()) {
|
||||
case "java.util.List<java.lang.Integer>":
|
||||
builder.append(StringUtils.format("{}.writeIntList($1, (List){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "java.util.List<java.lang.Long>":
|
||||
builder.append(StringUtils.format("{}.writeLongList($1, (List){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "java.util.List<java.lang.String>":
|
||||
builder.append(StringUtils.format("{}.writeStringList($1, (List){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
default:
|
||||
}
|
||||
|
||||
// List<IPacket>
|
||||
if (listField.getListElementRegistration() instanceof ObjectProtocolField) {
|
||||
var objectProtocolField = (ObjectProtocolField) listField.getListElementRegistration();
|
||||
builder.append(StringUtils.format("{}.writePacketList($1, (List){}, {});", EnhanceUtils.byteBufUtils, objectStr, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(objectProtocolField.getProtocolId())));
|
||||
return;
|
||||
}
|
||||
|
||||
var list = "list" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("List {} = (List){};", list, objectStr));
|
||||
|
||||
builder.append(StringUtils.format("{}.writeInt($1, CollectionUtils.size({}));", EnhanceUtils.byteBufUtils, list));
|
||||
|
||||
var iterator = "iterator" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Iterator {} = CollectionUtils.iterator({});", iterator, list));
|
||||
builder.append(StringUtils.format("while({}.hasNext()){", iterator));
|
||||
|
||||
var element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Object {}={}.next();", element, iterator));
|
||||
EnhanceUtils.enhanceSerializer(listField.getListElementRegistration().serializer())
|
||||
.writeObject(builder, element, field, listField.getListElementRegistration());
|
||||
builder.append("}");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var listField = (ListField) fieldRegistration;
|
||||
var list = "list" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
switch (listField.getType().getTypeName()) {
|
||||
case "java.util.List<java.lang.Integer>":
|
||||
builder.append(StringUtils.format("List {} = {}.readIntList($1);", list, EnhanceUtils.byteBufUtils));
|
||||
return list;
|
||||
case "java.util.List<java.lang.Long>":
|
||||
builder.append(StringUtils.format("List {} = {}.readLongList($1);", list, EnhanceUtils.byteBufUtils));
|
||||
return list;
|
||||
case "java.util.List<java.lang.String>":
|
||||
builder.append(StringUtils.format("List {} = {}.readStringList($1);", list, EnhanceUtils.byteBufUtils));
|
||||
return list;
|
||||
default:
|
||||
}
|
||||
|
||||
if (listField.getListElementRegistration() instanceof ObjectProtocolField) {
|
||||
var objectProtocolField = (ObjectProtocolField) listField.getListElementRegistration();
|
||||
builder.append(StringUtils.format("List {} = {}.readPacketList($1, {});", list, EnhanceUtils.byteBufUtils, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(objectProtocolField.getProtocolId())));
|
||||
return list;
|
||||
}
|
||||
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {}={}.readInt($1);", size, EnhanceUtils.byteBufUtils));
|
||||
|
||||
builder.append(StringUtils.format("List {} = CollectionUtils.newFixedList({});", list, size));
|
||||
|
||||
var i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
builder.append(StringUtils.format("for(int {}=0; {}<{}; {}++){", i, i, size, i));
|
||||
var readObject = EnhanceUtils.enhanceSerializer(listField.getListElementRegistration().serializer()).readObject(builder, field, listField.getListElementRegistration());
|
||||
builder.append(StringUtils.format("{}.add({});}", list, readObject));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceLongSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeLong($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeLongBox($1, (Long){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("long {} = {}.readLong($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Long {} = {}.readLongBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.BaseField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.MapField;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.serializer.*;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceMapSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
var mapField = (MapField) fieldRegistration;
|
||||
var keyRegistration = mapField.getMapKeyRegistration();
|
||||
var valueRegistration = mapField.getMapValueRegistration();
|
||||
|
||||
if (keyRegistration instanceof BaseField) {
|
||||
if (valueRegistration instanceof BaseField) {
|
||||
var keyBaseRegistration = (BaseField) keyRegistration;
|
||||
var valueBaseRegistration = (BaseField) valueRegistration;
|
||||
if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueBaseRegistration.serializer() == IntSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeIntIntMap($1, (Map){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
} else if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueBaseRegistration.serializer() == LongSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeIntLongMap($1, (Map){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
} else if (keyBaseRegistration.serializer() == LongSerializer.getInstance() && valueBaseRegistration.serializer() == IntSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeLongIntMap($1, (Map){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
} else if (keyBaseRegistration.serializer() == LongSerializer.getInstance() && valueBaseRegistration.serializer() == LongSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeLongLongMap($1, (Map){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
} else if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueBaseRegistration.serializer() == StringSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeIntStringMap($1, (Map){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
}
|
||||
} else if (valueRegistration instanceof ObjectProtocolField) {
|
||||
var keyBaseRegistration = (BaseField) keyRegistration;
|
||||
var valueProtocolRegistration = (ObjectProtocolField) valueRegistration;
|
||||
if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueProtocolRegistration.serializer() == ObjectProtocolSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeIntPacketMap($1, (Map){}, {});", EnhanceUtils.byteBufUtils, objectStr, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(valueProtocolRegistration.getProtocolId())));
|
||||
return;
|
||||
} else if (keyBaseRegistration.serializer() == LongSerializer.getInstance() && valueProtocolRegistration.serializer() == ObjectProtocolSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("{}.writeLongPacketMap($1, (Map){}, {});", EnhanceUtils.byteBufUtils, objectStr, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(valueProtocolRegistration.getProtocolId())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var map = "map" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Map {} = (Map){};", map, objectStr));
|
||||
builder.append(StringUtils.format("{}.writeInt($1, CollectionUtils.size({}));", EnhanceUtils.byteBufUtils, map));
|
||||
|
||||
var iterator = "iterator" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Iterator {} = CollectionUtils.iterator({});", iterator, map));
|
||||
builder.append(StringUtils.format("while({}.hasNext()) {", iterator));
|
||||
|
||||
var entry = "entry" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("{} {}=({}){}.next();", Map.Entry.class.getCanonicalName(), entry, Map.Entry.class.getCanonicalName(), iterator));
|
||||
|
||||
var key = "key" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Object {} = {}.getKey();", key, entry));
|
||||
|
||||
var value = "value" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Object {} = {}.getValue();", value, entry));
|
||||
|
||||
EnhanceUtils.enhanceSerializer(keyRegistration.serializer()).writeObject(builder, key, field, keyRegistration);
|
||||
EnhanceUtils.enhanceSerializer(valueRegistration.serializer()).writeObject(builder, value, field, valueRegistration);
|
||||
|
||||
builder.append("}");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var mapField = (MapField) fieldRegistration;
|
||||
var keyRegistration = mapField.getMapKeyRegistration();
|
||||
var valueRegistration = mapField.getMapValueRegistration();
|
||||
|
||||
var map = "map" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (keyRegistration instanceof BaseField) {
|
||||
if (valueRegistration instanceof BaseField) {
|
||||
var keyBaseRegistration = (BaseField) keyRegistration;
|
||||
var valueBaseRegistration = (BaseField) valueRegistration;
|
||||
if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueBaseRegistration.serializer() == IntSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readIntIntMap($1);", map, EnhanceUtils.byteBufUtils));
|
||||
return map;
|
||||
} else if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueBaseRegistration.serializer() == LongSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readIntLongMap($1);", map, EnhanceUtils.byteBufUtils));
|
||||
return map;
|
||||
} else if (keyBaseRegistration.serializer() == LongSerializer.getInstance() && valueBaseRegistration.serializer() == IntSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readLongIntMap($1);", map, EnhanceUtils.byteBufUtils));
|
||||
return map;
|
||||
} else if (keyBaseRegistration.serializer() == LongSerializer.getInstance() && valueBaseRegistration.serializer() == LongSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readLongLongMap($1);", map, EnhanceUtils.byteBufUtils));
|
||||
return map;
|
||||
} else if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueBaseRegistration.serializer() == StringSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readIntStringMap($1);", map, EnhanceUtils.byteBufUtils));
|
||||
return map;
|
||||
}
|
||||
} else if (valueRegistration instanceof ObjectProtocolField) {
|
||||
var keyBaseRegistration = (BaseField) keyRegistration;
|
||||
var valueProtocolRegistration = (ObjectProtocolField) valueRegistration;
|
||||
if (keyBaseRegistration.serializer() == IntSerializer.getInstance() && valueProtocolRegistration.serializer() == ObjectProtocolSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readIntPacketMap($1, {});", map, EnhanceUtils.byteBufUtils, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(valueProtocolRegistration.getProtocolId())));
|
||||
return map;
|
||||
} else if (keyBaseRegistration.serializer() == LongSerializer.getInstance() && valueProtocolRegistration.serializer() == ObjectProtocolSerializer.getInstance()) {
|
||||
builder.append(StringUtils.format("Map {} = {}.readLongPacketMap($1, {});", map, EnhanceUtils.byteBufUtils, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(valueProtocolRegistration.getProtocolId())));
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {}={}.readInt($1);", size, EnhanceUtils.byteBufUtils));
|
||||
builder.append(StringUtils.format("Map {} = CollectionUtils.newFixedMap({});", map, size));
|
||||
|
||||
var i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for(int {}=0; {}<{}; {}++){", i, i, size, i));
|
||||
|
||||
var keyObject = EnhanceUtils.enhanceSerializer(keyRegistration.serializer()).readObject(builder, field, keyRegistration);
|
||||
var valueObject = EnhanceUtils.enhanceSerializer(valueRegistration.serializer()).readObject(builder, field, valueRegistration);
|
||||
|
||||
builder.append(StringUtils.format("{}.put({},{});}", map, keyObject, valueObject));
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* 对应于ObjectProtocolSerializer
|
||||
*
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceObjectProtocolSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
var objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
builder.append(StringUtils.format("{}.write($1, (IPacket){});", EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(objectProtocolField.getProtocolId()), objectStr));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
var protocolName = getProtocolClassCanonicalName(objectProtocolField.getProtocolId());
|
||||
builder.append(StringUtils.format("{} {} = ({}){}.read($1);", protocolName, result, protocolName, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(objectProtocolField.getProtocolId())));
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getProtocolClassCanonicalName(short protocolId) {
|
||||
return ProtocolManager.getProtocol(protocolId).protocolConstructor().getDeclaringClass().getCanonicalName();
|
||||
}
|
||||
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.registration.field.SetField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceSetSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
var setField = (SetField) fieldRegistration;
|
||||
|
||||
switch (setField.getType().getTypeName()) {
|
||||
case "java.util.Set<java.lang.Integer>":
|
||||
builder.append(StringUtils.format("{}.writeIntSet($1, (Set){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "java.util.Set<java.lang.Long>":
|
||||
builder.append(StringUtils.format("{}.writeLongSet($1, (Set){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
case "java.util.Set<java.lang.String>":
|
||||
builder.append(StringUtils.format("{}.writeStringSet($1, (Set){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
return;
|
||||
default:
|
||||
}
|
||||
|
||||
// Set<IPacket>
|
||||
if (setField.getSetElementRegistration() instanceof ObjectProtocolField) {
|
||||
var objectProtocolField = (ObjectProtocolField) setField.getSetElementRegistration();
|
||||
builder.append(StringUtils.format("{}.writePacketSet($1, (Set){}, {});", EnhanceUtils.byteBufUtils, objectStr, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(objectProtocolField.getProtocolId())));
|
||||
return;
|
||||
}
|
||||
|
||||
var set = "set" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Set {} = (Set){};", set, objectStr));
|
||||
|
||||
builder.append(StringUtils.format("{}.writeInt($1, CollectionUtils.size({}));", EnhanceUtils.byteBufUtils, set));
|
||||
|
||||
var iterator = "iterator" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Iterator {} = CollectionUtils.iterator({});", iterator, set));
|
||||
builder.append(StringUtils.format("while({}.hasNext()) {", iterator));
|
||||
|
||||
var element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("Object {}={}.next();", element, iterator));
|
||||
EnhanceUtils.enhanceSerializer(setField.getSetElementRegistration().serializer())
|
||||
.writeObject(builder, element, field, setField.getSetElementRegistration());
|
||||
builder.append("}");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var setField = (SetField) fieldRegistration;
|
||||
var set = "set" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
switch (setField.getType().getTypeName()) {
|
||||
case "java.util.Set<java.lang.Integer>":
|
||||
builder.append(StringUtils.format("Set {} = {}.readIntSet($1);", set, EnhanceUtils.byteBufUtils));
|
||||
return set;
|
||||
case "java.util.Set<java.lang.Long>":
|
||||
builder.append(StringUtils.format("Set {} = {}.readLongSet($1);", set, EnhanceUtils.byteBufUtils));
|
||||
return set;
|
||||
case "java.util.Set<java.lang.String>":
|
||||
builder.append(StringUtils.format("Set {} = {}.readStringSet($1);", set, EnhanceUtils.byteBufUtils));
|
||||
return set;
|
||||
default:
|
||||
}
|
||||
|
||||
if (setField.getSetElementRegistration() instanceof ObjectProtocolField) {
|
||||
var objectProtocolField = (ObjectProtocolField) setField.getSetElementRegistration();
|
||||
builder.append(StringUtils.format("Set {} = {}.readPacketSet($1, {});", set, EnhanceUtils.byteBufUtils, EnhanceUtils.getProtocolRegistrationFieldNameByProtocolId(objectProtocolField.getProtocolId())));
|
||||
return set;
|
||||
}
|
||||
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("int {} = {}.readInt($1);", size, EnhanceUtils.byteBufUtils));
|
||||
builder.append(StringUtils.format("Set {} = CollectionUtils.newFixedSet({});", set, size));
|
||||
|
||||
var i = "i" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for(int {}=0; {}<{}; {}++){", i, i, size, i));
|
||||
|
||||
var readObject = EnhanceUtils.enhanceSerializer(setField.getSetElementRegistration().serializer()).readObject(builder, field, setField.getSetElementRegistration());
|
||||
builder.append(StringUtils.format("{}.add({});}", set, readObject));
|
||||
return set;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceShortSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("{}.writeShort($1, {});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
} else {
|
||||
builder.append(StringUtils.format("{}.writeShortBox($1, (Short){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
if (field.getType().isPrimitive() || (field.getType().isArray() && field.getType().getComponentType().isPrimitive())) {
|
||||
builder.append(StringUtils.format("short {} = {}.readShort($1);", result, EnhanceUtils.byteBufUtils));
|
||||
} else {
|
||||
builder.append(StringUtils.format("Short {} = {}.readShortBox($1);", result, EnhanceUtils.byteBufUtils));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.EnhanceUtils;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class EnhanceStringSerializer implements IEnhanceSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration) {
|
||||
builder.append(StringUtils.format("{}.writeString($1, (String){});", EnhanceUtils.byteBufUtils, objectStr));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration) {
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("String {} = {}.readString($1);", result, EnhanceUtils.byteBufUtils));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.enhance;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IEnhanceSerializer {
|
||||
|
||||
/**
|
||||
* IProtocolRegistration.write(ByteBuf buffer, IPacket packet);
|
||||
* $1=buffer
|
||||
* $2=packet
|
||||
*/
|
||||
void writeObject(StringBuilder builder, String objectStr, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
/**
|
||||
* IProtocolRegistration.Object read(ByteBuf buffer);
|
||||
* $1=buffer
|
||||
*/
|
||||
String readObject(StringBuilder builder, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolDocument;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.IOUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateJsUtils {
|
||||
|
||||
private static final String PROTOCOL_OUTPUT_ROOT_PATH = "jsProtocol/";
|
||||
|
||||
private static Map<ISerializer, IJsSerializer> jsSerializerMap;
|
||||
|
||||
public static IJsSerializer jsSerializer(ISerializer serializer) {
|
||||
return jsSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
FileUtils.deleteFile(new File(PROTOCOL_OUTPUT_ROOT_PATH));
|
||||
FileUtils.createDirectory(PROTOCOL_OUTPUT_ROOT_PATH);
|
||||
|
||||
jsSerializerMap = new HashMap<>();
|
||||
jsSerializerMap.put(BooleanSerializer.getInstance(), new JsBooleanSerializer());
|
||||
jsSerializerMap.put(ByteSerializer.getInstance(), new JsByteSerializer());
|
||||
jsSerializerMap.put(ShortSerializer.getInstance(), new JsShortSerializer());
|
||||
jsSerializerMap.put(IntSerializer.getInstance(), new JsIntSerializer());
|
||||
jsSerializerMap.put(LongSerializer.getInstance(), new JsLongSerializer());
|
||||
jsSerializerMap.put(FloatSerializer.getInstance(), new JsFloatSerializer());
|
||||
jsSerializerMap.put(DoubleSerializer.getInstance(), new JsDoubleSerializer());
|
||||
jsSerializerMap.put(CharSerializer.getInstance(), new JsCharSerializer());
|
||||
jsSerializerMap.put(StringSerializer.getInstance(), new JsStringSerializer());
|
||||
jsSerializerMap.put(ArraySerializer.getInstance(), new JsArraySerializer());
|
||||
jsSerializerMap.put(ListSerializer.getInstance(), new JsListSerializer());
|
||||
jsSerializerMap.put(SetSerializer.getInstance(), new JsSetSerializer());
|
||||
jsSerializerMap.put(MapSerializer.getInstance(), new JsMapSerializer());
|
||||
jsSerializerMap.put(ObjectProtocolSerializer.getInstance(), new JsObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
jsSerializerMap = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("js/buffer/ByteBuffer.js"
|
||||
, "js/buffer/long.js"
|
||||
, "js/buffer/longbits.js");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}{}", PROTOCOL_OUTPUT_ROOT_PATH, StringUtils.substringAfterFirst(fileName, "js/")));
|
||||
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
|
||||
}
|
||||
|
||||
|
||||
// 生成ProtocolManager.js文件
|
||||
var jsBuilder = new StringBuilder();
|
||||
|
||||
protocolList.stream()
|
||||
.filter(it -> Objects.nonNull(it))
|
||||
.forEach(it -> {
|
||||
var name = it.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var path = GenerateProtocolPath.getProtocolPath(it.protocolId());
|
||||
if (StringUtils.isBlank(path)) {
|
||||
jsBuilder.append(StringUtils.format("import {} from './{}.js';", name, name)).append(LS);
|
||||
} else {
|
||||
jsBuilder.append(StringUtils.format("import {} from './{}/{}.js';", name, path, name)).append(LS);
|
||||
}
|
||||
});
|
||||
|
||||
jsBuilder.append(LS).append(LS);
|
||||
|
||||
var protocolManagerStr = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("js/ProtocolManager.js")));
|
||||
jsBuilder.append(protocolManagerStr);
|
||||
|
||||
jsBuilder.append("ProtocolManager.initProtocol = function initProtocol() {").append(LS);
|
||||
protocolList.stream().filter(it -> Objects.nonNull(it))
|
||||
.forEach(it -> jsBuilder.append(TAB).append(StringUtils.format("protocols.set({}, {});", it.protocolId(), it.protocolConstructor().getDeclaringClass().getSimpleName())).append(LS));
|
||||
jsBuilder.append("};").append(LS + LS);
|
||||
|
||||
jsBuilder.append("export default ProtocolManager;").append(LS);
|
||||
|
||||
FileUtils.writeStringToFile(new File(StringUtils.format("{}{}", PROTOCOL_OUTPUT_ROOT_PATH, "ProtocolManager.js")), jsBuilder.toString());
|
||||
}
|
||||
|
||||
public static void createJsProtocolFile(ProtocolRegistration registration) {
|
||||
// 初始化index
|
||||
GenerateUtils.index.set(0);
|
||||
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
|
||||
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
|
||||
|
||||
var jsBuilder = new StringBuilder();
|
||||
|
||||
// 如果协议包含子协议,则需要导入ProtocolManager
|
||||
var subProtocols = ProtocolManager.getAllSubProtocolIds(protocolId);
|
||||
if (CollectionUtils.isNotEmpty(subProtocols)) {
|
||||
var path = GenerateProtocolPath.getProtocolPath(protocolId);
|
||||
if (StringUtils.isBlank(path)) {
|
||||
jsBuilder.append("import ProtocolManager from './ProtocolManager.js';").append(LS);
|
||||
} else {
|
||||
jsBuilder.append("import ProtocolManager from '");
|
||||
Arrays.stream(path.split(StringUtils.SLASH)).forEach(it -> jsBuilder.append("../"));
|
||||
jsBuilder.append("ProtocolManager.js';").append(LS);
|
||||
}
|
||||
}
|
||||
|
||||
// export object
|
||||
jsBuilder.append(exportFunction(registration));
|
||||
|
||||
// protocolId method
|
||||
jsBuilder.append(protocolIdFunction(registration));
|
||||
|
||||
// writeObject method
|
||||
jsBuilder.append(writeObject(registration));
|
||||
|
||||
// readObject method
|
||||
jsBuilder.append(readObject(registration));
|
||||
|
||||
|
||||
jsBuilder.append(LS).append(StringUtils.format("export default {};", protocolClazzName)).append(LS);
|
||||
|
||||
|
||||
var protocolOutputPath = StringUtils.format("{}{}/{}.js"
|
||||
, PROTOCOL_OUTPUT_ROOT_PATH
|
||||
, GenerateProtocolPath.getProtocolPath(protocolId)
|
||||
, protocolClazzName);
|
||||
FileUtils.writeStringToFile(new File(protocolOutputPath), jsBuilder.toString());
|
||||
}
|
||||
|
||||
private static String exportFunction(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
|
||||
var docTitle = protocolDocument.getKey();
|
||||
var docFieldMap = protocolDocument.getValue();
|
||||
|
||||
var jsBuilder = new StringBuilder();
|
||||
|
||||
if (!StringUtils.isBlank(docTitle)) {
|
||||
jsBuilder.append(docTitle).append(LS);
|
||||
}
|
||||
|
||||
jsBuilder.append(StringUtils.format("const {} = function(", protocolClazzName));
|
||||
jsBuilder.append(StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray()))
|
||||
.append(") {")
|
||||
.append(LS);
|
||||
|
||||
for (var field : fields) {
|
||||
var propertyName = field.getName();
|
||||
|
||||
// 生成注释
|
||||
var doc = docFieldMap.get(propertyName);
|
||||
if (!StringUtils.isBlank(doc)) {
|
||||
Arrays.stream(doc.split(LS)).forEach(it -> jsBuilder.append(TAB).append(it).append(LS));
|
||||
}
|
||||
|
||||
jsBuilder.append(TAB)
|
||||
.append(StringUtils.format("this.{} = {};", propertyName, propertyName))
|
||||
// 生成类型的注释
|
||||
.append(" // ").append(field.getGenericType().getTypeName())
|
||||
.append(LS);
|
||||
}
|
||||
|
||||
jsBuilder.append("};").append(LS).append(LS);
|
||||
return jsBuilder.toString();
|
||||
}
|
||||
|
||||
private static String protocolIdFunction(ProtocolRegistration registration) {
|
||||
var protocolId = registration.getId();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var jsBuilder = new StringBuilder();
|
||||
jsBuilder.append(StringUtils.format("{}.prototype.protocolId = function() {", protocolClazzName)).append(LS);
|
||||
jsBuilder.append(TAB).append(StringUtils.format("return {};", protocolId)).append(LS);
|
||||
jsBuilder.append("};").append(LS).append(LS);
|
||||
|
||||
return jsBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String writeObject(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var jsBuilder = new StringBuilder();
|
||||
jsBuilder.append(StringUtils.format("{}.writeObject = function(byteBuffer, packet) {", protocolClazzName)).append(LS);
|
||||
|
||||
jsBuilder.append(TAB).append("if (packet === null) {").append(LS);
|
||||
jsBuilder.append(TAB + TAB).append("byteBuffer.writeBoolean(false);").append(LS);
|
||||
jsBuilder.append(TAB + TAB).append("return;").append(LS);
|
||||
jsBuilder.append(TAB).append("}").append(LS);
|
||||
|
||||
jsBuilder.append(TAB).append("byteBuffer.writeBoolean(true);").append(LS);
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
jsSerializer(fieldRegistration.serializer()).writeObject(jsBuilder, "packet." + field.getName(), 1, field, fieldRegistration);
|
||||
}
|
||||
|
||||
jsBuilder.append("};").append(LS).append(LS);
|
||||
return jsBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String readObject(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var jsBuilder = new StringBuilder();
|
||||
jsBuilder.append(StringUtils.format("{}.readObject = function(byteBuffer) {", protocolClazzName)).append(LS);
|
||||
jsBuilder.append(TAB).append("if (!byteBuffer.readBoolean()) {").append(LS);
|
||||
jsBuilder.append(TAB + TAB).append("return null;").append(LS);
|
||||
jsBuilder.append(TAB).append("}").append(LS);
|
||||
|
||||
|
||||
jsBuilder.append(TAB).append(StringUtils.format("const packet = new {}();", protocolClazzName)).append(LS);
|
||||
|
||||
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
var readObject = jsSerializer(fieldRegistration.serializer()).readObject(jsBuilder, 1, field, fieldRegistration);
|
||||
jsBuilder.append(TAB).append(StringUtils.format("packet.{} = {};", field.getName(), readObject)).append(LS);
|
||||
}
|
||||
|
||||
jsBuilder.append(TAB).append("return packet;").append(LS);
|
||||
|
||||
jsBuilder.append("};").append(LS);
|
||||
|
||||
return jsBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface IJsSerializer {
|
||||
|
||||
void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.ArrayField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsArraySerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} === null) {", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("byteBuffer.writeInt(0);").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
|
||||
builder.append("} else {").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("byteBuffer.writeInt({}.length);", objectStr)).append(LS);
|
||||
|
||||
String element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("{}.forEach({} => {", objectStr, element)).append(LS);
|
||||
GenerateJsUtils.jsSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("});").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = [];", result)).append(LS);
|
||||
|
||||
String i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
String size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (let {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
String readObject = GenerateJsUtils.jsSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.push({});", result, readObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsBooleanSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeBoolean({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readBoolean(); ", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsByteSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeByte({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readByte();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsCharSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeChar({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readChar();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsDoubleSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeDouble({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readDouble();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsFloatSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeFloat({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readFloat();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsIntSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeInt({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readInt();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ListField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsListSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} === null) {", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("byteBuffer.writeInt(0);").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
|
||||
builder.append("} else {").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("byteBuffer.writeInt({}.length);", objectStr)).append(LS);
|
||||
|
||||
String element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("{}.forEach({} => {", objectStr, element)).append(LS);
|
||||
GenerateJsUtils.jsSerializer(listField.getListElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, listField.getListElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("});").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ListField listField = (ListField) fieldRegistration;
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = [];", result)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
String size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
String i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for (let {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
String readObject = GenerateJsUtils.jsSerializer(listField.getListElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, listField.getListElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.push({});", result, readObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsLongSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeLong({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readLong();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.MapField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsMapSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} === null) {", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("byteBuffer.writeInt(0);").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("} else {").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("byteBuffer.writeInt({}.size);", objectStr)).append(LS);
|
||||
|
||||
String key = "key" + GenerateUtils.index.getAndIncrement();
|
||||
String value = "value" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("{}.forEach(({}, {}) => {", objectStr, value, key)).append(LS);
|
||||
GenerateJsUtils.jsSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.writeObject(builder, key, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
GenerateJsUtils.jsSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.writeObject(builder, value, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("});").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
MapField mapField = (MapField) fieldRegistration;
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = new Map();", result)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
String size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
|
||||
String i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for (let {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
|
||||
String keyObject = GenerateJsUtils.jsSerializer(mapField.getMapKeyRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapKeyRegistration());
|
||||
|
||||
|
||||
String valueObject = GenerateJsUtils.jsSerializer(mapField.getMapValueRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, mapField.getMapValueRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
|
||||
builder.append(StringUtils.format("{}.set({}, {});", result, keyObject, valueObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.ObjectProtocolField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsObjectProtocolSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("ProtocolManager.getProtocol({}).writeObject(byteBuffer, {});", objectProtocolField.getProtocolId(), objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = ProtocolManager.getProtocol({}).readObject(byteBuffer);", result, objectProtocolField.getProtocolId())).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.registration.field.SetField;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsSetSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} === null) {", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("byteBuffer.writeInt(0);").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
|
||||
builder.append("} else {").append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("byteBuffer.writeInt({}.size);", objectStr)).append(LS);
|
||||
|
||||
String element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("{}.forEach({} => {", objectStr, element)).append(LS);
|
||||
GenerateJsUtils.jsSerializer(setField.getSetElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, setField.getSetElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("});").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
SetField setField = (SetField) fieldRegistration;
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = new Set();", result)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
String size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readInt();", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
String i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
builder.append(StringUtils.format("for (let {} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
|
||||
String readObject = GenerateJsUtils.jsSerializer(setField.getSetElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, setField.getSetElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("{}.add({});", result, readObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("}").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("}").append(LS);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsShortSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeShort({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readShort();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.js;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class JsStringSerializer implements IJsSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer.writeString({});", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("const {} = byteBuffer.readString();", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.lua;
|
||||
|
||||
import com.zfoo.protocol.ProtocolManager;
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolDocument;
|
||||
import com.zfoo.protocol.generate.GenerateProtocolPath;
|
||||
import com.zfoo.protocol.registration.IProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.ProtocolRegistration;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.*;
|
||||
import com.zfoo.protocol.util.ClassUtils;
|
||||
import com.zfoo.protocol.util.FileUtils;
|
||||
import com.zfoo.protocol.util.IOUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public abstract class GenerateLuaUtils {
|
||||
|
||||
private static final String PROTOCOL_OUTPUT_ROOT_PATH = "LuaProtocol/";
|
||||
|
||||
private static Map<ISerializer, ILuaSerializer> luaSerializerMap;
|
||||
|
||||
public static ILuaSerializer luaSerializer(ISerializer serializer) {
|
||||
return luaSerializerMap.get(serializer);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
FileUtils.deleteFile(new File(PROTOCOL_OUTPUT_ROOT_PATH));
|
||||
FileUtils.createDirectory(PROTOCOL_OUTPUT_ROOT_PATH);
|
||||
|
||||
luaSerializerMap = new HashMap<>();
|
||||
luaSerializerMap.put(BooleanSerializer.getInstance(), new LuaBooleanSerializer());
|
||||
luaSerializerMap.put(ByteSerializer.getInstance(), new LuaByteSerializer());
|
||||
luaSerializerMap.put(ShortSerializer.getInstance(), new LuaShortSerializer());
|
||||
luaSerializerMap.put(IntSerializer.getInstance(), new LuaIntSerializer());
|
||||
luaSerializerMap.put(LongSerializer.getInstance(), new LuaLongSerializer());
|
||||
luaSerializerMap.put(FloatSerializer.getInstance(), new LuaFloatSerializer());
|
||||
luaSerializerMap.put(DoubleSerializer.getInstance(), new LuaDoubleSerializer());
|
||||
luaSerializerMap.put(CharSerializer.getInstance(), new LuaCharSerializer());
|
||||
luaSerializerMap.put(StringSerializer.getInstance(), new LuaStringSerializer());
|
||||
luaSerializerMap.put(ArraySerializer.getInstance(), new LuaArraySerializer());
|
||||
luaSerializerMap.put(ListSerializer.getInstance(), new LuaListSerializer());
|
||||
luaSerializerMap.put(SetSerializer.getInstance(), new LuaSetSerializer());
|
||||
luaSerializerMap.put(MapSerializer.getInstance(), new LuaMapSerializer());
|
||||
luaSerializerMap.put(ObjectProtocolSerializer.getInstance(), new LuaObjectProtocolSerializer());
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
luaSerializerMap = null;
|
||||
}
|
||||
|
||||
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
|
||||
var list = List.of("lua/Buffer/ByteBuffer.lua", "lua/Buffer/Long.lua");
|
||||
|
||||
for (var fileName : list) {
|
||||
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
|
||||
var createFile = new File(StringUtils.format("{}{}", PROTOCOL_OUTPUT_ROOT_PATH, StringUtils.substringAfterFirst(fileName, "lua/")));
|
||||
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
|
||||
}
|
||||
|
||||
// 生成Protocol.lua文件
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
var protocolManagerStr = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("lua/ProtocolManager.lua")));
|
||||
luaBuilder.append(protocolManagerStr);
|
||||
|
||||
luaBuilder.append("function initProtocol()").append(LS);
|
||||
protocolList.stream()
|
||||
.filter(it -> Objects.nonNull(it))
|
||||
.forEach(it -> {
|
||||
var name = it.protocolConstructor().getDeclaringClass().getSimpleName();
|
||||
var path = GenerateProtocolPath.getCapitalizeProtocolPath(it.protocolId());
|
||||
|
||||
if (StringUtils.isBlank(path)) {
|
||||
luaBuilder.append(TAB).append(StringUtils.format("local {} = require(\"LuaProtocol.{}\")", name, name)).append(LS);
|
||||
} else {
|
||||
luaBuilder.append(TAB).append(StringUtils.format("local {} = require(\"LuaProtocol.{}.{}\")"
|
||||
, name, path.replaceAll(StringUtils.SLASH, StringUtils.PERIOD), name)).append(LS);
|
||||
}
|
||||
});
|
||||
|
||||
protocolList.stream().filter(it -> Objects.nonNull(it))
|
||||
.forEach(it -> luaBuilder.append(TAB).append(StringUtils.format("protocols[{}] = {}", it.protocolId(), it.protocolConstructor().getDeclaringClass().getSimpleName())).append(LS));
|
||||
|
||||
luaBuilder.append("end").append(LS + LS);
|
||||
luaBuilder.append("ProtocolManager.initProtocol = initProtocol").append(LS);
|
||||
luaBuilder.append("return ProtocolManager").append(LS);
|
||||
|
||||
FileUtils.writeStringToFile(new File(StringUtils.format("{}{}", PROTOCOL_OUTPUT_ROOT_PATH, "ProtocolManager.lua")), luaBuilder.toString());
|
||||
}
|
||||
|
||||
public static void createLuaProtocolFile(ProtocolRegistration registration) {
|
||||
// 初始化index
|
||||
GenerateUtils.index.set(0);
|
||||
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
|
||||
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
|
||||
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
// document
|
||||
luaBuilder.append(documentTitleAndImport(registration));
|
||||
|
||||
// new object
|
||||
luaBuilder.append(newFunction(registration));
|
||||
|
||||
// protocolId method
|
||||
luaBuilder.append(protocolIdFunction(registration));
|
||||
|
||||
// writeObject method
|
||||
luaBuilder.append(writePacket(registration));
|
||||
|
||||
// readObject method
|
||||
luaBuilder.append(readPacket(registration)).append(LS);
|
||||
|
||||
|
||||
luaBuilder.append(StringUtils.format("return {}", protocolClazzName)).append(LS);
|
||||
|
||||
|
||||
var protocolOutputPath = StringUtils.format("{}{}/{}.lua"
|
||||
, PROTOCOL_OUTPUT_ROOT_PATH
|
||||
, GenerateProtocolPath.getCapitalizeProtocolPath(protocolId)
|
||||
, protocolClazzName);
|
||||
FileUtils.writeStringToFile(new File(protocolOutputPath), luaBuilder.toString());
|
||||
}
|
||||
|
||||
private static String documentTitleAndImport(ProtocolRegistration registration) {
|
||||
var protocolId = registration.protocolId();
|
||||
var registrationConstructor = registration.getConstructor();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
|
||||
var docTitle = protocolDocument.getKey();
|
||||
|
||||
if (!StringUtils.isBlank(docTitle)) {
|
||||
Arrays.stream(docTitle.split(LS)).forEach(it -> luaBuilder.append(docToLuaDoc(it)).append(LS));
|
||||
luaBuilder.append(LS);
|
||||
}
|
||||
|
||||
|
||||
// 如果协议包含子协议,则需要导入ProtocolManager
|
||||
var subProtocols = ProtocolManager.getAllSubProtocolIds(protocolId);
|
||||
if (CollectionUtils.isNotEmpty(subProtocols)) {
|
||||
luaBuilder.append("local ProtocolManager = require(\"LuaProtocol.ProtocolManager\")").append(LS + LS);
|
||||
}
|
||||
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
private static String newFunction(ProtocolRegistration registration) {
|
||||
short protocolId = registration.getId();
|
||||
var fields = registration.getFields();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
|
||||
var docFieldMap = protocolDocument.getValue();
|
||||
|
||||
var luaBuilder = new StringBuilder();
|
||||
|
||||
luaBuilder.append(StringUtils.format("local {} = {}", protocolClazzName)).append(LS + LS);
|
||||
|
||||
luaBuilder.append(StringUtils.format("function {}:new(", protocolClazzName));
|
||||
luaBuilder.append(StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray()))
|
||||
.append(")")
|
||||
.append(LS);
|
||||
luaBuilder.append(TAB).append("local obj = {").append(LS);
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var propertyName = field.getName();
|
||||
|
||||
// 生成注释
|
||||
var doc = docFieldMap.get(propertyName);
|
||||
if (!StringUtils.isBlank(doc)) {
|
||||
Arrays.stream(doc.split(LS)).forEach(it -> luaBuilder.append(TAB + TAB).append(docToLuaDoc(it)).append(LS));
|
||||
}
|
||||
|
||||
if (i == fields.length - 1) {
|
||||
luaBuilder.append(TAB + TAB)
|
||||
.append(StringUtils.format("{} = {}", propertyName, propertyName));
|
||||
} else {
|
||||
luaBuilder.append(TAB + TAB)
|
||||
.append(StringUtils.format("{} = {},", propertyName, propertyName));
|
||||
}
|
||||
|
||||
// 生成类型的注释
|
||||
luaBuilder.append(" -- ").append(field.getGenericType().getTypeName()).append(LS);
|
||||
}
|
||||
luaBuilder.append(TAB).append("}").append(LS);
|
||||
luaBuilder.append(TAB).append("setmetatable(obj, self)").append(LS);
|
||||
luaBuilder.append(TAB).append("self.__index = self").append(LS);
|
||||
luaBuilder.append(TAB).append("return obj").append(LS);
|
||||
luaBuilder.append("end").append(LS).append(LS);
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
private static String protocolIdFunction(ProtocolRegistration registration) {
|
||||
short protocolId = registration.getId();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var luaBuilder = new StringBuilder();
|
||||
luaBuilder.append(StringUtils.format("function {}:protocolId()", protocolClazzName)).append(LS);
|
||||
luaBuilder.append(TAB).append(StringUtils.format("return {}", protocolId)).append(LS);
|
||||
luaBuilder.append("end").append(LS).append(LS);
|
||||
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String writePacket(ProtocolRegistration registration) {
|
||||
var fields = registration.getFields();
|
||||
var fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var luaBuilder = new StringBuilder();
|
||||
luaBuilder.append(StringUtils.format("function {}:write(byteBuffer, packet)", protocolClazzName)).append(LS);
|
||||
|
||||
luaBuilder.append(TAB).append("if packet == null then").append(LS);
|
||||
luaBuilder.append(TAB + TAB).append("byteBuffer:writeBoolean(false)").append(LS);
|
||||
luaBuilder.append(TAB + TAB).append("return").append(LS);
|
||||
luaBuilder.append(TAB).append("end").append(LS);
|
||||
|
||||
luaBuilder.append(TAB).append("byteBuffer:writeBoolean(true)").append(LS);
|
||||
|
||||
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
var fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
luaSerializer(fieldRegistration.serializer()).writeObject(luaBuilder, "packet." + field.getName(), 1, field, fieldRegistration);
|
||||
}
|
||||
|
||||
luaBuilder.append("end").append(LS).append(LS);
|
||||
return luaBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String readPacket(ProtocolRegistration registration) {
|
||||
Field[] fields = registration.getFields();
|
||||
IFieldRegistration[] fieldRegistrations = registration.getFieldRegistrations();
|
||||
var protocolClazzName = registration.getConstructor().getDeclaringClass().getSimpleName();
|
||||
|
||||
var jsBuilder = new StringBuilder();
|
||||
jsBuilder.append(StringUtils.format("function {}:read(byteBuffer)", protocolClazzName)).append(LS);
|
||||
jsBuilder.append(TAB).append("if not(byteBuffer:readBoolean()) then").append(LS);
|
||||
jsBuilder.append(TAB + TAB).append("return nil").append(LS);
|
||||
jsBuilder.append(TAB).append("end").append(LS);
|
||||
|
||||
|
||||
jsBuilder.append(TAB).append(StringUtils.format("local packet = {}:new()", protocolClazzName)).append(LS);
|
||||
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
IFieldRegistration fieldRegistration = fieldRegistrations[i];
|
||||
|
||||
String readObject = luaSerializer(fieldRegistration.serializer()).readObject(jsBuilder, 1, field, fieldRegistration);
|
||||
jsBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
|
||||
}
|
||||
|
||||
jsBuilder.append(TAB).append("return packet").append(LS);
|
||||
|
||||
jsBuilder.append("end").append(LS);
|
||||
|
||||
return jsBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static String docToLuaDoc(String doc) {
|
||||
return doc.replaceFirst("//", "--");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.lua;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public interface ILuaSerializer {
|
||||
|
||||
void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.lua;
|
||||
|
||||
import com.zfoo.protocol.registration.field.ArrayField;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class LuaArraySerializer implements ILuaSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
ArrayField arrayField = (ArrayField) fieldRegistration;
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if {} == null then", objectStr)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("byteBuffer:writeInt(0)").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
|
||||
builder.append("else").append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("byteBuffer:writeInt(#{});", objectStr)).append(LS);
|
||||
|
||||
String index = "index" + GenerateUtils.index.getAndIncrement();
|
||||
String element = "element" + GenerateUtils.index.getAndIncrement();
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {}, {} in pairs({}) do", index, element, objectStr)).append(LS);
|
||||
GenerateLuaUtils.luaSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("end").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("end").append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
var arrayField = (ArrayField) fieldRegistration;
|
||||
var result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("local {} = {}", result)).append(LS);
|
||||
|
||||
var i = "index" + GenerateUtils.index.getAndIncrement();
|
||||
var size = "size" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("local {} = byteBuffer:readInt()", size)).append(LS);
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("if {} > 0 then", size)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append(StringUtils.format("for {} = 1, {} do", i, size)).append(LS);
|
||||
String readObject = GenerateLuaUtils.luaSerializer(arrayField.getArrayElementRegistration().serializer())
|
||||
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
|
||||
GenerateUtils.addTab(builder, deep + 2);
|
||||
builder.append(StringUtils.format("table.insert({}, {})", result, readObject)).append(LS);
|
||||
GenerateUtils.addTab(builder, deep + 1);
|
||||
builder.append("end").append(LS);
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append("end").append(LS);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The zfoo Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.zfoo.protocol.serializer.lua;
|
||||
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
import com.zfoo.protocol.serializer.GenerateUtils;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
|
||||
|
||||
/**
|
||||
* @author jaysunxiao
|
||||
* @version 3.0
|
||||
*/
|
||||
public class LuaBooleanSerializer implements ILuaSerializer {
|
||||
|
||||
@Override
|
||||
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("byteBuffer:writeBoolean({})", objectStr)).append(LS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
|
||||
String result = "result" + GenerateUtils.index.getAndIncrement();
|
||||
|
||||
GenerateUtils.addTab(builder, deep);
|
||||
builder.append(StringUtils.format("local {} = byteBuffer:readBoolean()", result)).append(LS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user