From 9ed99e9fc0e05be9e937816c1778a1a207f77ac1 Mon Sep 17 00:00:00 2001 From: godotg Date: Sun, 15 Oct 2023 21:59:56 +0800 Subject: [PATCH] feat[golang]: compatible field of inside protocol class --- .../serializer/go/GenerateGoUtils.java | 73 +++++++------------ protocol/src/main/resources/go/ByteBuffer.go | 18 +++-- .../src/main/resources/go/ProtocolTemplate.go | 10 ++- .../resources/go/ProtocolTemplateEmpty.go | 30 ++++++++ 4 files changed, 73 insertions(+), 58 deletions(-) create mode 100644 protocol/src/main/resources/go/ProtocolTemplateEmpty.go diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/go/GenerateGoUtils.java b/protocol/src/main/java/com/zfoo/protocol/serializer/go/GenerateGoUtils.java index 43cd4fda..fd2d2f6c 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/go/GenerateGoUtils.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/go/GenerateGoUtils.java @@ -115,16 +115,24 @@ public abstract class GenerateGoUtils { var registrationConstructor = registration.getConstructor(); var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName(); - var protocolTemplate = ClassUtils.getFileFromClassPathToString("go/ProtocolTemplate.go"); + var protocolTemplate = ArrayUtils.isEmpty(registration.getFields()) + ? ClassUtils.getFileFromClassPathToString("go/ProtocolTemplateEmpty.go") + : ClassUtils.getFileFromClassPathToString("go/ProtocolTemplate.go"); + var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.Go); var fieldDefinition = fieldDefinition(registration); var writeObject = writeObject(registration); var readObject = readObject(registration); - protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName, fieldDefinition.trim() - , protocolClazzName, protocolId, protocolClazzName, protocolClazzName - , writeObject.trim(), protocolClazzName, protocolClazzName, readObject.trim()); + if (ArrayUtils.isEmpty(registration.getFields())) { + protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName, fieldDefinition.trim() + , protocolClazzName, protocolId, protocolClazzName, protocolClazzName, protocolClazzName); + } else { + protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName, fieldDefinition.trim() + , protocolClazzName, protocolId, protocolClazzName, protocolClazzName + , writeObject.trim(), protocolClazzName, protocolClazzName, readObject.trim()); + } var outputPath = StringUtils.format("{}/{}.go", protocolOutputPath, protocolClazzName); FileUtils.writeStringToFile(new File(outputPath), protocolTemplate, true); @@ -157,15 +165,23 @@ public abstract class GenerateGoUtils { var fields = registration.getFields(); var fieldRegistrations = registration.getFieldRegistrations(); var goBuilder = new StringBuilder(); + if (registration.isCompatible()) { + goBuilder.append(TAB).append("var beforeWriteIndex = buffer.WriteOffset()").append(LS); + goBuilder.append(TAB ).append(StringUtils.format("buffer.WriteInt({})", registration.getPredictionLength())).append(LS); + } else { + goBuilder.append(TAB).append("buffer.WriteInt(-1)").append(LS); + } for (var i = 0; i < fields.length; i++) { var field = fields[i]; var fieldRegistration = fieldRegistrations[i]; goSerializer(fieldRegistration.serializer()).writeObject(goBuilder, "message." + StringUtils.capitalize(field.getName()), 1, field, fieldRegistration); } + if (registration.isCompatible()) { + goBuilder.append(TAB).append(StringUtils.format("buffer.AdjustPadding({}, beforeWriteIndex)", registration.getPredictionLength())).append(LS); + } return goBuilder.toString(); } - private static String readObject(ProtocolRegistration registration) { var fields = registration.getFields(); var fieldRegistrations = registration.getFieldRegistrations(); @@ -174,10 +190,11 @@ public abstract class GenerateGoUtils { var field = fields[i]; var fieldRegistration = fieldRegistrations[i]; if (field.isAnnotationPresent(Compatible.class)) { - goBuilder.append(TAB).append("if !buffer.IsReadable()").append(LS); - goBuilder.append(TAB).append("{").append(LS); - goBuilder.append(TAB + TAB).append("return packet").append(LS); + goBuilder.append(TAB ).append("if buffer.CompatibleRead(beforeReadIndex, length) {").append(LS); + var compatibleReadObject = goSerializer(fieldRegistration.serializer()).readObject(goBuilder, 2, field, fieldRegistration); + goBuilder.append(TAB + TAB).append(StringUtils.format("packet.{} = {}", field.getName(), compatibleReadObject)).append(LS); goBuilder.append(TAB).append("}").append(LS); + continue; } var readObject = goSerializer(fieldRegistration.serializer()).readObject(goBuilder, 1, field, fieldRegistration); goBuilder.append(TAB).append(StringUtils.format("packet.{} = {}", StringUtils.capitalize(field.getName()), readObject)).append(LS); @@ -185,44 +202,4 @@ public abstract class GenerateGoUtils { return goBuilder.toString(); } - public static String toGoClassName(String typeName) { - typeName = typeName.replaceAll("java.util.|java.lang.", StringUtils.EMPTY); - typeName = typeName.replaceAll("[a-zA-Z0-9_.]*\\.", StringUtils.EMPTY); - - // CSharp不适用基础类型的泛型,会影响性能 - 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": - typeName = "float32"; - return typeName; - case "Double": - typeName = "float64"; - return typeName; - case "Character": - typeName = "string"; - return typeName; - default: - } - - return typeName; - } } diff --git a/protocol/src/main/resources/go/ByteBuffer.go b/protocol/src/main/resources/go/ByteBuffer.go index a6ba0541..0e6e1284 100644 --- a/protocol/src/main/resources/go/ByteBuffer.go +++ b/protocol/src/main/resources/go/ByteBuffer.go @@ -38,6 +38,10 @@ func (byteBuffer *ByteBuffer) AdjustPadding(predictionLength int, beforeWriteInd } } +func (byteBuffer *ByteBuffer) CompatibleRead(beforeReadIndex int, length int) bool { + return length != -1 && byteBuffer.readIndex < length+beforeReadIndex +} + // -------------------------------------------------get/set------------------------------------------------- func (byteBuffer *ByteBuffer) WriteOffset() int { return byteBuffer.writeIndex @@ -51,6 +55,10 @@ func (byteBuffer *ByteBuffer) SetWriteOffset(writeIndex int) { byteBuffer.writeIndex = writeIndex } +func (byteBuffer *ByteBuffer) ReadOffset() int { + return byteBuffer.readIndex +} + func (byteBuffer *ByteBuffer) SetReadOffset(readIndex int) { if readIndex > byteBuffer.writeIndex { var error = fmt.Sprintf("readIndex:[{%d}] out of bounds exception: readerIndex:[{%d}] , writerIndex:[{%d}] (expected: 0 <= readerIndex <= writerIndex <= capacity:[{%d}])", readIndex, byteBuffer.readIndex, byteBuffer.writeIndex, len(byteBuffer.buffer)) @@ -468,12 +476,6 @@ func (byteBuffer *ByteBuffer) ReadChar() string { return byteBuffer.ReadString() } -func (byteBuffer *ByteBuffer) WritePacketFlag(packet any) bool { - var flag = packet == nil - byteBuffer.WriteBool(!flag) - return flag -} - func (byteBuffer *ByteBuffer) WritePacket(packet any, protocolId int16) { var protocolRegistration = GetProtocol(protocolId) protocolRegistration.write(byteBuffer, packet) @@ -486,7 +488,7 @@ func (byteBuffer *ByteBuffer) ReadPacket(protocolId int16) any { // -------------------------------------------------IProtocolRegistration------------------------------------------------- type IProtocolRegistration interface { - protocolId() int16 + ProtocolId() int16 write(buffer *ByteBuffer, packet any) @@ -501,7 +503,7 @@ func GetProtocol(protocolId int16) IProtocolRegistration { } func Write(buffer *ByteBuffer, packet any) { - var protocolId = packet.(IProtocolRegistration).protocolId() + var protocolId = packet.(IProtocolRegistration).ProtocolId() buffer.WriteShort(protocolId) var protocolRegistration = GetProtocol(protocolId) protocolRegistration.write(buffer, packet) diff --git a/protocol/src/main/resources/go/ProtocolTemplate.go b/protocol/src/main/resources/go/ProtocolTemplate.go index 8a1799fe..5b873100 100644 --- a/protocol/src/main/resources/go/ProtocolTemplate.go +++ b/protocol/src/main/resources/go/ProtocolTemplate.go @@ -9,7 +9,8 @@ func (protocol {}) ProtocolId() int16 { } func (protocol {}) write(buffer *ByteBuffer, packet any) { - if buffer.WritePacketFlag(packet) { + if packet == nil { + buffer.WriteInt(0) return } var message = packet.(*{}) @@ -18,9 +19,14 @@ func (protocol {}) write(buffer *ByteBuffer, packet any) { func (protocol {}) read(buffer *ByteBuffer) any { var packet = new({}) - if !buffer.ReadBool() { + var length = buffer.ReadInt() + if length == 0 { return packet } + var beforeReadIndex = buffer.ReadOffset() {} + if length > 0 { + buffer.SetReadOffset(beforeReadIndex + length) + } return packet } diff --git a/protocol/src/main/resources/go/ProtocolTemplateEmpty.go b/protocol/src/main/resources/go/ProtocolTemplateEmpty.go new file mode 100644 index 00000000..da779094 --- /dev/null +++ b/protocol/src/main/resources/go/ProtocolTemplateEmpty.go @@ -0,0 +1,30 @@ +package protocol +{} +type {} struct { + {} +} + +func (protocol {}) ProtocolId() int16 { + return {} +} + +func (protocol {}) write(buffer *ByteBuffer, packet any) { + if packet == nil { + buffer.WriteInt(0) + return + } + buffer.WriteInt(-1) +} + +func (protocol {}) read(buffer *ByteBuffer) any { + var packet = new({}) + var length = buffer.ReadInt() + if length == 0 { + return packet + } + var beforeReadIndex = buffer.ReadOffset() + if length > 0 { + buffer.SetReadOffset(beforeReadIndex + length) + } + return packet +}