diff --git a/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolNote.java b/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolNote.java index 7abc8a2b..8b8e22a0 100644 --- a/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolNote.java +++ b/protocol/src/main/java/com/zfoo/protocol/generate/GenerateProtocolNote.java @@ -93,6 +93,7 @@ public abstract class GenerateProtocolNote { case CSharp: case Php: case Dart: + case Swift: case Protobuf: note = StringUtils.format("// {}", note); break; diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/CodeLanguage.java b/protocol/src/main/java/com/zfoo/protocol/serializer/CodeLanguage.java index 6dc800d0..871a318e 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/CodeLanguage.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/CodeLanguage.java @@ -27,6 +27,7 @@ import com.zfoo.protocol.serializer.python.CodeGeneratePython; import com.zfoo.protocol.serializer.ruby.CodeGenerateRuby; import com.zfoo.protocol.serializer.rust.CodeGenerateRust; import com.zfoo.protocol.serializer.scala.CodeGenerateScala; +import com.zfoo.protocol.serializer.swift.CodeGenerateSwift; import com.zfoo.protocol.serializer.typescript.CodeGenerateTypeScript; /** @@ -47,6 +48,8 @@ public enum CodeLanguage { Dart(1 << 3, CodeGenerateDart.class), + Swift(1 << 4, CodeGenerateSwift.class), + Cpp(1 << 7, CodeGenerateCpp.class), Rust(1 << 8, CodeGenerateRust.class), diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/CodeGenerateSwift.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/CodeGenerateSwift.java new file mode 100644 index 00000000..4d43d3ca --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/CodeGenerateSwift.java @@ -0,0 +1,390 @@ +/* + * 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.swift; + +import com.zfoo.protocol.anno.Compatible; +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.ProtocolRegistration; +import com.zfoo.protocol.registration.field.IFieldRegistration; +import com.zfoo.protocol.serializer.CodeLanguage; +import com.zfoo.protocol.serializer.CodeTemplatePlaceholder; +import com.zfoo.protocol.serializer.ICodeGenerate; +import com.zfoo.protocol.serializer.reflect.*; +import com.zfoo.protocol.util.ClassUtils; +import com.zfoo.protocol.util.FileUtils; +import com.zfoo.protocol.util.ReflectionUtils; +import com.zfoo.protocol.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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; + + +/** + * @author godotg + */ +public class CodeGenerateSwift implements ICodeGenerate { + private static final Logger logger = LoggerFactory.getLogger(CodeGenerateSwift.class); + + // custom configuration + public static String protocolOutputRootPath = "zfooswift"; + private static String protocolOutputPath = StringUtils.EMPTY; + + private static final Map swiftSerializerMap = new HashMap<>(); + + public static ISwiftSerializer swiftSerializer(ISerializer serializer) { + return swiftSerializerMap.get(serializer); + } + + @Override + public void init(GenerateOperation generateOperation) { + protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath); + FileUtils.deleteFile(new File(protocolOutputPath)); + + swiftSerializerMap.put(BoolSerializer.INSTANCE, new SwiftBoolSerializer()); + swiftSerializerMap.put(ByteSerializer.INSTANCE, new SwiftByteSerializer()); + swiftSerializerMap.put(ShortSerializer.INSTANCE, new SwiftShortSerializer()); + swiftSerializerMap.put(IntSerializer.INSTANCE, new SwiftIntSerializer()); + swiftSerializerMap.put(LongSerializer.INSTANCE, new SwiftLongSerializer()); + swiftSerializerMap.put(FloatSerializer.INSTANCE, new SwiftFloatSerializer()); + swiftSerializerMap.put(DoubleSerializer.INSTANCE, new SwiftDoubleSerializer()); + swiftSerializerMap.put(StringSerializer.INSTANCE, new SwiftStringSerializer()); + swiftSerializerMap.put(ArraySerializer.INSTANCE, new SwiftArraySerializer()); + swiftSerializerMap.put(ListSerializer.INSTANCE, new SwiftListSerializer()); + swiftSerializerMap.put(SetSerializer.INSTANCE, new SwiftSetSerializer()); + swiftSerializerMap.put(MapSerializer.INSTANCE, new SwiftMapSerializer()); + swiftSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new SwiftObjectProtocolSerializer()); + } + + @Override + public void mergerProtocol(List registrations) throws IOException { + createTemplateFile(); + + var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("kotlin/ProtocolManagerTemplate.kt"); + var protocol_manager_registrations = new StringBuilder(); + var protocol_imports = new StringBuilder(); + for (var registration : registrations) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}Registration()", protocol_id, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocolIdMap.put({}::class.java, {})", protocol_name, protocol_id)).append(LS); + } + + var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString() + , CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString()); + var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap); + var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.kt")); + FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true); + logger.info("Generated Swift protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath()); + + var protocol_class = new StringBuilder(); + var protocol_registration = new StringBuilder(); + for (var registration : GenerateProtocolFile.subProtocolFirst(registrations)) { + var protocol_id = registration.protocolId(); + // protocol + protocol_class.append(protocol_class(registration)).append(LS); + // registration + protocol_registration.append(protocol_registration(registration)).append(LS); + } + var protocolTemplate = ClassUtils.getFileFromClassPathToString("kotlin/ProtocolsTemplate.kt"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_imports, StringUtils.EMPTY + , CodeTemplatePlaceholder.protocol_class, protocol_class.toString() + , CodeTemplatePlaceholder.protocol_registration, protocol_registration.toString() + )); + var outputPath = StringUtils.format("{}/Protocols.kt", protocolOutputPath); + var file = new File(outputPath); + FileUtils.writeStringToFile(file, formatProtocolTemplate, true); + logger.info("Generated Swift protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath()); + } + + @Override + public void foldProtocol(List registrations) throws IOException { + createTemplateFile(); + + var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("kotlin/ProtocolManagerTemplate.kt"); + var protocol_manager_registrations = new StringBuilder(); + var protocol_imports = new StringBuilder(); + for (var registration : registrations) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}Registration()", protocol_id, protocol_name)).append(LS); + protocol_manager_registrations.append(StringUtils.format("protocolIdMap[{}::class.java] = {}.toShort()", protocol_name, protocol_id)).append(LS); + } + + var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports.toString() + , CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString()); + var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap); + var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.kt")); + FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true); + logger.info("Generated Swift protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath()); + + for (var registration : registrations) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + var protocolTemplate = ClassUtils.getFileFromClassPathToString("kotlin/ProtocolTemplate.kt"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_class, protocol_class(registration) + , CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration) + )); + var outputPath = StringUtils.format("{}/{}/{}.kt", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name); + var file = new File(outputPath); + FileUtils.writeStringToFile(file, formatProtocolTemplate, true); + logger.info("Generated Swift protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath()); + } + } + + @Override + public void defaultProtocol(List registrations) throws IOException { + createTemplateFile(); + + var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("swift/ProtocolManagerTemplate.swift"); + var protocol_manager_registrations = new StringBuilder(); + for (var registration : registrations) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + protocol_manager_registrations.append(StringUtils.format("protocols[{}] = {}Registration()", protocol_id, protocol_name)).append(LS); + } + + var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString()); + var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap); + var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputRootPath, "ProtocolManager.swift")); + FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true); + logger.info("Generated Swift protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath()); + + for (var registration : registrations) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + var protocolTemplate = ClassUtils.getFileFromClassPathToString("swift/ProtocolTemplate.swift"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_imports, StringUtils.EMPTY + ,CodeTemplatePlaceholder.protocol_class, protocol_class(registration) + , CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration) + )); + var outputPath = StringUtils.format("{}/{}.swift", protocolOutputPath, protocol_name); + var file = new File(outputPath); + FileUtils.writeStringToFile(file, formatProtocolTemplate, true); + logger.info("Generated Swift protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath()); + } + } + + private void createTemplateFile() throws IOException { + var list = List.of("swift/ByteBuffer.swift", "swift/IProtocolRegistration.swift"); + for (var fileName : list) { + var fileInputStream = ClassUtils.getFileFromClassPath(fileName); + var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "swift/"))); + FileUtils.writeInputStreamToFile(createFile, fileInputStream); + } + } + + private String protocol_class(ProtocolRegistration registration) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + var protocolTemplate = ClassUtils.getFileFromClassPathToString("swift/ProtocolClassTemplate.swift"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Swift) + , CodeTemplatePlaceholder.protocol_name, protocol_name + , CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) + , CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(registration) + , CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration) + )); + return formatProtocolTemplate; + } + + private String protocol_registration(ProtocolRegistration registration) { + var protocol_id = registration.protocolId(); + var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName(); + var protocolTemplate = ClassUtils.getFileFromClassPathToString("swift/ProtocolRegistrationTemplate.swift"); + var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of( + CodeTemplatePlaceholder.protocol_name, protocol_name + , CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id) + , CodeTemplatePlaceholder.protocol_write_serialization, protocol_write_serialization(registration) + , CodeTemplatePlaceholder.protocol_read_deserialization, protocol_read_deserialization(registration) + )); + return formatProtocolTemplate; + } + + private String protocol_field_definition(ProtocolRegistration registration) { + var protocolId = registration.getId(); + var fields = registration.getFields(); + var fieldRegistrations = registration.getFieldRegistrations(); + var ktBuilder = 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 fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.Swift); + for (var fieldNote : fieldNotes) { + ktBuilder.append(fieldNote).append(LS); + } + var fieldTypeDefaultValue = swiftSerializer(fieldRegistration.serializer()).fieldTypeDefaultValue(field, fieldRegistration); + var fieldType = fieldTypeDefaultValue.getKey(); + var fieldDefaultValue = fieldTypeDefaultValue.getValue(); + ktBuilder.append(StringUtils.format("var {}: {} = {}", fieldName, fieldType, fieldDefaultValue)).append(LS); + } + return ktBuilder.toString(); + } + + + private String protocol_write_serialization(ProtocolRegistration registration) { + GenerateProtocolFile.localVariableId = 0; + var fields = registration.getFields(); + var fieldRegistrations = registration.getFieldRegistrations(); + var ktBuilder = new StringBuilder(); + if (registration.isCompatible()) { + ktBuilder.append("let beforeWriteIndex = buffer.getWriteOffset()").append(LS); + ktBuilder.append(StringUtils.format("buffer.writeInt({})", registration.getPredictionLength())).append(LS); + } else { + ktBuilder.append("buffer.writeInt(-1)").append(LS); + } + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var fieldRegistration = fieldRegistrations[i]; + swiftSerializer(fieldRegistration.serializer()).writeObject(ktBuilder, "message." + field.getName(), 0, field, fieldRegistration); + } + if (registration.isCompatible()) { + ktBuilder.append(StringUtils.format("buffer.adjustPadding({}, beforeWriteIndex)", registration.getPredictionLength())).append(LS); + } + return ktBuilder.toString(); + } + + + private String protocol_read_deserialization(ProtocolRegistration registration) { + GenerateProtocolFile.localVariableId = 0; + var fields = registration.getFields(); + var fieldRegistrations = registration.getFieldRegistrations(); + var ktBuilder = new StringBuilder(); + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var fieldRegistration = fieldRegistrations[i]; + + if (field.isAnnotationPresent(Compatible.class)) { + ktBuilder.append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS); + var compatibleReadObject = swiftSerializer(fieldRegistration.serializer()).readObject(ktBuilder, 1, field, fieldRegistration); + ktBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", field.getName(), compatibleReadObject)).append(LS); + ktBuilder.append("}").append(LS); + continue; + } + var readObject = swiftSerializer(fieldRegistration.serializer()).readObject(ktBuilder, 0, field, fieldRegistration); + ktBuilder.append(StringUtils.format("packet.{} = {}", field.getName(), readObject)).append(LS); + } + return ktBuilder.toString(); + } + + public static String toSwiftClassName(String typeName) { + typeName = typeName.replaceAll("java.util.|java.lang.", StringUtils.EMPTY); + typeName = typeName.replaceAll("[a-zA-Z0-9_.]*\\.", StringUtils.EMPTY); + + switch (typeName) { + case "boolean": + case "Boolean": + typeName = "Bool"; + return typeName; + case "byte": + case "Byte": + typeName = "Int8"; + return typeName; + case "short": + case "Short": + typeName = "Int16"; + return typeName; + case "int": + case "Integer": + typeName = "Int"; + return typeName; + case "long": + case "Long": + typeName = "Int64"; + return typeName; + case "float": + case "Float": + typeName = "Float32"; + return typeName; + case "double": + case "Double": + typeName = "Float64"; + return typeName; + case "char": + case "Character": + case "String": + typeName = "String"; + return typeName; + default: + } + + // 将boolean转为bool + typeName = typeName.replaceAll("[B|b]oolean\\[", "Boolean"); + typeName = typeName.replace("", "Boolean>"); + + // 将Byte转为byte + typeName = typeName.replace("Byte[", "Int8"); + typeName = typeName.replace("Byte>", "Int8>"); + typeName = typeName.replace("", "Int16>"); + typeName = typeName.replace("", "Int>"); + typeName = typeName.replace("", "Int64>"); + typeName = typeName.replace("", "Float32>"); + typeName = typeName.replace("", "Float64>"); + typeName = typeName.replace("", "String>"); + typeName = typeName.replace("", "String>"); + typeName = typeName.replace(" fieldTypeDefaultValue(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); + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftArraySerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftArraySerializer.java new file mode 100644 index 00000000..96c49458 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftArraySerializer.java @@ -0,0 +1,106 @@ +/* + * 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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftArraySerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + var type = StringUtils.format("Array<{}>", CodeGenerateSwift.toSwiftClassName(field.getType().getComponentType().getSimpleName())); + return new Pair<>(type, "[]"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + if (CutDownArraySerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Swift)) { + return; + } + + ArrayField arrayField = (ArrayField) fieldRegistration; + + builder.append(StringUtils.format("buffer.writeInt({}.count)", objectStr)).append(LS); + GenerateProtocolFile.addTab(builder, deep); + String length = "length" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("let {} = {}.count", length, objectStr)).append(LS); + + String i = "i" + GenerateProtocolFile.localVariableId++; + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("for {} in 0..<{} {", i, length)).append(LS); + GenerateProtocolFile.addTab(builder, deep + 1); + String element = "element" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("let {} = {}[{}]", element, objectStr, i)).append(LS); + + CodeGenerateSwift.swiftSerializer(arrayField.getArrayElementRegistration().serializer()) + .writeObject(builder, element, deep + 1, field, arrayField.getArrayElementRegistration()); + + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + } + + @Override + public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + var cutDown = CutDownArraySerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Swift); + if (cutDown != null) { + return cutDown; + } + + + var arrayField = (ArrayField) fieldRegistration; + var result = "result" + GenerateProtocolFile.localVariableId++; + + var typeName = CodeGenerateSwift.toSwiftClassName(arrayField.getType().getSimpleName()); + + var i = "index" + GenerateProtocolFile.localVariableId++; + var length = "length" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("let {} = buffer.readInt()", length)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("var {} = Array<{}>()", result, typeName)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("if ({} > 0) {", length)).append(LS); + + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append(StringUtils.format("for _ in 0..<{} {", length)).append(LS); + var readObject = CodeGenerateSwift.swiftSerializer(arrayField.getArrayElementRegistration().serializer()) + .readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration()); + GenerateProtocolFile.addTab(builder, deep + 2); + builder.append(StringUtils.format("{}.append({})", result, readObject)); + builder.append(LS); + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append("}").append(LS); + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + + + return result; + } +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftBoolSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftBoolSerializer.java new file mode 100644 index 00000000..406c3ae2 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftBoolSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftBoolSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Bool", "false"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readBool()", result)).append(LS); + return result; + } +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftByteSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftByteSerializer.java new file mode 100644 index 00000000..4b3bc154 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftByteSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftByteSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Int8", "0"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readByte()", result)).append(LS); + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftDoubleSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftDoubleSerializer.java new file mode 100644 index 00000000..80a75190 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftDoubleSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftDoubleSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Float64", "0.0"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readDouble()", result)).append(LS); + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftFloatSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftFloatSerializer.java new file mode 100644 index 00000000..bf23f185 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftFloatSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftFloatSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Float32", "0.0"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readFloat()", result)).append(LS); + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftIntSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftIntSerializer.java new file mode 100644 index 00000000..1dfb8d0c --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftIntSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftIntSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Int", "0"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readInt()", result)).append(LS); + return result; + } +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftListSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftListSerializer.java new file mode 100644 index 00000000..aad9b7be --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftListSerializer.java @@ -0,0 +1,99 @@ +/* + * 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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftListSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + var type = StringUtils.format("{}", CodeGenerateSwift.toSwiftClassName(field.getGenericType().toString())); + return new Pair<>(type, "[]"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + if (CutDownListSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Swift)) { + return; + } + + ListField listField = (ListField) fieldRegistration; + + builder.append(StringUtils.format("buffer.writeInt({}.count)", objectStr)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + String element = "element" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("for {} in {} {", element, objectStr)).append(LS); + + CodeGenerateSwift.swiftSerializer(listField.getListElementRegistration().serializer()) + .writeObject(builder, element, deep + 1, field, listField.getListElementRegistration()); + + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + } + + @Override + public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + var cutDown = CutDownListSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Swift); + if (cutDown != null) { + return cutDown; + } + + var listField = (ListField) fieldRegistration; + var result = "result" + GenerateProtocolFile.localVariableId++; + + var typeName = CodeGenerateSwift.toSwiftClassName(listField.getType().toString()); + + var i = "index" + GenerateProtocolFile.localVariableId++; + var size = "size" + GenerateProtocolFile.localVariableId++; + + builder.append(StringUtils.format("let {} = buffer.readInt()", size)).append(LS); + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("var {} = {}()", result, typeName)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS); + + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append(StringUtils.format("for _ in 0..<{} {", size)).append(LS); + var readObject = CodeGenerateSwift.swiftSerializer(listField.getListElementRegistration().serializer()) + .readObject(builder, deep + 2, field, listField.getListElementRegistration()); + GenerateProtocolFile.addTab(builder, deep + 2); + builder.append(StringUtils.format("{}.append({})", result, readObject)).append(LS); + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append("}").append(LS); + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + + + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftLongSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftLongSerializer.java new file mode 100644 index 00000000..2ae1cce9 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftLongSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftLongSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Int64", "0"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readLong()", result)).append(LS); + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftMapSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftMapSerializer.java new file mode 100644 index 00000000..b802f70f --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftMapSerializer.java @@ -0,0 +1,107 @@ +/* + * 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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftMapSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + var type = StringUtils.format("{}", CodeGenerateSwift.toSwiftClassName(field.getGenericType().toString())); + return new Pair<>(type, "[:]"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + if (CutDownMapSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Swift)) { + return; + } + + MapField mapField = (MapField) fieldRegistration; + + builder.append(StringUtils.format("buffer.writeInt({}.count)", objectStr)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + String key = "keyElement" + GenerateProtocolFile.localVariableId++; + String value = "valueElement" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("for ({}, {}) in {} {", key,value, objectStr)).append(LS); + + CodeGenerateSwift.swiftSerializer(mapField.getMapKeyRegistration().serializer()) + .writeObject(builder, key, deep + 1, field, mapField.getMapKeyRegistration()); + CodeGenerateSwift.swiftSerializer(mapField.getMapValueRegistration().serializer()) + .writeObject(builder, value, deep + 1, field, mapField.getMapValueRegistration()); + + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + } + + + @Override + public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + var cutDown = CutDownMapSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Swift); + if (cutDown != null) { + return cutDown; + } + + MapField mapField = (MapField) fieldRegistration; + String result = "result" + GenerateProtocolFile.localVariableId++; + + var typeName = CodeGenerateSwift.toSwiftClassName(mapField.getType().toString()); + + String size = "size" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("let {} = buffer.readInt()", size)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("var {} = {}()", result, typeName)).append(LS); + + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS); + + String i = "index" + GenerateProtocolFile.localVariableId++; + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append(StringUtils.format("for _ in 0..<{} {", size)).append(LS); + + String keyObject = CodeGenerateSwift.swiftSerializer(mapField.getMapKeyRegistration().serializer()) + .readObject(builder, deep + 2, field, mapField.getMapKeyRegistration()); + + + String valueObject = CodeGenerateSwift.swiftSerializer(mapField.getMapValueRegistration().serializer()) + .readObject(builder, deep + 2, field, mapField.getMapValueRegistration()); + GenerateProtocolFile.addTab(builder, deep + 2); + + builder.append(StringUtils.format("{}[{}] = {}", result, keyObject, valueObject)).append(LS); + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append("}").append(LS); + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + return result; + } +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftObjectProtocolSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftObjectProtocolSerializer.java new file mode 100644 index 00000000..bf08dbdb --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftObjectProtocolSerializer.java @@ -0,0 +1,62 @@ +/* + * 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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +import com.zfoo.protocol.registration.field.IFieldRegistration; +import com.zfoo.protocol.registration.field.ObjectProtocolField; +import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer; +import com.zfoo.protocol.util.StringUtils; + +import java.lang.reflect.Field; + +import static com.zfoo.protocol.util.FileUtils.LS; + + +/** + * @author godotg + */ +public class SwiftObjectProtocolSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration; + var protocolSimpleName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(objectProtocolField.getProtocolId()); + var type = StringUtils.format("{}?", protocolSimpleName); + return new Pair<>(type, "nil"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + ObjectProtocolField objectProtocolField = (ObjectProtocolField) fieldRegistration; + GenerateProtocolFile.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; + String result = "result" + GenerateProtocolFile.localVariableId++; + + var protocolSimpleName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(objectProtocolField.getProtocolId()); + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readPacket({}) as! {}", result, objectProtocolField.getProtocolId(), protocolSimpleName)) + .append(LS); + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftSetSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftSetSerializer.java new file mode 100644 index 00000000..e13d3e7e --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftSetSerializer.java @@ -0,0 +1,98 @@ +/* + * 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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftSetSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + var type = StringUtils.format("{}", CodeGenerateSwift.toSwiftClassName(field.getGenericType().toString())); + return new Pair<>(type, "[]"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + if (CutDownSetSerializer.getInstance().writeObject(builder, objectStr, field, fieldRegistration, CodeLanguage.Swift)) { + return; + } + + SetField setField = (SetField) fieldRegistration; + + builder.append(StringUtils.format("buffer.writeInt({}.count)", objectStr)).append(LS); + + String element = "i" + GenerateProtocolFile.localVariableId++; + GenerateProtocolFile.addTab(builder, deep ); + builder.append(StringUtils.format("for {} in {} {", element, objectStr)).append(LS); + + CodeGenerateSwift.swiftSerializer(setField.getSetElementRegistration().serializer()) + .writeObject(builder, element, deep + 1, field, setField.getSetElementRegistration()); + + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + } + + @Override + public String readObject(StringBuilder builder, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.addTab(builder, deep); + var cutDown = CutDownSetSerializer.getInstance().readObject(builder, field, fieldRegistration, CodeLanguage.Swift); + if (cutDown != null) { + return cutDown; + } + + SetField setField = (SetField) fieldRegistration; + var result = "result" + GenerateProtocolFile.localVariableId++; + + var typeName = CodeGenerateSwift.toSwiftClassName(setField.getType().toString()); + + var i = "index" + GenerateProtocolFile.localVariableId++; + var size = "size" + GenerateProtocolFile.localVariableId++; + builder.append(StringUtils.format("let {} = buffer.readInt()", size)).append(LS); + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("var {} = {}()", result, typeName)).append(LS); + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS); + + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append(StringUtils.format("for _ in 0..<{} {", size)).append(LS); + + var readObject = CodeGenerateSwift.swiftSerializer(setField.getSetElementRegistration().serializer()) + .readObject(builder, deep + 2, field, setField.getSetElementRegistration()); + GenerateProtocolFile.addTab(builder, deep + 2); + builder.append(StringUtils.format("{}.insert({})", result, readObject)).append(LS); + GenerateProtocolFile.addTab(builder, deep + 1); + builder.append("}").append(LS); + GenerateProtocolFile.addTab(builder, deep); + builder.append("}").append(LS); + + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftShortSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftShortSerializer.java new file mode 100644 index 00000000..f354c623 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftShortSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftShortSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("Int16", "0"); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readShort()", result)).append(LS); + return result; + } + +} diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftStringSerializer.java b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftStringSerializer.java new file mode 100644 index 00000000..b2ffb047 --- /dev/null +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/swift/SwiftStringSerializer.java @@ -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.swift; + +import com.zfoo.protocol.generate.GenerateProtocolFile; +import com.zfoo.protocol.model.Pair; +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 + */ +public class SwiftStringSerializer implements ISwiftSerializer { + + @Override + public Pair fieldTypeDefaultValue(Field field, IFieldRegistration fieldRegistration) { + return new Pair<>("String", "\"\""); + } + + @Override + public void writeObject(StringBuilder builder, String objectStr, int deep, Field field, IFieldRegistration fieldRegistration) { + GenerateProtocolFile.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.localVariableId++; + + GenerateProtocolFile.addTab(builder, deep); + builder.append(StringUtils.format("let {} = buffer.readString()", result)).append(LS); + return result; + } + + +} diff --git a/protocol/src/main/resources/swift/ByteBuffer.swift b/protocol/src/main/resources/swift/ByteBuffer.swift new file mode 100644 index 00000000..1be8b601 --- /dev/null +++ b/protocol/src/main/resources/swift/ByteBuffer.swift @@ -0,0 +1,367 @@ +import Foundation + +class ByteBuffer { + var buffer: [Int8] = Array(repeating: 0, count: 128) + var writeOffset: Int = 0 + var readOffset: Int = 0 + + func adjustPadding(_ predictionLength: Int, _ beforewriteIndex: Int) { + // 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置 + let currentwriteIndex = writeOffset + let predictionCount = writeIntCount(predictionLength) + let length = currentwriteIndex - beforewriteIndex - predictionCount + let lengthCount = writeIntCount(length) + let padding = lengthCount - predictionCount + if (padding == 0) { + writeOffset = beforewriteIndex + writeInt(length) + writeOffset = currentwriteIndex + } else { + let bytes = Array(buffer[(currentwriteIndex - length).. Bool { + return length != -1 && readOffset < length + beforeReadIndex + } + + func getBuffer() -> [Int8] { + return buffer + } + + func getWriteOffset() -> Int { + return writeOffset + } + + func setWriteOffset(_ writeIndex: Int) { + writeOffset = writeIndex + } + + func getReadOffset() -> Int { + return readOffset + } + + func setReadOffset(_ readIndex: Int) { + readOffset = readIndex + } + + func isReadable() -> Bool { + return writeOffset > readOffset + } + + func writeBytes(_ bytes: [Int8]) { + let length = bytes.count + buffer[writeOffset..<(writeOffset + length)] = bytes[0.. [Int8] { + let bytes = buffer[readOffset..<(readOffset + length)] + readOffset += length + return Array(bytes) + } + + func toBytes() -> [Int8] { + return Array(buffer[0.. Int { + return buffer.count - writeOffset; + } + + func ensureCapacity(_ capacity: Int) { + while (capacity - getCapacity() > 0) { + let newSize = buffer.count * 2 + var newBytes = Array(repeating: 0, count: newSize) + newBytes.append(contentsOf: buffer) + buffer = newBytes + } + } + + func writeBool(_ value: Bool) { + ensureCapacity(1) + buffer[writeOffset] = value ? 1 : 0 + writeOffset += 1 + } + + func readBool() -> Bool { + let value = buffer[readOffset] == 1 ? true : false + readOffset += 1 + return value + } + + func writeByte(_ value: Int8) { + ensureCapacity(1) + buffer[writeOffset] = value + writeOffset += 1 + } + + func readByte() -> Int8 { + let value = buffer[readOffset] + readOffset += 1 + return value + } + + func writeUByte(_ value: UInt8) { + ensureCapacity(1) + buffer[writeOffset] = Int8(bitPattern: value) + writeOffset += 1 + } + + func readUByte() -> UInt8 { + let value = buffer[readOffset] + readOffset += 1 + return UInt8(bitPattern: value) + } + + func writeShort(_ value: Int16) { + ensureCapacity(2) + buffer[writeOffset] = Int8(bitPattern: UInt8(value >> 8 & 0xFF)) + buffer[writeOffset + 1] = Int8(bitPattern: UInt8(value & 0xFF)) + writeOffset += 2 + } + + func readShort() -> Int16 { + let value = Int16(UInt8(bitPattern: buffer[readOffset])) << 8 | Int16(UInt8(bitPattern: buffer[readOffset + 1])) + readOffset += 2 + return value + } + + func writeIntCount(_ intValue: Int) -> Int { + let longValue = Int64(intValue) + let value = UInt64(bitPattern: ((longValue << 1) ^ (longValue >> 63))) + if (value >> 7 == 0) { + return 1 + } + if (value >> 14 == 0) { + return 2 + } + if (value >> 21 == 0) { + return 3 + } + + if (value >> 28 == 0) { + return 4 + } + return 5 + } + + func writeRawInt(_ value: Int32) { + writeUByte(UInt8(value >> 24 & 0xFF)) + writeUByte(UInt8(value >> 16 & 0xFF)) + writeUByte(UInt8(value >> 8 & 0xFF)) + writeUByte(UInt8(value & 0xFF)) + } + + func readRawInt() -> Int32 { + let value = Int32(readUByte()) << 24 | Int32(readUByte()) << 16 | Int32(readUByte()) << 8 | Int32(readUByte()) + return value + } + + func writeRawLong(_ value: Int64) { + writeUByte(UInt8(value >> 56 & 0xFF)) + writeUByte(UInt8(value >> 48 & 0xFF)) + writeUByte(UInt8(value >> 40 & 0xFF)) + writeUByte(UInt8(value >> 32 & 0xFF)) + writeUByte(UInt8(value >> 24 & 0xFF)) + writeUByte(UInt8(value >> 16 & 0xFF)) + writeUByte(UInt8(value >> 8 & 0xFF)) + writeUByte(UInt8(value & 0xFF)) + } + + func readRawLong() -> Int64 { + let value = Int64(readUByte()) << 56 | Int64(readUByte()) << 48 | Int64(readUByte()) << 40 | Int64(readUByte()) << 32 | Int64(readUByte()) << 24 | Int64(readUByte()) << 16 | Int64(readUByte()) << 8 | Int64(readUByte()) + return value + } + + func writeInt(_ value: Int) { + var v = value + if (v > 2147483647) { + v = 2147483647 + } else if (v < -2147483648) { + v = -2147483648 + } + writeLong(Int64(v)) + } + + func readInt() -> Int { + return Int(readLong()) + } + + func writeLong(_ longValue: Int64) { + let value = UInt64(bitPattern: ((longValue << 1) ^ (longValue >> 63))) + + if (value >> 7 == 0) { + writeUByte(UInt8(value)) + return; + } + + if (value >> 14 == 0) { + writeUByte(UInt8((value & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 7)) + return; + } + + if (value >> 21 == 0) { + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 14)) + return; + } + + if ((value >> 28) == 0) { + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 14 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 21)) + return; + } + + if (value >> 35 == 0) { + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 14 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 21 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 28)) + return; + } + + if (value >> 42 == 0) { + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 14 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 21 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 28 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 35)) + return; + } + + if (value >> 49 == 0) { + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 14 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 21 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 28 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 35 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 42)) + return; + } + + if ((value >> 56) == 0) { + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 14 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 21 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 28 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 35 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 42 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 49)) + return; + } + + writeUByte(UInt8(value & 0x7F | 0x80)) + writeUByte(UInt8((value >> 7 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 14 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 21 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 28 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 35 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 42 & 0x7F) | 0x80)) + writeUByte(UInt8((value >> 49 & 0x7F) | 0x80)) + writeUByte(UInt8(value >> 56)) + } + + func readLong() -> Int64 { + var b = UInt64(readUByte()) + var value = b & 0x7F + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 7 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 14 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 21 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 28 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 35 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 42 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= (b & 0x7F) << 49 + if ((b & 0x80) != 0) { + b = UInt64(readUByte()) + value |= b << 56 + } + } + } + } + } + } + } + } + return Int64(bitPattern: value >> 1) ^ -(Int64(bitPattern: value) & 1) + } + + func writeFloat(_ value: Float32) { + let v = value.bitPattern.bigEndian + writeRawInt(Int32(bitPattern: v)) + } + + func readFloat() -> Float32 { + let value = UInt32(bitPattern: readRawInt()).bigEndian + return Float32(bitPattern: value) + } + + func writeDouble(_ value: Float64) { + let v = value.bitPattern.bigEndian + writeRawLong(Int64(bitPattern: v)) + } + + func readDouble() -> Float64 { + let value = UInt64(bitPattern: readRawLong()).bigEndian + return Float64(bitPattern: value) + } + + func writeString(_ value: String) { + if (value.isEmpty) { + writeInt(0) + return + } + if let data = value.data(using: .utf8) { + let byteArray = [UInt8](data) + let bytes = byteArray.map { Int8(bitPattern: $0) } + writeInt(bytes.count) + writeBytes(bytes) + } + } + + func readString() -> String { + let length = readInt() + if (length <= 0) { + return "" + } + let int8Array = readBytes(length) + let bytes = int8Array.map { UInt8(bitPattern: $0) } + let value = String(bytes: bytes, encoding: .utf8)! + return value + } + + func writePacket(_ packet: Any?, _ protocolId: Int) { + let pro = ProtocolManager.getProtocol(protocolId) + pro.write(self, packet) + } + + func readPacket(_ protocolId: Int) -> Any { + let pro = ProtocolManager.getProtocol(protocolId) + return pro.read(self) + } +} diff --git a/protocol/src/main/resources/swift/IProtocolRegistration.swift b/protocol/src/main/resources/swift/IProtocolRegistration.swift new file mode 100644 index 00000000..710cf6dc --- /dev/null +++ b/protocol/src/main/resources/swift/IProtocolRegistration.swift @@ -0,0 +1,12 @@ +import Foundation + +protocol IProtocol { + func protocolId() -> Int +} + + +protocol IProtocolRegistration { + func write(_ buffer: ByteBuffer, _ packet: Any?) + + func read(_ buffer: ByteBuffer) -> Any +} diff --git a/protocol/src/main/resources/swift/ProtocolClassTemplate.swift b/protocol/src/main/resources/swift/ProtocolClassTemplate.swift new file mode 100644 index 00000000..eaffe8c6 --- /dev/null +++ b/protocol/src/main/resources/swift/ProtocolClassTemplate.swift @@ -0,0 +1,8 @@ +${protocol_note} +class ${protocol_name} : IProtocol { + ${protocol_field_definition} + + func protocolId() -> Int { + return ${protocol_id} + } +} \ No newline at end of file diff --git a/protocol/src/main/resources/swift/ProtocolManagerTemplate.swift b/protocol/src/main/resources/swift/ProtocolManagerTemplate.swift new file mode 100644 index 00000000..81ca1a52 --- /dev/null +++ b/protocol/src/main/resources/swift/ProtocolManagerTemplate.swift @@ -0,0 +1,28 @@ +import Foundation + +class ProtocolManager { + static var protocols = Dictionary() + + static func initProtocol() { + // initProtocol + ${protocol_manager_registrations} + } + + static func getProtocol(_ protocolId: Int) -> IProtocolRegistration { + return protocols[protocolId]! + } + + static func write(_ buffer: ByteBuffer, _ packet: Any) { + let p = packet as! IProtocol + let protocolId = p.protocolId() + let pro = getProtocol(protocolId) + buffer.writeShort(Int16(protocolId)) + pro.write(buffer, p) + } + + static func read(_ buffer: ByteBuffer) -> Any { + let protocolId = buffer.readShort() + let pro = getProtocol(Int(protocolId)) + return pro.read(buffer) + } +} diff --git a/protocol/src/main/resources/swift/ProtocolRegistrationTemplate.swift b/protocol/src/main/resources/swift/ProtocolRegistrationTemplate.swift new file mode 100644 index 00000000..c55dac7f --- /dev/null +++ b/protocol/src/main/resources/swift/ProtocolRegistrationTemplate.swift @@ -0,0 +1,24 @@ +class ${protocol_name}Registration : IProtocolRegistration { + func write(_ buffer: ByteBuffer, _ packet: Any?) { + if (packet == nil) { + buffer.writeInt(0) + return + } + let message = packet as! ${protocol_name} + ${protocol_write_serialization} + } + + func read(_ buffer: ByteBuffer) -> Any { + let length = buffer.readInt() + let packet = ${protocol_name}() + if (length == 0) { + return packet + } + let beforeReadIndex = buffer.getReadOffset() + ${protocol_read_deserialization} + if (length > 0) { + buffer.setReadOffset(beforeReadIndex + length) + } + return packet + } +} diff --git a/protocol/src/main/resources/swift/ProtocolTemplate.swift b/protocol/src/main/resources/swift/ProtocolTemplate.swift new file mode 100644 index 00000000..df07a1d7 --- /dev/null +++ b/protocol/src/main/resources/swift/ProtocolTemplate.swift @@ -0,0 +1,5 @@ +import Foundation +${protocol_imports} +${protocol_class} + +${protocol_registration} \ No newline at end of file