From 6f7dc497752547a0660940f59b478c0e699863d2 Mon Sep 17 00:00:00 2001 From: godotg Date: Sun, 15 Oct 2023 16:30:36 +0800 Subject: [PATCH] feat[cpp]: compatible field of inside protocol class --- .../serializer/cpp/GenerateCppUtils.java | 18 ++++++++- .../typescript/GenerateTsUtils.java | 1 - protocol/src/main/resources/cpp/ByteBuffer.h | 39 +++++++++++++------ .../src/main/resources/cpp/ProtocolTemplate.h | 3 +- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/cpp/GenerateCppUtils.java b/protocol/src/main/java/com/zfoo/protocol/serializer/cpp/GenerateCppUtils.java index c7aba749d..4614a50e7 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/cpp/GenerateCppUtils.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/cpp/GenerateCppUtils.java @@ -245,8 +245,13 @@ private static String operator(ProtocolRegistration registration) { private static String writeObject(ProtocolRegistration registration) { var fields = registration.getFields(); var fieldRegistrations = registration.getFieldRegistrations(); - var cppBuilder = new StringBuilder(); + if (registration.isCompatible()) { + cppBuilder.append(TAB + TAB + TAB).append("auto beforeWriteIndex = buffer.writerIndex();").append(LS); + cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("buffer.writeInt({});", registration.getPredictionLength())).append(LS); + } else { + cppBuilder.append(TAB + TAB + TAB).append("buffer.writeInt(-1);").append(LS); + } for (int i = 0; i < fields.length; i++) { var field = fields[i]; var fieldRegistration = fieldRegistrations[i]; @@ -273,6 +278,17 @@ private static String readObject(ProtocolRegistration registration) { if (field.isAnnotationPresent(Compatible.class)) { cppBuilder.append(TAB + TAB + TAB).append(StringUtils.format("if (!buffer.isReadable()) { return packet; }")).append(LS); } + if (field.isAnnotationPresent(Compatible.class)) { + cppBuilder.append(TAB + TAB + TAB).append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS); + var compatibleReadObject = cppSerializer(fieldRegistration.serializer()).readObject(cppBuilder, 4, field, fieldRegistration); + cppBuilder.append(TAB + TAB + TAB); + if (ProtocolManager.isProtocolClass(field.getType())) { + cppBuilder.append(StringUtils.format("packet->{} = *{};", field.getName(), compatibleReadObject)); + } else { + cppBuilder.append(StringUtils.format("packet->{} = {};", field.getName(), compatibleReadObject)); + } + continue; + } var readObject = cppSerializer(fieldRegistration.serializer()).readObject(cppBuilder, 3, field, fieldRegistration); cppBuilder.append(TAB + TAB + TAB); diff --git a/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/GenerateTsUtils.java b/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/GenerateTsUtils.java index 8be25cb9a..7ccabb8af 100644 --- a/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/GenerateTsUtils.java +++ b/protocol/src/main/java/com/zfoo/protocol/serializer/typescript/GenerateTsUtils.java @@ -205,7 +205,6 @@ private static String readObject(ProtocolRegistration registration) { var field = fields[i]; var fieldRegistration = fieldRegistrations[i]; if (field.isAnnotationPresent(Compatible.class)) { - tsBuilder.append(TAB + TAB).append("if (buffer.compatibleRead(beforeReadIndex, length)) {").append(LS); var compatibleReadObject = tsSerializer(fieldRegistration.serializer()).readObject(tsBuilder, 3, field, fieldRegistration); tsBuilder.append(TAB + TAB+ TAB).append(StringUtils.format("packet.{} = {};", field.getName(), compatibleReadObject)).append(LS); diff --git a/protocol/src/main/resources/cpp/ByteBuffer.h b/protocol/src/main/resources/cpp/ByteBuffer.h index 2287c78d3..d05684769 100644 --- a/protocol/src/main/resources/cpp/ByteBuffer.h +++ b/protocol/src/main/resources/cpp/ByteBuffer.h @@ -77,6 +77,29 @@ namespace zfoo { ByteBuffer &operator=(const ByteBuffer &buffer) = delete; + void adjustPadding(int32_t predictionLength, int32_t beforeWriteIndex) { + int32_t currentWriteIndex = writerIndex(); + int32_t predictionCount = writeIntCount(predictionLength); + int32_t length = currentWriteIndex - beforeWriteIndex - predictionCount; + int32_t lengthCount = writeIntCount(length); + int32_t padding = lengthCount - predictionCount; + if (padding == 0) { + writerIndex(beforeWriteIndex); + writeInt(length); + writerIndex(currentWriteIndex); + } else { + int8_t *targetPtr = (int8_t *) calloc(length, sizeof(int8_t)); + memcpy(targetPtr, &m_buffer[currentWriteIndex - length], length); + writerIndex(beforeWriteIndex); + writeInt(length); + writeBytes(targetPtr, length); + free(targetPtr); + } + } + + bool compatibleRead(int32_t beforeReadIndex, int32_t length) { + return length != -1 && readerIndex() < length + beforeReadIndex; + } void clear() { m_writerIndex = 0; @@ -229,17 +252,17 @@ namespace zfoo { } inline int32_t writeIntCount(const int32_t &intValue) { - uint32_t v = (uint32_t) ((intValue << 1) ^ (intValue >> 31)); - if (v >> 7 == 0) { + uint32_t value = (uint32_t) ((intValue << 1) ^ (intValue >> 31)); + if (value >> 7 == 0) { return 1; } - if (v >> 14 == 0) { + if (value >> 14 == 0) { return 2; } - if (v >> 21 == 0) { + if (value >> 21 == 0) { return 3; } - if (v >> 28 == 0) { + if (value >> 28 == 0) { return 4; } return 5; @@ -401,12 +424,6 @@ namespace zfoo { return str; } - inline bool writePacketFlag(const IProtocol *packet) { - bool flag = packet == nullptr; - writeBool(!flag); - return flag; - } - inline void writePacket(IProtocol *packet, const int16_t &protocolId) { IProtocolRegistration *protocolRegistration = getProtocol(protocolId); protocolRegistration->write(*this, packet); diff --git a/protocol/src/main/resources/cpp/ProtocolTemplate.h b/protocol/src/main/resources/cpp/ProtocolTemplate.h index d8fee3cbf..5a4daa761 100644 --- a/protocol/src/main/resources/cpp/ProtocolTemplate.h +++ b/protocol/src/main/resources/cpp/ProtocolTemplate.h @@ -36,7 +36,8 @@ namespace zfoo { } void write(ByteBuffer &buffer, IProtocol *packet) override { - if (buffer.writePacketFlag(packet)) { + if (packet == nullptr) { + buffer.writeInt(0); return; } auto *message = ({} *) packet;