mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-05-24 08:26:00 +00:00
feat[swift]: support swift protocol
This commit is contained in:
@@ -93,6 +93,7 @@ public abstract class GenerateProtocolNote {
|
||||
case CSharp:
|
||||
case Php:
|
||||
case Dart:
|
||||
case Swift:
|
||||
case Protobuf:
|
||||
note = StringUtils.format("// {}", note);
|
||||
break;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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<ISerializer, ISwiftSerializer> 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<ProtocolRegistration> 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<ProtocolRegistration> 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<ProtocolRegistration> 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", "<Boolean");
|
||||
typeName = typeName.replace("Boolean>", "Boolean>");
|
||||
|
||||
// 将Byte转为byte
|
||||
typeName = typeName.replace("Byte[", "Int8");
|
||||
typeName = typeName.replace("Byte>", "Int8>");
|
||||
typeName = typeName.replace("<Byte", "<Int8");
|
||||
|
||||
// 将Short转为short
|
||||
typeName = typeName.replace("Short[", "Int16");
|
||||
typeName = typeName.replace("Short>", "Int16>");
|
||||
typeName = typeName.replace("<Short", "<Int16");
|
||||
|
||||
// 将Integer转为int
|
||||
typeName = typeName.replace("Integer[", "Int");
|
||||
typeName = typeName.replace("Integer>", "Int>");
|
||||
typeName = typeName.replace("<Integer", "<Int");
|
||||
|
||||
// 将Long转为long
|
||||
typeName = typeName.replace("Long[", "Int64");
|
||||
typeName = typeName.replace("Long>", "Int64>");
|
||||
typeName = typeName.replace("<Long", "<Int64");
|
||||
|
||||
// 将Float转为float
|
||||
typeName = typeName.replace("Float[", "Float32");
|
||||
typeName = typeName.replace("Float>", "Float32>");
|
||||
typeName = typeName.replace("<Float", "<Float32");
|
||||
|
||||
// 将Double转为double
|
||||
typeName = typeName.replace("Double[", "Float64");
|
||||
typeName = typeName.replace("Double>", "Float64>");
|
||||
typeName = typeName.replace("<Double", "<Float64");
|
||||
|
||||
// 将Character转为Char
|
||||
typeName = typeName.replace("Character[", "String");
|
||||
typeName = typeName.replace("Character>", "String>");
|
||||
typeName = typeName.replace("<Character", "<String");
|
||||
|
||||
// 将String转为string
|
||||
typeName = typeName.replace("String[", "String");
|
||||
typeName = typeName.replace("String>", "String>");
|
||||
typeName = typeName.replace("<String", "<String");
|
||||
|
||||
typeName = typeName.replace("Map<", "Dictionary<");
|
||||
typeName = typeName.replace("Set<", "Set<");
|
||||
typeName = typeName.replace("List<", "Array<");
|
||||
|
||||
return typeName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.model.Pair;
|
||||
import com.zfoo.protocol.registration.field.IFieldRegistration;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author godotg
|
||||
*/
|
||||
public interface ISwiftSerializer {
|
||||
/**
|
||||
* 获取属性的类型,默认值
|
||||
*/
|
||||
Pair<String, String> 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);
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
}
|
||||
+62
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
import Foundation
|
||||
|
||||
class ByteBuffer {
|
||||
var buffer: [Int8] = Array<Int8>(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<Int8>(buffer[(currentwriteIndex - length)..<currentwriteIndex])
|
||||
writeOffset = beforewriteIndex
|
||||
writeInt(length)
|
||||
writeBytes(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func compatibleRead(_ beforeReadIndex: Int, _ length: Int) -> 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..<length]
|
||||
writeOffset += length
|
||||
}
|
||||
|
||||
func readBytes(_ length: Int) -> [Int8] {
|
||||
let bytes = buffer[readOffset..<(readOffset + length)]
|
||||
readOffset += length
|
||||
return Array<Int8>(bytes)
|
||||
}
|
||||
|
||||
func toBytes() -> [Int8] {
|
||||
return Array<Int8>(buffer[0..<writeOffset])
|
||||
}
|
||||
|
||||
func getCapacity() -> Int {
|
||||
return buffer.count - writeOffset;
|
||||
}
|
||||
|
||||
func ensureCapacity(_ capacity: Int) {
|
||||
while (capacity - getCapacity() > 0) {
|
||||
let newSize = buffer.count * 2
|
||||
var newBytes = Array<Int8>(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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import Foundation
|
||||
|
||||
protocol IProtocol {
|
||||
func protocolId() -> Int
|
||||
}
|
||||
|
||||
|
||||
protocol IProtocolRegistration {
|
||||
func write(_ buffer: ByteBuffer, _ packet: Any?)
|
||||
|
||||
func read(_ buffer: ByteBuffer) -> Any
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
${protocol_note}
|
||||
class ${protocol_name} : IProtocol {
|
||||
${protocol_field_definition}
|
||||
|
||||
func protocolId() -> Int {
|
||||
return ${protocol_id}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import Foundation
|
||||
|
||||
class ProtocolManager {
|
||||
static var protocols = Dictionary<Int, IProtocolRegistration>()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import Foundation
|
||||
${protocol_imports}
|
||||
${protocol_class}
|
||||
|
||||
${protocol_registration}
|
||||
Reference in New Issue
Block a user