feat[python]: support python

This commit is contained in:
godotg
2023-08-26 18:30:23 +08:00
parent 1d079b0a7a
commit 99d3cd8b3d
23 changed files with 1434 additions and 10 deletions
+1
View File
@@ -37,6 +37,7 @@ test.md
# 忽略生成的协议文件
**/jsProtocol/
**/gdProtocol/
**/pyProtocol/
**/CsProtocol/
**/LuaProtocol/
**/cppProtocol/
@@ -25,6 +25,7 @@ import com.zfoo.protocol.serializer.go.GenerateGoUtils;
import com.zfoo.protocol.serializer.javascript.GenerateJsUtils;
import com.zfoo.protocol.serializer.lua.GenerateLuaUtils;
import com.zfoo.protocol.serializer.protobuf.GenerateProtobufUtils;
import com.zfoo.protocol.serializer.python.GeneratePyUtils;
import com.zfoo.protocol.serializer.typescript.GenerateTsUtils;
import java.io.IOException;
@@ -62,11 +63,8 @@ public abstract class GenerateProtocolFile {
}
/**
* 生成各种语言的协议文件
*
* @param generateOperation
* @throws IOException
* @throws ClassNotFoundException
* EN: Generate protocol files to various languages
* CN: 生成各种语言的协议文件
*/
public static void generate(GenerateOperation generateOperation) throws IOException, ClassNotFoundException {
var protocols = ProtocolManager.protocols;
@@ -172,6 +170,15 @@ public abstract class GenerateProtocolFile {
}
}
// 生成Python协议
if (generateLanguages.contains(CodeLanguage.Python)) {
GeneratePyUtils.init(generateOperation);
GeneratePyUtils.createProtocolManager(allSortedGenerateProtocols);
for (var protocolRegistration : allSortedGenerateProtocols) {
GeneratePyUtils.createPyProtocolFile((ProtocolRegistration) protocolRegistration);
}
}
// 生成Protobuf协议
if (generateLanguages.contains(CodeLanguage.Protobuf)) {
GenerateProtobufUtils.init(generateOperation);
@@ -28,7 +28,8 @@ import java.util.List;
import java.util.Map;
/**
* 生成协议的时候,协议的文档注释和字段注释会使用这个类
* EN: When generating the protocol, the document comments and field comments of the protocol will use this class
* CN: 生成协议的时候,协议的文档注释和字段注释会使用这个类
*
* @author godotg
* @version 3.0
@@ -38,14 +39,14 @@ public abstract class GenerateProtocolNote {
// 临时变量,启动完成就会销毁,协议的文档,外层map的key为协议类;pair的key为总的注释,value为属性字段的注释,value表示的map的key为属性名称
// 比如在Test中的ComplexObject生成的pari是如下格式
/**
* key docTitle:
* key is docTitle note:
* // 复杂的对象
* // 包括了各种复杂的结构,数组,List,Set,Map
* //
* // @author godotg
* // @version 1.0
* <p>
* value aa:
* value is field note:
* // byte的包装类型
* // 优先使用基础类型,包装类型会有装箱拆箱
*/
@@ -92,18 +93,19 @@ public abstract class GenerateProtocolNote {
case Lua:
fieldNote = StringUtils.format("-- {}", fieldNote).replace("\n", "\n-- ");
break;
case Python:
case GdScript:
fieldNote = StringUtils.format("# {}", fieldNote).replace("\n", "\n# ");
break;
case Enhance:
default:
throw new RunException("无法识别的枚举类型[{}]", language);
throw new RunException("unrecognized enum type [{}]", language);
}
return fieldNote;
}
public static void initProtocolNote(List<IProtocolRegistration> protocolRegistrations) {
AssertionUtils.notNull(protocolNoteMap, "[{}]已经初始完成,初始化完成过后不能调用initProtocolDocument", GenerateProtocolNote.class.getSimpleName());
AssertionUtils.notNull(protocolNoteMap, "[{}] duplicate initialization", GenerateProtocolNote.class.getSimpleName());
for (var protocolRegistration : protocolRegistrations) {
var protocolClazz = protocolRegistration.protocolConstructor().getDeclaringClass();
@@ -33,6 +33,7 @@ import com.zfoo.protocol.serializer.go.GenerateGoUtils;
import com.zfoo.protocol.serializer.javascript.GenerateJsUtils;
import com.zfoo.protocol.serializer.lua.GenerateLuaUtils;
import com.zfoo.protocol.serializer.protobuf.GenerateProtobufUtils;
import com.zfoo.protocol.serializer.python.GeneratePyUtils;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.serializer.typescript.GenerateTsUtils;
import com.zfoo.protocol.util.AssertionUtils;
@@ -352,6 +353,7 @@ public class ProtocolAnalysis {
GenerateTsUtils.clear();
GenerateLuaUtils.clear();
GenerateGdUtils.clear();
GeneratePyUtils.clear();
GenerateProtobufUtils.clear();
}
@@ -0,0 +1,187 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.csharp.GenerateCsUtils;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.*;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.zfoo.protocol.util.FileUtils.LS;
import static com.zfoo.protocol.util.StringUtils.TAB;
import static com.zfoo.protocol.util.StringUtils.TAB_ASCII;
/**
* @author godotg
* @version 3.0
*/
public abstract class GeneratePyUtils {
private static String protocolOutputRootPath = "pyProtocol/";
private static Map<ISerializer, IPySerializer> pySerializerMap;
public static IPySerializer pySerializer(ISerializer serializer) {
return pySerializerMap.get(serializer);
}
public static void init(GenerateOperation generateOperation) {
protocolOutputRootPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
FileUtils.deleteFile(new File(protocolOutputRootPath));
FileUtils.createDirectory(protocolOutputRootPath);
pySerializerMap = new HashMap<>();
pySerializerMap.put(BooleanSerializer.INSTANCE, new PyBooleanSerializer());
pySerializerMap.put(ByteSerializer.INSTANCE, new PyByteSerializer());
pySerializerMap.put(ShortSerializer.INSTANCE, new PyShortSerializer());
pySerializerMap.put(IntSerializer.INSTANCE, new PyIntSerializer());
pySerializerMap.put(LongSerializer.INSTANCE, new PyLongSerializer());
pySerializerMap.put(FloatSerializer.INSTANCE, new PyFloatSerializer());
pySerializerMap.put(DoubleSerializer.INSTANCE, new PyDoubleSerializer());
pySerializerMap.put(CharSerializer.INSTANCE, new PyCharSerializer());
pySerializerMap.put(StringSerializer.INSTANCE, new PyStringSerializer());
pySerializerMap.put(ArraySerializer.INSTANCE, new PyArraySerializer());
pySerializerMap.put(ListSerializer.INSTANCE, new PyListSerializer());
pySerializerMap.put(SetSerializer.INSTANCE, new PySetSerializer());
pySerializerMap.put(MapSerializer.INSTANCE, new PyMapSerializer());
pySerializerMap.put(ObjectProtocolSerializer.INSTANCE, new PyObjectProtocolSerializer());
}
public static void clear() {
pySerializerMap = null;
protocolOutputRootPath = null;
}
public static void createProtocolManager(List<IProtocolRegistration> protocolList) throws IOException {
var list = List.of("python/byte_buffer.py");
for (var fileName : list) {
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
var createFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, StringUtils.substringAfterFirst(fileName, "python/")));
FileUtils.writeInputStreamToFile(createFile, fileInputStream);
}
// 生成ProtocolManager.js文件
var protocolManagerTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("javascript/ProtocolManagerTemplate.js")));
var importBuilder = new StringBuilder();
var initProtocolBuilder = new StringBuilder();
for (var protocol : protocolList) {
var protocolId = protocol.protocolId();
var protocolName = protocol.protocolConstructor().getDeclaringClass().getSimpleName();
var path = GenerateProtocolPath.protocolAbsolutePath(protocol.protocolId(), CodeLanguage.JavaScript);
importBuilder.append(StringUtils.format("import {} from './{}.js';", protocolName, path)).append(LS);
initProtocolBuilder.append(StringUtils.format("protocols.set({}, {});", protocolId, protocolName)).append(LS);
}
protocolManagerTemplate = StringUtils.format(protocolManagerTemplate, importBuilder.toString().trim(), StringUtils.EMPTY_JSON, initProtocolBuilder.toString().trim());
FileUtils.writeStringToFile(new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.js")), protocolManagerTemplate, true);
}
public static void createPyProtocolFile(ProtocolRegistration registration) {
GenerateProtocolFile.index.set(0);
var protocolId = registration.protocolId();
var registrationConstructor = registration.getConstructor();
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
var protocolTemplate = ClassUtils.getFileFromClassPathToString("python/ProtocolTemplate.py");
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.Python);
var fieldDefinition = fieldDefinition(registration);
var writeObject = writeObject(registration);
var readObject = readObject(registration);
protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName
, fieldDefinition.trim(), protocolId, writeObject.trim(), readObject.trim(), protocolClazzName);
var protocolOutputPath = StringUtils.format("{}/{}/{}.py", protocolOutputRootPath
, GenerateProtocolPath.getProtocolPath(protocolId), protocolClazzName);
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate, true);
}
private static String fieldDefinition(ProtocolRegistration registration) {
var protocolId = registration.getId();
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var pyBuilder = new StringBuilder();
// 生成源代码字段的时候,按照原始定义的方式生成
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
for (int i = 0; i < sequencedFields.size(); i++) {
var field = sequencedFields.get(i);
IFieldRegistration fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
var fieldName = field.getName();
// 生成注释
var fieldNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.Python);
if (StringUtils.isNotBlank(fieldNote)) {
pyBuilder.append(TAB).append(fieldNote).append(LS);
}
var fieldDefaultValue = pySerializer(fieldRegistration.serializer()).fieldDefaultValue(field, fieldRegistration);
// 生成类型的注释
pyBuilder.append(StringUtils.format("{}{} = {}", TAB, fieldName, fieldDefaultValue));
pyBuilder.append(StringUtils.format(" # {}", GenerateCsUtils.toCsClassName(field.getGenericType().getTypeName())));
pyBuilder.append(LS);
}
return pyBuilder.toString();
}
private static String writeObject(ProtocolRegistration registration) {
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var pyBuilder = new StringBuilder();
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
pySerializer(fieldRegistration.serializer()).writeObject(pyBuilder, "packet." + field.getName(), 2, field, fieldRegistration);
}
return pyBuilder.toString();
}
private static String readObject(ProtocolRegistration registration) {
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var pyBuilder = new StringBuilder();
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
if (field.isAnnotationPresent(Compatible.class)) {
pyBuilder.append(TAB+ TAB).append("if !buffer.isReadable():").append(LS);
pyBuilder.append(TAB + TAB+ TAB).append("return packet").append(LS);
pyBuilder.append(TAB+ TAB).append("pass").append(LS);
}
var readObject = pySerializer(fieldRegistration.serializer()).readObject(pyBuilder, 2, field, fieldRegistration);
pyBuilder.append(TAB + TAB).append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS);
}
return pyBuilder.toString();
}
public static StringBuilder addTab(StringBuilder builder, int deep) {
builder.append(TAB_ASCII.repeat(Math.max(0, deep)));
return builder;
}
}
@@ -0,0 +1,32 @@
/*
* 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.python;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import java.lang.reflect.Field;
/**
* @author godotg
* @version 3.0
*/
public interface IPySerializer {
String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration);
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,92 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.ArrayField;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.CutDownArraySerializer;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyArraySerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "[]";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownArraySerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
return;
}
ArrayField arrayField = (ArrayField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append("else:").append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("buffer.writeInt({}.size())", objectStr)).append(LS);
String element = "element" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in {}:", element, objectStr)).append(LS);
GeneratePyUtils.pySerializer(arrayField.getArrayElementRegistration().serializer())
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
}
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownArraySerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
if (cutDown != null) {
return cutDown;
}
ArrayField arrayField = (ArrayField) fieldRegistration;
String result = "result" + GenerateProtocolFile.index.getAndIncrement();
builder.append(StringUtils.format("{} = []", result)).append(LS);
String i = "index" + GenerateProtocolFile.index.getAndIncrement();
String size = "size" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String readObject = GeneratePyUtils.pySerializer(arrayField.getArrayElementRegistration().serializer())
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
GeneratePyUtils.addTab(builder, deep + 2);
builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyBooleanSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "False";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readBool() ", result)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyByteSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "0";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readByte()", result)).append(LS);
return result;
}
}
@@ -0,0 +1,48 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyCharSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return StringUtils.EMPTY;
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readChar()", result)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyDoubleSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "0.0";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readDouble()", result)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyFloatSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "0.0";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readFloat()", result)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyIntSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "0";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readInt()", result)).append(LS);
return result;
}
}
@@ -0,0 +1,92 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.registration.field.ListField;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.CutDownListSerializer;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyListSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "[]";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownListSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
return;
}
ListField listField = (ListField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append("else:").append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("buffer.writeInt({}.size())", objectStr)).append(LS);
String element = "element" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in {}:", element, objectStr)).append(LS);
GeneratePyUtils.pySerializer(listField.getListElementRegistration().serializer())
.writeObject(builder, element, deep + 2, field, listField.getListElementRegistration());
}
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownListSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
if (cutDown != null) {
return cutDown;
}
ListField listField = (ListField) fieldRegistration;
String result = "result" + GenerateProtocolFile.index.getAndIncrement();
builder.append(StringUtils.format("{} = []", result)).append(LS);
String i = "index" + GenerateProtocolFile.index.getAndIncrement();
String size = "size" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String readObject = GeneratePyUtils.pySerializer(listField.getListElementRegistration().serializer())
.readObject(builder, deep + 2, field, listField.getListElementRegistration());
GeneratePyUtils.addTab(builder, deep + 2);
builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyLongSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "0";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readLong()", result)).append(LS);
return result;
}
}
@@ -0,0 +1,104 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.registration.field.MapField;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.CutDownMapSerializer;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyMapSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "{}";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownMapSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
return;
}
MapField mapField = (MapField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append("else:").append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("buffer.writeInt({}.size())", objectStr)).append(LS);
String key = "key" + GenerateProtocolFile.index.getAndIncrement();
String value = "value" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in {}:", key, objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 2);
builder.append(StringUtils.format("{} = {}[{}]", value, objectStr, key)).append(LS);
GeneratePyUtils.pySerializer(mapField.getMapKeyRegistration().serializer())
.writeObject(builder, key, deep + 2, field, mapField.getMapKeyRegistration());
GeneratePyUtils.pySerializer(mapField.getMapValueRegistration().serializer())
.writeObject(builder, value, deep + 2, field, mapField.getMapValueRegistration());
}
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownMapSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
if (cutDown != null) {
return cutDown;
}
MapField mapField = (MapField) fieldRegistration;
String result = "result" + GenerateProtocolFile.index.getAndIncrement();
builder.append(StringUtils.format("{} = {}", result)).append(LS);
GeneratePyUtils.addTab(builder, deep);
String size = "size" + GenerateProtocolFile.index.getAndIncrement();
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
String i = "index" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String keyObject = GeneratePyUtils.pySerializer(mapField.getMapKeyRegistration().serializer())
.readObject(builder, deep + 2, field, mapField.getMapKeyRegistration());
String valueObject = GeneratePyUtils.pySerializer(mapField.getMapValueRegistration().serializer())
.readObject(builder, deep + 2, field, mapField.getMapValueRegistration());
GeneratePyUtils.addTab(builder, deep + 2);
builder.append(StringUtils.format("{}[{}] = {}", result, keyObject, valueObject)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.registration.field.ObjectProtocolField;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyObjectProtocolSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "None";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("buffer.writePacket({}, {})", objectStr, objectProtocolField.getProtocolId())).append(LS);
}
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration;
var result = "result" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readPacket({})", result, objectProtocolField.getProtocolId())).append(LS);
return result;
}
}
@@ -0,0 +1,92 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.registration.field.SetField;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.CutDownSetSerializer;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PySetSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "{}";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
if (CutDownSetSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.GdScript)) {
return;
}
SetField setField = (SetField) fieldRegistration;
builder.append(StringUtils.format("if ({} == null):", objectStr)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append("buffer.writeInt(0)").append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append("else:").append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("buffer.writeInt({}.size())", objectStr)).append(LS);
String element = "element" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in {}:", element, objectStr)).append(LS);
GeneratePyUtils.pySerializer(setField.getSetElementRegistration().serializer())
.writeObject(builder, element, deep + 2, field, setField.getSetElementRegistration());
}
@Override
public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.addTab(builder, deep);
var cutDown = CutDownSetSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.GdScript);
if (cutDown != null) {
return cutDown;
}
SetField setField = (SetField) fieldRegistration;
String result = "result" + GenerateProtocolFile.index.getAndIncrement();
builder.append(StringUtils.format("{} = []", result)).append(LS);
String i = "index" + GenerateProtocolFile.index.getAndIncrement();
String size = "size" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readInt()", size)).append(LS);
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0):", size)).append(LS);
GeneratePyUtils.addTab(builder, deep + 1);
builder.append(StringUtils.format("for {} in range({}):", i, size)).append(LS);
String readObject = GeneratePyUtils.pySerializer(setField.getSetElementRegistration().serializer())
.readObject(builder, deep + 2, field, setField.getSetElementRegistration());
GeneratePyUtils.addTab(builder, deep + 2);
builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS);
return result;
}
}
@@ -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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyShortSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return "0";
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readShort()", result)).append(LS);
return result;
}
}
@@ -0,0 +1,48 @@
/*
* 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.python;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
* @version 3.0
*/
public class PyStringSerializer implements IPySerializer {
@Override
public String fieldDefaultValue(Field field, IFieldRegistration fieldRegistration) {
return StringUtils.EMPTY;
}
@Override
public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) {
GeneratePyUtils.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" + GenerateProtocolFile.index.getAndIncrement();
GeneratePyUtils.addTab(builder, deep);
builder.append(StringUtils.format("{} = buffer.readString()", result)).append(LS);
return result;
}
}
@@ -0,0 +1,18 @@
{}
class {}():
{}
def protocolId(self):
return {}
@classmethod
def write(cls, buffer, packet):
if (buffer.writePacketFlag(packet)):
return
{}
@classmethod
def read(cls, buffer):
{}
pass
@@ -0,0 +1,303 @@
import struct
maxSize = 655537
maxInt = 2147483647
minInt = -2147483648
maxLong = 9223372036854775807
minLong = -9223372036854775808
empty_str = ""
class ByteBuffer():
writeOffset = 0
readOffset = 0
buffer = bytearray(8)
def setWriteOffset(self, writeOffset):
if writeOffset > len(self.buffer):
raise ValueError("index out of bounds exception:readerIndex:" + str(self.readOffset) +
", writerIndex:" + str(self.writeOffset) +
"(expected:0 <= readerIndex <= writerIndex <= capacity:" + str(len(self.buffer)))
self.writeOffset = writeOffset
def setReadOffset(self, readOffset):
if readOffset > self.writeOffset:
raise ValueError("index out of bounds exception:readerIndex:" + str(self.readOffset) +
", writerIndex:" + str(self.writeOffset) +
"(expected:0 <= readerIndex <= writerIndex <= capacity:" + str(len(self.buffer)))
self.readOffset = readOffset
def isReadable(self):
return self.writeOffset > self.readOffset
pass
def getCapacity(self):
return len(self.buffer) - self.writeOffset
def ensureCapacity(self, minCapacity):
while (minCapacity - self.getCapacity() > 0):
newSize = len(self.buffer) * 2
if newSize > maxSize:
raise ValueError("out of memory error")
# auto grow capacity
self.buffer.extend(bytearray(len(self.buffer)))
def writeBool(self, value):
if value:
self.writeByte(1)
else:
self.writeByte(0)
def readBool(self):
if self.readByte():
return True
else:
return False
def writeByte(self, value):
self.ensureCapacity(1)
struct.pack_into('>b', self.buffer, self.writeOffset, value)
self.writeOffset += 1
def readByte(self):
value = struct.unpack_from('>b', self.buffer, self.readOffset)[0]
self.readOffset += 1
return value
def writeUByte(self, value):
self.ensureCapacity(1)
struct.pack_into('>B', self.buffer, self.writeOffset, value)
self.writeOffset += 1
def readUByte(self):
value = struct.unpack_from('>B', self.buffer, self.readOffset)[0]
self.readOffset += 1
return value
def writeShort(self, value):
self.ensureCapacity(1)
struct.pack_into('>h', self.buffer, self.writeOffset, value)
self.writeOffset += 2
def readShort(self):
value = struct.unpack_from('>h', self.buffer, self.readOffset)[0]
self.readOffset += 2
return value
def writeRawInt(self, value):
self.ensureCapacity(4)
struct.pack_into('>i', self.buffer, self.writeOffset, value)
self.writeOffset += 4
def readRawInt(self):
value = struct.unpack_from('>i', self.buffer, self.readOffset)[0]
self.readOffset += 4
return value
def writeInt(self, value):
if not (minInt <= value <= maxInt):
raise ValueError('value must range between minInt:-2147483648 and maxInt:2147483647')
value = (value << 1) ^ (value >> 31)
self.ensureCapacity(5)
if value >> 7 == 0:
self.writeUByte(value)
return
if value >> 14 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte((value >> 7) & 0x7F)
return
if value >> 21 == 0:
self.writeUByte((value & 0x7F) | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte((value >> 14) & 0x7F)
return
if value >> 28 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte((value >> 21) & 0x7F)
return
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte(((value >> 21) & 0x7F | 0x80))
self.writeUByte((value >> 28) & 0x7F)
pass
def readInt(self):
b = self.readUByte()
value = b & 0x7F
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 7
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 14
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 21
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 28
return (value >> 1) ^ -(value & 1)
def writeLong(self, value):
if not (minLong <= value <= maxLong):
raise ValueError('value must range between minLong:-9223372036854775808 and maxLong:9223372036854775807')
value = (value << 1) ^ (value >> 63)
self.ensureCapacity(9)
if value >> 7 == 0:
self.writeUByte(value)
return
if value >> 14 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte((value >> 7) & 0x7F)
return
if value >> 21 == 0:
self.writeUByte((value & 0x7F) | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte((value >> 14) & 0x7F)
return
if value >> 28 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte((value >> 21) & 0x7F)
return
if value >> 35 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte(((value >> 21) & 0x7F | 0x80))
self.writeUByte((value >> 28) & 0x7F)
return
if value >> 42 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte(((value >> 21) & 0x7F | 0x80))
self.writeUByte(((value >> 28) & 0x7F | 0x80))
self.writeUByte((value >> 35) & 0x7F)
return
if value >> 49 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte(((value >> 21) & 0x7F | 0x80))
self.writeUByte(((value >> 28) & 0x7F | 0x80))
self.writeUByte(((value >> 35) & 0x7F | 0x80))
self.writeUByte((value >> 42) & 0x7F)
return
if value >> 56 == 0:
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte(((value >> 21) & 0x7F | 0x80))
self.writeUByte(((value >> 28) & 0x7F | 0x80))
self.writeUByte(((value >> 35) & 0x7F | 0x80))
self.writeUByte(((value >> 42) & 0x7F | 0x80))
self.writeUByte((value >> 49) & 0x7F)
return
self.writeUByte(value & 0x7F | 0x80)
self.writeUByte(((value >> 7) & 0x7F | 0x80))
self.writeUByte(((value >> 14) & 0x7F | 0x80))
self.writeUByte(((value >> 21) & 0x7F | 0x80))
self.writeUByte(((value >> 28) & 0x7F | 0x80))
self.writeUByte(((value >> 35) & 0x7F | 0x80))
self.writeUByte(((value >> 42) & 0x7F | 0x80))
self.writeUByte(((value >> 49) & 0x7F | 0x80))
self.writeUByte(value >> 56)
pass
def readLong(self):
b = self.readUByte()
value = b & 0x7F
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 7
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 14
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 21
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 28
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 35
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 42
if (b & 0x80) != 0:
b = self.readUByte()
value |= (b & 0x7F) << 49
if (b & 0x80) != 0:
b = self.readUByte()
value |= b << 56
return (value >> 1) ^ -(value & 1)
def writeFloat(self, value):
self.ensureCapacity(4)
struct.pack_into('>f', self.buffer, self.writeOffset, value)
self.writeOffset += 4
def readFloat(self):
value = struct.unpack_from('>f', self.buffer, self.readOffset)[0]
self.readOffset += 4
return value
def writeDouble(self, value):
self.ensureCapacity(8)
struct.pack_into('>d', self.buffer, self.writeOffset, value)
self.writeOffset += 8
def readDouble(self):
value = struct.unpack_from('>d', self.buffer, self.readOffset)[0]
self.readOffset += 8
return value
def writeChar(self, value):
if len(value) == 0:
self.writeInt(0)
return
self.writeString(value[0])
def readChar(self):
return self.readString()
def writeString(self, value):
if len(value) == 0:
self.writeInt(0)
return
byte_array = bytearray(value, 'utf-8')
length = len(byte_array)
self.ensureCapacity(5 + length)
self.writeInt(length)
self.buffer[self.writeOffset:self.writeOffset + length] = byte_array[:]
self.writeOffset += length
def readString(self):
length = self.readInt()
if (length <= 0):
return empty_str
byte_array = self.buffer[self.readOffset:self.readOffset + length]
# 使用utf-8编码进行解码
value = byte_array.decode('utf-8')
self.readOffset += length
return value
def writePacketFlag(self, value):
if value is None:
self.writeBool(False)
else:
self.writeBool(True)
pass
@@ -23,6 +23,7 @@ import com.google.protobuf.CodedOutputStream;
import com.zfoo.protocol.collection.ArrayUtils;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.packet.*;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.util.StringUtils;
import io.fury.Fury;
import io.fury.Language;
@@ -375,6 +376,7 @@ public class SpeedTest {
// op.getGenerateLanguages().add(CodeLanguage.Lua);
// op.getGenerateLanguages().add(CodeLanguage.CSharp);
// op.getGenerateLanguages().add(CodeLanguage.GdScript);
op.getGenerateLanguages().add(CodeLanguage.Python);
// 需要protocol协议的字段里面都加上JProtobuf注解才能用
// op.setProtocolParam("protobuf=protobuf.xml");