feat[php]: php support

This commit is contained in:
godotg
2024-07-11 16:20:46 +08:00
parent a0b6b8c573
commit 4497a02329
24 changed files with 2358 additions and 4 deletions
@@ -90,6 +90,7 @@ public abstract class GenerateProtocolNote {
case EcmaScript:
case TypeScript:
case CSharp:
case Php:
case Protobuf:
note = StringUtils.format("// {}", note);
break;
@@ -21,6 +21,7 @@ import com.zfoo.protocol.serializer.java.CodeGenerateJava;
import com.zfoo.protocol.serializer.javascript.CodeGenerateJavaScript;
import com.zfoo.protocol.serializer.kotlin.CodeGenerateKotlin;
import com.zfoo.protocol.serializer.lua.CodeGenerateLua;
import com.zfoo.protocol.serializer.php.CodeGeneratePhp;
import com.zfoo.protocol.serializer.python.CodeGeneratePython;
import com.zfoo.protocol.serializer.scala.CodeGenerateScala;
import com.zfoo.protocol.serializer.typescript.CodeGenerateTypeScript;
@@ -59,6 +60,8 @@ public enum CodeLanguage {
Python(1 << 22, CodeGeneratePython.class),
Php(1 << 28, CodeGeneratePhp.class),
Protobuf(1 << 30, null);
public final int id;
@@ -0,0 +1,405 @@
/*
* 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.php;
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.ProtocolAnalysis;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.CodeTemplatePlaceholder;
import com.zfoo.protocol.serializer.ICodeGenerate;
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
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 CodeGeneratePhp implements ICodeGenerate {
private static final Logger logger = LoggerFactory.getLogger(CodeGeneratePhp.class);
// custom configuration
public static String protocolOutputRootPath = "zfoophp";
private static String protocolOutputPath = StringUtils.EMPTY;
private static final Map<ISerializer, IPhpSerializer> phpSerializerMap = new HashMap<>();
public static IPhpSerializer phpSerializer(ISerializer serializer) {
return phpSerializerMap.get(serializer);
}
@Override
public void init(GenerateOperation generateOperation) {
protocolOutputPath = FileUtils.joinPath(generateOperation.getProtocolPath(), protocolOutputRootPath);
FileUtils.deleteFile(new File(protocolOutputPath));
phpSerializerMap.put(BooleanSerializer.INSTANCE, new PhpBooleanSerializer());
phpSerializerMap.put(ByteSerializer.INSTANCE, new PhpByteSerializer());
phpSerializerMap.put(ShortSerializer.INSTANCE, new PhpShortSerializer());
phpSerializerMap.put(IntSerializer.INSTANCE, new PhpIntSerializer());
phpSerializerMap.put(LongSerializer.INSTANCE, new PhpLongSerializer());
phpSerializerMap.put(FloatSerializer.INSTANCE, new PhpFloatSerializer());
phpSerializerMap.put(DoubleSerializer.INSTANCE, new PhpDoubleSerializer());
phpSerializerMap.put(StringSerializer.INSTANCE, new PhpStringSerializer());
phpSerializerMap.put(ArraySerializer.INSTANCE, new PhpArraySerializer());
phpSerializerMap.put(ListSerializer.INSTANCE, new PhpListSerializer());
phpSerializerMap.put(SetSerializer.INSTANCE, new PhpSetSerializer());
phpSerializerMap.put(MapSerializer.INSTANCE, new PhpMapSerializer());
phpSerializerMap.put(ObjectProtocolSerializer.INSTANCE, new PhpObjectProtocolSerializer());
}
@Override
public void mergerProtocol(List<ProtocolRegistration> registrations) throws IOException {
createTemplateFile();
// 生成ProtocolManager.ts文件
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolManagerTemplate.ts");
var protocol_imports_manager = new StringBuilder();
var protocol_manager_registrations = new StringBuilder();
protocol_imports_manager.append("import * as Protocols from './Protocols';").append(LS);
for (var registration : registrations) {
var protocol_id = registration.protocolId();
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new Protocols.{}Registration());", protocol_id, protocol_name)).append(LS);
protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set(Protocols.{}, {});", protocol_name, protocol_id)).append(LS);
}
var placeholderMap = Map.of(CodeTemplatePlaceholder.protocol_imports, protocol_imports_manager.toString()
, CodeTemplatePlaceholder.protocol_manager_registrations, protocol_manager_registrations.toString());
var formatProtocolManagerTemplate = CodeTemplatePlaceholder.formatTemplate(protocolManagerTemplate, placeholderMap);
var protocolManagerFile = new File(StringUtils.format("{}/{}", protocolOutputPath, "ProtocolManager.ts"));
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
logger.info("Generated TypeScript protocol manager file:[{}] is in path:[{}]", protocolManagerFile.getName(), protocolManagerFile.getAbsolutePath());
var protocol_imports_protocols = new StringBuilder();
protocol_imports_protocols.append("import IByteBuffer from './IByteBuffer';").append(LS);
protocol_imports_protocols.append("import IProtocolRegistration from './IProtocolRegistration';").append(LS);
var protocol_class = new StringBuilder();
var protocol_registration = new StringBuilder();
for (var registration : registrations) {
protocol_class.append(protocol_class(registration).replace("class ", "export class ")).append(LS);
protocol_registration.append(protocol_registration(registration)).append(LS);
}
var protocolTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolsTemplate.ts");
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
CodeTemplatePlaceholder.protocol_imports, protocol_imports_protocols.toString()
, CodeTemplatePlaceholder.protocol_class, protocol_class.toString()
, CodeTemplatePlaceholder.protocol_registration, protocol_registration.toString()
));
var outputPath = StringUtils.format("{}/Protocols.ts", protocolOutputPath);
var file = new File(outputPath);
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
logger.info("Generated TypeScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
}
@Override
public void foldProtocol(List<ProtocolRegistration> registrations) throws IOException {
createTemplateFile();
// 生成ProtocolManager.ts文件
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("typescript/ProtocolManagerTemplate.ts");
var protocol_imports = new StringBuilder();
var protocol_manager_registrations = new StringBuilder();
for (var registration : registrations) {
var protocol_id = registration.protocolId();
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
protocol_imports.append(StringUtils.format("import {} from './{}/{}';", protocol_name, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS);
protocol_imports.append(StringUtils.format("import { {}Registration } from './{}/{}';", protocol_name, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name)).append(LS);
protocol_manager_registrations.append(StringUtils.format("protocols.set({}, new {}Registration());", protocol_id, protocol_name)).append(LS);
protocol_manager_registrations.append(StringUtils.format("protocolIdMap.set({}, {});", 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("{}/{}", protocolOutputPath, "ProtocolManager.ts"));
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
logger.info("Generated TypeScript 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("typescript/ProtocolTemplate.ts");
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
, CodeTemplatePlaceholder.protocol_name, protocol_name
, CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
, CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
));
var outputPath = StringUtils.format("{}/{}/{}.ts", protocolOutputPath, GenerateProtocolPath.protocolPathSlash(protocol_id), protocol_name);
var file = new File(outputPath);
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
logger.info("Generated TypeScript protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
}
}
@Override
public void defaultProtocol(List<ProtocolRegistration> registrations) throws IOException {
createTemplateFile();
// 生成ProtocolManager.ts文件
var protocolManagerTemplate = ClassUtils.getFileFromClassPathToString("php/ProtocolManagerTemplate.php");
var protocol_imports = new StringBuilder();
var protocol_manager_registrations = new StringBuilder();
for (var registration : registrations) {
var protocol_id = registration.protocolId();
var protocol_name = registration.protocolConstructor().getDeclaringClass().getSimpleName();
protocol_imports.append(StringUtils.format("include_once '{}.php';", protocol_name, protocol_name)).append(LS);
protocol_manager_registrations.append(StringUtils.format("self::$protocols[{}] = new {}Registration();", protocol_id, protocol_name)).append(LS);
protocol_manager_registrations.append(StringUtils.format("self::$protocolIdMap[{}::class] = {};", 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("{}/{}", protocolOutputPath, "ProtocolManager.php"));
FileUtils.writeStringToFile(protocolManagerFile, formatProtocolManagerTemplate, true);
logger.info("Generated Php 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("php/ProtocolTemplate.php");
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
CodeTemplatePlaceholder.protocol_name, protocol_name
, CodeTemplatePlaceholder.protocol_imports, protocol_imports_default(registration)
, CodeTemplatePlaceholder.protocol_class, protocol_class(registration)
, CodeTemplatePlaceholder.protocol_registration, protocol_registration(registration)
));
var outputPath = StringUtils.format("{}/{}.php", protocolOutputPath, protocol_name);
var file = new File(outputPath);
FileUtils.writeStringToFile(file, formatProtocolTemplate, true);
logger.info("Generated Php protocol file:[{}] is in path:[{}]", file.getName(), file.getAbsolutePath());
}
}
private void createTemplateFile() throws IOException {
var list = List.of("php/IProtocolRegistration.php", "php/ByteBuffer.php");
for (var fileName : list) {
var fileInputStream = ClassUtils.getFileFromClassPath(fileName);
var createFile = new File(StringUtils.format("{}/{}", protocolOutputPath, StringUtils.substringAfterFirst(fileName, "php/")));
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("php/ProtocolClassTemplate.php");
var formatProtocolTemplate = CodeTemplatePlaceholder.formatTemplate(protocolTemplate, Map.of(
CodeTemplatePlaceholder.protocol_note, GenerateProtocolNote.protocol_note(protocol_id, CodeLanguage.Php)
, CodeTemplatePlaceholder.protocol_name, protocol_name
, CodeTemplatePlaceholder.protocol_id, String.valueOf(protocol_id)
, CodeTemplatePlaceholder.protocol_field_definition, protocol_field_definition(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("php/ProtocolRegistrationTemplate.php");
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_imports_default(ProtocolRegistration registration) {
// import IByteBuffer first
var protocolId = registration.getId();
var importBuilder = new StringBuilder();
importBuilder.append(StringUtils.format("include_once 'IProtocolRegistration.php';")).append(LS);
// import other sub protocols
var subProtocols = ProtocolAnalysis.getFirstSubProtocolIds(protocolId);
for (var subProtocolId : subProtocols) {
var protocolName = EnhanceObjectProtocolSerializer.getProtocolClassSimpleName(subProtocolId);
importBuilder.append(StringUtils.format("include_once '{}.php';", protocolName, protocolName)).append(LS);
}
return importBuilder.toString();
}
private String protocol_field_definition(ProtocolRegistration registration) {
var protocolId = registration.protocolId();
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
// when generate source code fields, use origin fields sort
var sequencedFields = ReflectionUtils.notStaticAndTransientFields(registration.getConstructor().getDeclaringClass());
var phpBuilder = new StringBuilder();
for (var field : sequencedFields) {
var fieldRegistration = fieldRegistrations[GenerateProtocolFile.indexOf(fields, field)];
var fieldName = field.getName();
// 生成注释
var fieldNotes = GenerateProtocolNote.fieldNotes(protocolId, fieldName, CodeLanguage.Php);
for (var fieldNote : fieldNotes) {
phpBuilder.append(fieldNote).append(LS);
}
var pair = phpSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
phpBuilder.append(StringUtils.format("var {} ${} = {};", pair.getKey(), fieldName, pair.getValue())).append(LS);
}
return phpBuilder.toString();
}
private String protocol_write_serialization(ProtocolRegistration registration) {
GenerateProtocolFile.localVariableId = 0;
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var phpBuilder = new StringBuilder();
if (registration.isCompatible()) {
phpBuilder.append("$beforeWriteIndex = $buffer->getWriteOffset();").append(LS);
phpBuilder.append(StringUtils.format("$buffer->writeInt({});", registration.getPredictionLength())).append(LS);
} else {
phpBuilder.append("$buffer->writeInt(-1);").append(LS);
}
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
phpSerializer(fieldRegistration.serializer()).writeObject(phpBuilder, "$packet->" + field.getName(), 0, field, fieldRegistration);
}
if (registration.isCompatible()) {
phpBuilder.append(StringUtils.format("$buffer->adjustPadding({}, $beforeWriteIndex);", registration.getPredictionLength())).append(LS);
}
return phpBuilder.toString();
}
private String protocol_read_deserialization(ProtocolRegistration registration) {
GenerateProtocolFile.localVariableId = 0;
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var phpBuilder = new StringBuilder();
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
if (field.isAnnotationPresent(Compatible.class)) {
phpBuilder.append("if ($buffer->compatibleRead($beforeReadIndex, $length)) {").append(LS);
var compatibleReadObject = phpSerializer(fieldRegistration.serializer()).readObject(phpBuilder, 1, field, fieldRegistration);
phpBuilder.append(TAB).append(StringUtils.format("$packet->{} = {};", field.getName(), compatibleReadObject)).append(LS);
phpBuilder.append("}").append(LS);
continue;
}
var readObject = phpSerializer(fieldRegistration.serializer()).readObject(phpBuilder, 0, field, fieldRegistration);
phpBuilder.append(StringUtils.format("$packet->{} = {};", field.getName(), readObject)).append(LS);
}
return phpBuilder.toString();
}
public static String toTsClassName(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 = "boolean";
return typeName;
case "byte":
case "Byte":
case "short":
case "Short":
case "int":
case "Integer":
case "long":
case "Long":
case "float":
case "Float":
case "double":
case "Double":
typeName = "number";
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[", "number");
typeName = typeName.replace("Byte>", "number>");
typeName = typeName.replace("<Byte", "<number");
// 将Short转为short
typeName = typeName.replace("Short[", "number");
typeName = typeName.replace("Short>", "number>");
typeName = typeName.replace("<Short", "<number");
// 将Integer转为int
typeName = typeName.replace("Integer[", "number");
typeName = typeName.replace("Integer>", "number>");
typeName = typeName.replace("<Integer", "<number");
// 将Long转为long
typeName = typeName.replace("Long[", "number");
typeName = typeName.replace("Long>", "number>");
typeName = typeName.replace("<Long", "<number");
// 将Float转为float
typeName = typeName.replace("Float[", "number");
typeName = typeName.replace("Float>", "number>");
typeName = typeName.replace("<Float", "<number");
// 将Double转为double
typeName = typeName.replace("Double[", "number");
typeName = typeName.replace("Double>", "number>");
typeName = typeName.replace("<Double", "<number");
// 将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<", "Map<");
typeName = typeName.replace("Set<", "Set<");
typeName = typeName.replace("List<", "Array<");
return typeName;
}
}
@@ -0,0 +1,36 @@
/*
* 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.php;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import java.lang.reflect.Field;
/**
* @author godotg
*/
public interface IPhpSerializer {
/**
* 获取属性的类型,名称,默认值
*/
Pair<String, String> field(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,109 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.serializer.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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.serializer.kotlin.CodeGenerateKotlin;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
*/
public class PhpArraySerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("array", "array()");
}
@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.Php)) {
return;
}
ArrayField arrayField = (ArrayField) fieldRegistration;
builder.append(StringUtils.format("if (empty({})) {", objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("$buffer->writeInt(0);").append(LS);
GenerateProtocolFile.addTab(builder, deep);
builder.append("} else {").append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String length = "$length" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = count({});", length, objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append(StringUtils.format("$buffer->writeInt({});", length)).append(LS);
String i = "$i" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("for ({} = 0; {} < {}; {}++) {", i, i, length, i)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String element = "$element" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = {}[{}];", element, objectStr, i)).append(LS);
CodeGeneratePhp.phpSerializer(arrayField.getArrayElementRegistration().serializer())
.writeObject(builder, element, deep + 2, field, arrayField.getArrayElementRegistration());
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("}").append(LS);
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.Php);
if (cutDown != null) {
return cutDown;
}
ArrayField arrayField = (ArrayField) fieldRegistration;
String result = "$result" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = array();", result)).append(LS);
String i = "$index" + GenerateProtocolFile.localVariableId++;
String size = "$size" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("{} = $buffer->readInt();", size)).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 ({} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
String readObject = CodeGeneratePhp.phpSerializer(arrayField.getArrayElementRegistration().serializer())
.readObject(builder, deep + 2, field, arrayField.getArrayElementRegistration());
GenerateProtocolFile.addTab(builder, deep + 2);
builder.append(StringUtils.format("array_push({}, {});", 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,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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpBooleanSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(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("{} = $buffer->readBool(); ", result)).append(LS);
return result;
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.serializer.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpByteSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(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->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("{} = $buffer->readByte();", 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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpDoubleSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("float", "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("{} = $buffer->readDouble();", result)).append(LS);
return result;
}
}
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.serializer.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpFloatSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("float", "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("{} = $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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpIntSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(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("{} = $buffer->readInt();", result)).append(LS);
return result;
}
}
@@ -0,0 +1,108 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.serializer.php;
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.registration.field.ListField;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.CutDownArraySerializer;
import com.zfoo.protocol.serializer.CutDownListSerializer;
import com.zfoo.protocol.serializer.reflect.ArraySerializer;
import com.zfoo.protocol.util.StringUtils;
import java.lang.reflect.Field;
import static com.zfoo.protocol.util.FileUtils.LS;
/**
* @author godotg
*/
public class PhpListSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("array", "array()");
}
@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.Php)) {
return;
}
ListField listField = (ListField) fieldRegistration;
builder.append(StringUtils.format("if (empty({})) {", objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("$buffer->writeInt(0);").append(LS);
GenerateProtocolFile.addTab(builder, deep);
builder.append("} else {").append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String length = "$length" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = count({});", length, objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append(StringUtils.format("$buffer->writeInt({});", length)).append(LS);
String i = "$i" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("for ({} = 0; {} < {}; {}++) {", i, i, length, i)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String element = "$element" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = {}[{}];", element, objectStr, i)).append(LS);
CodeGeneratePhp.phpSerializer(listField.getListElementRegistration().serializer())
.writeObject(builder, element, deep + 2, field, listField.getListElementRegistration());
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("}").append(LS);
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.Php);
if (cutDown != null) {
return cutDown;
}
ListField arrayField = (ListField) fieldRegistration;
String result = "$result" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = array();", result)).append(LS);
String i = "$index" + GenerateProtocolFile.localVariableId++;
String size = "$size" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("{} = $buffer->readInt();", size)).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 ({} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
String readObject = CodeGeneratePhp.phpSerializer(arrayField.getListElementRegistration().serializer())
.readObject(builder, deep + 2, field, arrayField.getListElementRegistration());
GenerateProtocolFile.addTab(builder, deep + 2);
builder.append(StringUtils.format("array_push({}, {});", 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,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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpLongSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(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->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("{} = $buffer->readLong();", result)).append(LS);
return result;
}
}
@@ -0,0 +1,113 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.serializer.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpMapSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("array", "array()");
}
@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.Php)) {
return;
}
MapField mapField = (MapField) fieldRegistration;
builder.append(StringUtils.format("if (empty({})) {", objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("$buffer->writeInt(0);").append(LS);
GenerateProtocolFile.addTab(builder, deep);
builder.append("} else {").append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String length = "$length" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = count({});", length, objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append(StringUtils.format("$buffer->writeInt({});", length)).append(LS);
String key = "$key" + GenerateProtocolFile.localVariableId++;
String value = "$value" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append(StringUtils.format("foreach ({} as {} => {}) {", objectStr, value, key)).append(LS);
CodeGeneratePhp.phpSerializer(mapField.getMapKeyRegistration().serializer())
.writeObject(builder, key, deep + 2, field, mapField.getMapKeyRegistration());
CodeGeneratePhp.phpSerializer(mapField.getMapValueRegistration().serializer())
.writeObject(builder, value, deep + 2, field, mapField.getMapValueRegistration());
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("}").append(LS);
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.Php);
if (cutDown != null) {
return cutDown;
}
MapField mapField = (MapField) fieldRegistration;
String result = "$result" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = array();", result)).append(LS);
GenerateProtocolFile.addTab(builder, deep);
String size = "$size" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = $buffer->readInt();", size)).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 ({} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
String keyObject = CodeGeneratePhp.phpSerializer(mapField.getMapKeyRegistration().serializer())
.readObject(builder, deep + 2, field, mapField.getMapKeyRegistration());
String valueObject = CodeGeneratePhp.phpSerializer(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;
}
}
@@ -0,0 +1,53 @@
/*
* 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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpObjectProtocolSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("mixed", "null");
}
@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;
var result = "$result" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("{} = $buffer->readPacket({});", result, objectProtocolField.getProtocolId())).append(LS);
return result;
}
}
@@ -0,0 +1,108 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.serializer.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.registration.field.ListField;
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 PhpSetSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(Field field, IFieldRegistration fieldRegistration) {
return new Pair<>("array", "array()");
}
@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.Php)) {
return;
}
SetField setField = (SetField) fieldRegistration;
builder.append(StringUtils.format("if (empty({})) {", objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("$buffer->writeInt(0);").append(LS);
GenerateProtocolFile.addTab(builder, deep);
builder.append("} else {").append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String length = "$length" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = count({});", length, objectStr)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append(StringUtils.format("$buffer->writeInt({});", length)).append(LS);
String i = "$i" + GenerateProtocolFile.localVariableId++;
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("for ({} = 0; {} < {}; {}++) {", i, i, length, i)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String element = "$element" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = {}[{}];", element, objectStr, i)).append(LS);
CodeGeneratePhp.phpSerializer(setField.getSetElementRegistration().serializer())
.writeObject(builder, element, deep + 2, field, setField.getSetElementRegistration());
GenerateProtocolFile.addTab(builder, deep + 1);
builder.append("}").append(LS);
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.Php);
if (cutDown != null) {
return cutDown;
}
SetField setField = (SetField) fieldRegistration;
String result = "$result" + GenerateProtocolFile.localVariableId++;
var typeName = CodeGeneratePhp.toTsClassName(setField.getType().toString());
builder.append(StringUtils.format("{} = array();", result)).append(LS);
GenerateProtocolFile.addTab(builder, deep);
String size = "$size" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("{} = $buffer->readInt();", size)).append(LS);
GenerateProtocolFile.addTab(builder, deep);
builder.append(StringUtils.format("if ({} > 0) {", size)).append(LS);
GenerateProtocolFile.addTab(builder, deep + 1);
String i = "$index" + GenerateProtocolFile.localVariableId++;
builder.append(StringUtils.format("for ({} = 0; {} < {}; {}++) {", i, i, size, i)).append(LS);
String readObject = CodeGeneratePhp.phpSerializer(setField.getSetElementRegistration().serializer())
.readObject(builder, deep + 2, field, setField.getSetElementRegistration());
GenerateProtocolFile.addTab(builder, deep + 2);
builder.append(StringUtils.format("array_push({}, {});", 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,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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpShortSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(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->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("{} = $buffer->readShort();", 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.php;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.model.Triple;
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 PhpStringSerializer implements IPhpSerializer {
@Override
public Pair<String, String> field(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("{} = $buffer->readString();", result)).append(LS);
return result;
}
}
@@ -0,0 +1,927 @@
<?php
namespace zfoophp;
use Exception;
class ByteBuffer
{
private string $buffer;
private int $writeOffset = 0;
private int $readOffset = 0;
public function __construct()
{
$this->buffer = str_pad("", 128);
}
public function adjustPadding(int $predictionLength, int $beforewriteIndex): void
{
// 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置
$currentwriteIndex = $this->writeOffset;
$predictionCount = $this->writeIntCount($predictionLength);
$length = $currentwriteIndex - $beforewriteIndex - $predictionCount;
$lengthCount = $this->writeIntCount($length);
$padding = $lengthCount - $predictionCount;
if ($padding == 0) {
$this->writeOffset = $beforewriteIndex;
$this->writeInt($length);
$this->writeOffset = $currentwriteIndex;
} else {
$bytes = substr($this->buffer, $currentwriteIndex - $length, $length);
$this->writeOffset = $beforewriteIndex;
$this->writeInt($length);
$this->writeBytes($bytes);
}
}
public function compatibleRead(int $beforereadIndex, int $length): bool
{
return $length != -1 && $this->readOffset < $length + $beforereadIndex;
}
// -------------------------------------------------get/set-------------------------------------------------
public function getBuffer(): string
{
return $this->buffer;
}
public function getWriteOffset(): int
{
return $this->writeOffset;
}
/**
* @throws Exception
*/
public function setWriteOffset(int $writeIndex): void
{
if ($writeIndex > strlen($this->buffer)) {
throw new Exception("writeIndex[" . $writeIndex . "] out of bounds exception: readerIndex: " . $this->readOffset .
", writerIndex: " . $this->writeOffset . "(expected: 0 <= readerIndex <= writerIndex <= capacity:" . strlen($this->buffer));
}
$this->writeOffset = $writeIndex;
}
public function getReadOffset(): int
{
return $this->readOffset;
}
/**
* @throws Exception
*/
public function setReadOffset(int $readIndex): void
{
if ($readIndex > $this->writeOffset) {
throw new Exception("readIndex[" . $readIndex . "] out of bounds exception: readerIndex: " . $this->readOffset .
", writerIndex: " . $this->writeOffset . "(expected: 0 <= readerIndex <= writerIndex <= capacity:" . strlen($this->buffer));
}
$this->readOffset = $readIndex;
}
public function toBytes(): string
{
return substr($this->buffer, 0, $this->writeOffset);
}
public function isReadable(): bool
{
return $this->writeOffset > $this->readOffset;
}
public function getCapacity(): int
{
return strlen($this->buffer) - $this->writeOffset;
}
// -------------------------------------------------write/read-------------------------------------------------
public function writeBytes(string $bytes): void
{
// 如果容量不够则扩容一倍
$length = strlen($bytes);
while ($length > $this->getCapacity()) {
$this->buffer = str_pad($this->buffer, strlen($this->buffer) * 2);
}
for ($i = 0; $i < $length; $i++) {
$this->buffer[$this->writeOffset] = $bytes[$i];
$this->writeOffset++;
}
}
public function readBytes(int $count): string
{
$bytes = substr($this->buffer, $this->readOffset, $count);
$this->readOffset += $count;
return $bytes;
}
public function writeByte(int $value): void
{
$this->writeBytes(pack('c', $value));
}
public function readByte(): int
{
return unpack('c', $this->readBytes(1))[1];
}
public function writeUByte(int $value): void
{
$this->writeBytes(pack('C', $value));
}
public function readUByte(): int
{
return unpack('c', $this->readBytes(1))[1];
}
public function writeBool(bool $value): void
{
$this->writeBytes(pack('C', $value ? 1 : 0));
}
public function readBool(): bool
{
return unpack('C', $this->readBytes(1))[1] == 1;
}
public function writeShort(int $value): void
{
$this->writeBytes(pack('s', $value));
}
public function readShort(): int
{
return unpack('s', $this->readBytes(2))[1];
}
public function writeRawInt(int $value): void
{
$this->writeBytes(pack('i', $value));
}
public function readRawInt(): int
{
return unpack('i', $this->readBytes(4))[1];
}
public function writeInt(int $value): void
{
$this->writeLong($value);
}
public function readInt(): int
{
return $this->readLong();
}
public function writeIntCount(int $value): int
{
$value = ($value << 1) ^ ($value >> 31);
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;
}
public function writeLong(int $longValue): void
{
$value = ($longValue << 1) ^ ($longValue >> 63);
if ($value < 0) {
$this->writeByte($value & 0xFF | 0x80);
$this->writeByte($value >> 7 & 0xFF | 0x80);
$this->writeByte($value >> 14 & 0xFF | 0x80);
$this->writeByte($value >> 21 & 0xFF | 0x80);
$this->writeByte($value >> 28 & 0xFF | 0x80);
$this->writeByte($value >> 35 & 0xFF | 0x80);
$this->writeByte($value >> 42 & 0xFF | 0x80);
$this->writeByte($value >> 49 & 0xFF | 0x80);
$this->writeByte($value >> 56 & 0xFF);
return;
}
if ($value >> 7 == 0) {
$this->writeByte($value);
return;
}
if ($value >> 14 == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7);
return;
}
if ($value >> 21 == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14);
return;
}
if ($value >> 28 == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14 | 0x80);
$this->writeByte($value >> 21);
return;
}
if ($value >> 35 == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14 | 0x80);
$this->writeByte($value >> 21 | 0x80);
$this->writeByte($value >> 28);
return;
}
if ($value >> 42 == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14 | 0x80);
$this->writeByte($value >> 21 | 0x80);
$this->writeByte($value >> 28 | 0x80);
$this->writeByte($value >> 35);
return;
}
if ($value >> 49 == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14 | 0x80);
$this->writeByte($value >> 21 | 0x80);
$this->writeByte($value >> 28 | 0x80);
$this->writeByte($value >> 35 | 0x80);
$this->writeByte($value >> 42);
return;
}
if (($value >> 56) == 0) {
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14 | 0x80);
$this->writeByte($value >> 21 | 0x80);
$this->writeByte($value >> 28 | 0x80);
$this->writeByte($value >> 35 | 0x80);
$this->writeByte($value >> 42 | 0x80);
$this->writeByte($value >> 49);
return;
}
$this->writeByte($value | 0x80);
$this->writeByte($value >> 7 | 0x80);
$this->writeByte($value >> 14 | 0x80);
$this->writeByte($value >> 21 | 0x80);
$this->writeByte($value >> 28 | 0x80);
$this->writeByte($value >> 35 | 0x80);
$this->writeByte($value >> 42 | 0x80);
$this->writeByte($value >> 49 | 0x80);
$this->writeByte($value >> 56);
}
public function readLong(): int
{
$b = $this->readByte();
$value = $b;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x00000000_0000007F | $b << 7;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x00000000_00003FFF | $b << 14;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x00000000_001FFFFF | $b << 21;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x00000000_0FFFFFFF | $b << 28;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x00000007_FFFFFFFF | $b << 35;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x000003FF_FFFFFFFF | $b << 42;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x0001FFFF_FFFFFFFF | $b << 49;
if ($b < 0) {
$b = $this->readByte();
$value = $value & 0x00FFFFFF_FFFFFFFF | $b << 56;
}
}
}
}
}
}
}
}
return (($value >> 1 & 0x7FFFFFFF_FFFFFFFF) ^ -($value & 1));
}
public function writeFloat(float $value): void
{
$this->writeBytes(pack('f', $value));
}
public function readFloat(): float
{
return unpack('f', $this->readBytes(4))[1];
}
public function writeDouble(float $value): void
{
$this->writeBytes(pack('d', $value));
}
public function readDouble(): float
{
return unpack('d', $this->readBytes(8))[1];
}
public function writeString(string $value): void
{
$this->writeInt(strlen($value));
$this->writeBytes($value);
}
public function readString(): string
{
$length = $this->readInt();
return $this->readBytes($length);
}
public function writePacket(mixed $value, int $protocolId): void
{
$protocolRegistration = ProtocolManager::getProtocol($protocolId);
$protocolRegistration->write($this, $value);
}
public function readPacket(int $protocolId): mixed
{
$protocolRegistration = ProtocolManager::getProtocol($protocolId);
return $protocolRegistration->read($this);
}
public function writeBooleanArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeBool($array[$index]);
}
}
}
public function readBooleanArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readBool());
}
}
return $array;
}
public function writeByteArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeByte($array[$index]);
}
}
}
public function readByteArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readByte());
}
}
return $array;
}
public function writeShortArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeShort($array[$index]);
}
}
}
public function readShortArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readShort());
}
}
return $array;
}
public function writeIntArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeInt($array[$index]);
}
}
}
public function readIntArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readInt());
}
}
return $array;
}
public function writeLongArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeLong($array[$index]);
}
}
}
public function readLongArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readLong());
}
}
return $array;
}
public function writeFloatArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeFloat($array[$index]);
}
}
}
public function readFloatArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readFloat());
}
}
return $array;
}
public function writeDoubleArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeDouble($array[$index]);
}
}
}
public function readDoubleArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readDouble());
}
}
return $array;
}
public function writeStringArray(array $array): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writeString($array[$index]);
}
}
}
public function readStringArray(): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readString());
}
}
return $array;
}
public function writePacketArray(array $array, int $protocolId): void
{
if (empty($array)) {
$this->writeInt(0);
} else {
$this->writeInt(count($array));
$length = count($array);
for ($index = 0; $index < $length; $index++) {
$this->writePacket($array[$index], $protocolId);
}
}
}
public function readPacketArray(int $protocolId): array
{
$size = $this->readInt();
$array = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
array_push($array, $this->readPacket($protocolId));
}
}
return $array;
}
public function writeIntIntMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeInt($key);
$this->writeInt($value);
}
}
}
public function readIntIntMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readInt();
$value = $this->readInt();
$map[$key] = $value;
}
}
return $map;
}
public function writeIntLongMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeInt($key);
$this->writeLong($value);
}
}
}
public function readIntLongMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readInt();
$value = $this->readLong();
$map[$key] = $value;
}
}
return $map;
}
public function writeIntStringMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeInt($key);
$this->writeString($value);
}
}
}
public function readIntStringMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readInt();
$value = $this->readString();
$map[$key] = $value;
}
}
return $map;
}
public function writeIntPacketMap(array $map, int $protocolId): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeInt($key);
$this->writePacket($value, $protocolId);
}
}
}
public function readIntPacketMap(int $protocolId): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readInt();
$value = $this->readPacket($protocolId);
$map[$key] = $value;
}
}
return $map;
}
public function writeLongIntMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeLong($key);
$this->writeInt($value);
}
}
}
public function readLongIntMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readLong();
$value = $this->readInt();
$map[$key] = $value;
}
}
return $map;
}
public function writeLongLongMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeLong($key);
$this->writeLong($value);
}
}
}
public function readLongLongMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readLong();
$value = $this->readLong();
$map[$key] = $value;
}
}
return $map;
}
public function writeLongStringMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeLong($key);
$this->writeString($value);
}
}
}
public function readLongStringMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readLong();
$value = $this->readString();
$map[$key] = $value;
}
}
return $map;
}
public function writeLongPacketMap(array $map, int $protocolId): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeLong($key);
$this->writePacket($value, $protocolId);
}
}
}
public function readLongPacketMap(int $protocolId): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readLong();
$value = $this->readPacket($protocolId);
$map[$key] = $value;
}
}
return $map;
}
public function writeStringIntMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeString($key);
$this->writeInt($value);
}
}
}
public function readStringIntMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readString();
$value = $this->readInt();
$map[$key] = $value;
}
}
return $map;
}
public function writeStringLongMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeString($key);
$this->writeLong($value);
}
}
}
public function readStringLongMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readString();
$value = $this->readLong();
$map[$key] = $value;
}
}
return $map;
}
public function writeStringStringMap(array $map): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeString($key);
$this->writeString($value);
}
}
}
public function readStringStringMap(): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readString();
$value = $this->readString();
$map[$key] = $value;
}
}
return $map;
}
public function writeStringPacketMap(array $map, int $protocolId): void
{
if (empty($map)) {
$this->writeInt(0);
} else {
$this->writeInt(count($map));
foreach ($map as $key => $value) {
$this->writeString($key);
$this->writePacket($value, $protocolId);
}
}
}
public function readStringPacketMap(int $protocolId): array
{
$size = $this->readInt();
$map = array();
if ($size > 0) {
for ($index = 0; $index < $size; $index++) {
$key = $this->readString();
$value = $this->readPacket($protocolId);
$map[$key] = $value;
}
}
return $map;
}
}
@@ -0,0 +1,13 @@
<?php
namespace zfoophp;
interface IProtocolRegistration
{
public function protocolId(): int;
public function write(ByteBuffer $buffer, mixed $packet): void;
public function read(ByteBuffer $buffer): mixed;
}
@@ -0,0 +1,4 @@
${protocol_note}
class ${protocol_name} {
${protocol_field_definition}
}
@@ -0,0 +1,42 @@
<?php
namespace zfoophp;
${protocol_imports}
class ProtocolManager
{
private static array $protocols = array();
private static array $protocolIdMap = array();
public static function initProtocol(): void
{
${protocol_manager_registrations};
}
public static function getProtocolId(mixed $clazz): int
{
return self::$protocolIdMap[$clazz];
}
public static function getProtocol(int $protocolId): IProtocolRegistration
{
return self::$protocols[$protocolId];
}
public static function write(ByteBuffer $buffer, mixed $packet): void
{
$protocolId = self::getProtocolId($packet::class);
// write protocol id to buffer
$buffer->writeShort($protocolId);
// write packet
self::getProtocol($protocolId)->write($buffer, $packet);
}
public static function read(ByteBuffer $buffer): mixed
{
$protocolId = $buffer->readShort();
return self::getProtocol($protocolId)->read($buffer);
}
}
@@ -0,0 +1,31 @@
class ${protocol_name}Registration implements IProtocolRegistration {
public function protocolId(): int
{
return ${protocol_id};
}
public function write(ByteBuffer $buffer, mixed $packet): void
{
if ($packet == null)
{
$buffer->writeInt(0);
return;
}
${protocol_write_serialization}
}
public function read(ByteBuffer $buffer): mixed
{
$length = $buffer->readInt();
$packet = new ${protocol_name}();
if ($length == 0) {
return $packet;
}
$beforeReadIndex = $buffer->readOffset();
${protocol_read_deserialization}
if ($length > 0) {
$buffer->setReadOffset($beforeReadIndex + $length);
}
return $packet;
}
}
@@ -0,0 +1,9 @@
<?php
namespace zfoophp;
${protocol_imports}
${protocol_class}
${protocol_registration}
@@ -51,14 +51,14 @@ public class GenerateTesting {
generateLanguages.add(CodeLanguage.Python);
// Initialize and then generate the protocol
ProtocolManager.initProtocolAuto(List.of(ComplexObject.class, NormalObject.class, SimpleObject.class, EmptyObject.class), op);
// copyFiles();
ProtocolManager.initProtocolAuto(List.of(NormalObject.class, SimpleObject.class, EmptyObject.class), op);
copyFiles();
}
@Test
public void copyFiles() throws IOException {
var sourceDirectory = "C:\\github\\zfoo\\protocol\\zfookt";
var targetDirectory = "C:\\github\\zfoo-kotlin-support\\src\\main\\kotlin\\com\\zfoo\\kotlin";
var sourceDirectory = "D:\\Project\\zfoo\\protocol\\zfoophp";
var targetDirectory = "D:\\github\\zfoo-php-support2\\zfoophp";
FileUtils.deleteFile(new File(targetDirectory));
FileUtils.copyDirectory(new File(sourceDirectory), new File(targetDirectory));
}