diff --git a/.gitignore b/.gitignore index 5ff1f95d..07b60da2 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ hs_err_pid* **/gdProtocol/ **/CsProtocol/ **/LuaProtocol/ +**/zfoocpp/ **/protos/ # 以下是web前端需要忽略的文件 @@ -69,3 +70,6 @@ export_presets.cfg # Mono-specific ignores .mono/ data_*/ + +# C++ CMake +**/cmake-build-debug/ diff --git a/protocol/src/test/cpp/CMakeLists.txt b/protocol/src/test/cpp/CMakeLists.txt new file mode 100644 index 00000000..fc0ae73d --- /dev/null +++ b/protocol/src/test/cpp/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.23) +project(cpp) + +set(CMAKE_CXX_STANDARD 20) + +set(PROJECT_MAIN cpp) + +# main +file(GLOB_RECURSE MAIN_SOURCES zfoocpp/*.c**) +file(GLOB_RECURSE MAIN_HEADERS zfoocpp/*.h**) + +# test +file(GLOB_RECURSE TEST_SOURCES test/*.c**) +file(GLOB_RECURSE TEST_HEADERS test/*.h**) + +add_executable(${PROJECT_MAIN} + main.cpp + ${TEST_SOURCES} ${TEST_HEADERS} + ${MAIN_SOURCES} ${MAIN_HEADERS}) + +target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/protocol/src/test/cpp/main.cpp b/protocol/src/test/cpp/main.cpp new file mode 100644 index 00000000..aae751d0 --- /dev/null +++ b/protocol/src/test/cpp/main.cpp @@ -0,0 +1,18 @@ +#include "test/list_test.h" +#include "test/byte_buffer_test.h" +#include "test/serialization_test.h" +#include "test/speed_test.h" + +using namespace zfoo; +using namespace std; + + +int main() { + list_test::list_all_test(); + byte_buffer_test::byte_buffer_all_test(); + serialization_test::protocol_all_test(); + + speed_test::parseObject(); + speed_test::singleThreadBenchmarks(); + return 0; +} diff --git a/protocol/src/test/cpp/test/byte_buffer_test.h b/protocol/src/test/cpp/test/byte_buffer_test.h new file mode 100644 index 00000000..31eb9fc0 --- /dev/null +++ b/protocol/src/test/cpp/test/byte_buffer_test.h @@ -0,0 +1,147 @@ +#ifndef ZFOO_BYTE_BUFFER_TEST_H +#define ZFOO_BYTE_BUFFER_TEST_H + +#include + +#include "zfoocpp/ByteBuffer.h" + +namespace byte_buffer_test { + + using namespace zfoo; + + void assert(bool flag) { + if (!flag) { + throw "exception happen"; + } + } + + void typeTest() { + using namespace std; + int32_t a = 0xFFFFFFFF; + uint32_t b = 0xFFFFFFFF; + assert(a == b); + + b = a; + assert(a == b); + } + + void boolTest(ByteBuffer &buffer) { + bool value = true; + buffer.writeBool(value); + assert(buffer.readBool() == value); + + value = false; + buffer.writeBool(value); + assert(buffer.readBool() == value); + } + + void byteTest(ByteBuffer &buffer) { + int8_t values[] = {127, 0 - 128}; + for (auto value : values) { + buffer.writeByte(value); + assert(buffer.readByte() == value); + } + } + + void bytesTest(ByteBuffer &buffer) { + int8_t values[] = {127, 0 - 128}; + int length = sizeof(values) / sizeof(int8_t); + buffer.writeBytes(values, length); + int8_t *bytes = buffer.readBytes(length); + for (int i = 0; i < length; ++i) { + assert(bytes[i] == values[i]); + } + } + + void shortTest(ByteBuffer &buffer) { + int16_t values[] = {-32768, -100, -2, -1, 0, 1, 2, 100, 32767}; + for (auto value : values) { + buffer.writeShort(value); + assert(buffer.readShort() == value); + } + } + + void intTest(ByteBuffer &buffer) { + int32_t values[] = {static_cast(0x80000000), -99999999, -9999, -100, -2, -1, 0, 1, 2, 100, 9999, + 99999999, 0x7fffffff}; + + for (auto value : values) { + buffer.writeInt(value); + assert(buffer.readInt() == value); + } + } + + void longTest(ByteBuffer &buffer) { + int64_t values[] = {static_cast(0x8000000000000000LL), -9999999999999999L, -9999999999999999L, + -99999999, -9999, -100, -2, -1, 0, 1, 2, 100, 9999, 99999999, 9999999999999999L, + 0x7fffffffffffffffLL}; + + for (auto value : values) { + buffer.writeLong(value); + assert(buffer.readLong() == value); + } + } + + void floatTest(ByteBuffer &buffer) { + float values[] = {-12345678.12345678, -1234.5678, -100, -2, -1, 0, 1, 2, 100, 1234.5678, 12345678.12345678}; + for (auto value : values) { + buffer.writeFloat(value); + assert(std::abs(buffer.readFloat() - value) < 0.001); + } + } + + void doubleTest(ByteBuffer &buffer) { + double values[] = {-1234.5678, -100, -2, -1, 0, 1, 2, 100, 1234.5678}; + for (auto value : values) { + buffer.writeDouble(value); + assert(std::abs(buffer.readDouble() - value) < 0.001); + } + } + + void stringTest(ByteBuffer &buffer) { + using namespace std; + string value = "hello world!"; + buffer.writeString(value); + assert(buffer.readString().compare(value) == 0); + } + + + void byte_buffer_all_test() { + using namespace std; + + typeTest(); + + ByteBuffer buffer; + assert(buffer.getCapacity() == DEFAULT_BUFFER_SIZE); + assert(buffer.writerIndex() == 0); + assert(buffer.readerIndex() == 0); + + boolTest(buffer); + byteTest(buffer); + bytesTest(buffer); + shortTest(buffer); + intTest(buffer); + floatTest(buffer); + doubleTest(buffer); + stringTest(buffer); + } +// void string_utf8_test(ByteBuffer &buffer) { +// using namespace std; +// string str = "我爱的人。。。.."; +// wstring utf8_str = buffer.string_to_utf8(str); +// string str_origin = buffer.utf8_to_string(utf8_str); +// +// cout << str << endl; +// cout << str_origin << endl; +// std::wstring_convert> converter; +// std::string string = converter.to_bytes(utf8_str); +// auto list = std::list(string.begin(), string.end()); +// for (auto v : list) { +// cout << std::to_string(v) << endl; +// } +// } + +} + + +#endif diff --git a/protocol/src/test/cpp/test/list.h b/protocol/src/test/cpp/test/list.h new file mode 100644 index 00000000..9c21d81a --- /dev/null +++ b/protocol/src/test/cpp/test/list.h @@ -0,0 +1,135 @@ +#ifndef ZFOO_LIST_H +#define ZFOO_LIST_H + +#include + +namespace zfoo { + + template + class List { + private: + int max_list_size; + int length; + T *head; + + private: + void out() { + T *p = head; + for (int i = 0; i < length; i++, p++) { + std::cout << *p << " "; //setw(sizeof(int)) + } + } + + public: + List() { + //默认构造函数,创建大小为100的空间 + max_list_size = 10; + head = new T[max_list_size]; + length = 0; + } + + List(const List &list) { + max_list_size = list.max_list_size; + length = list.length; + head = new T[max_list_size]; + memcpy(head, list.head, max_list_size * sizeof(T)); + std::cout << "copy" << std::endl; + } + + List &operator=(const List &list) { + if (this == &list) { + return *this; + } + if (head != nullptr) { + delete[] head; + } + max_list_size = list.max_list_size; + length = list.length; + head = new T[max_list_size]; + memcpy(head, list.head, max_list_size * sizeof(T)); + std::cout << "operator" << std::endl; + return *this; + } + + + ~List() { + // 程序完成后,自动调用,释放数组空间 + if (head != nullptr) { + delete[] head; + std::cout << "deconstructor" << std::endl; + } + } + + bool isEmpty() const { return length == 0; }; //判断线性表是否为空 + int size() const { return length; }; //返回线性表长度 + + void add(T &x) { + if (length >= max_list_size) { + int newSize = max_list_size * 2; + T *p = (T *) realloc(head, newSize * sizeof(T)); + max_list_size = newSize; + head = p; + } + head[length++] = x; + } + + T *get(int index) { return (index >= length) ? nullptr : &head[index]; } + + int indexOf(T &x) {// return -1 if x not in list. + // return -1 if x not in list. + for (int i = 0; i < length; i++) { + if (head[i] == x) { + return i; + } + } + return -1; + } + + bool remove(T &x) { + int index = indexOf(x); + if (index < 0) { + return false; + } + // 开始移除 + length--; + if (index == length) { + return true; + } + memmove(&head[index], &head[index + 1], (length - index) * sizeof(T)); + return true; + } + + + public: + friend std::ostream &operator<<(std::ostream &cout, List &list) { + list.out(); + return cout; + } + + bool operator<(const List &rhs) const { + if (max_list_size < rhs.max_list_size) + return true; + if (rhs.max_list_size < max_list_size) + return false; + if (length < rhs.length) + return true; + if (rhs.length < length) + return false; + return head < rhs.head; + } + + bool operator>(const List &rhs) const { + return rhs < *this; + } + + bool operator<=(const List &rhs) const { + return !(rhs < *this); + } + + bool operator>=(const List &rhs) const { + return !(*this < rhs); + } + }; +} + +#endif diff --git a/protocol/src/test/cpp/test/list_test.h b/protocol/src/test/cpp/test/list_test.h new file mode 100644 index 00000000..ce0cb8fc --- /dev/null +++ b/protocol/src/test/cpp/test/list_test.h @@ -0,0 +1,123 @@ +#ifndef ZFOO_LIST_TEST_H +#define ZFOO_LIST_TEST_H + +#include "list.h" + +namespace list_test { + void assert(bool flag, std::string errorMessage) { + if (!flag) { + throw errorMessage; + } + } + + void listCopyTest() { + using namespace zfoo; + using namespace std; + List list; + int64_t a = 1; + int64_t b = 2; + int64_t c = 3; + list.add(a); + list.add(b); + list.add(c); + + List newList = list; + assert(newList.size() == 3, "listCopyTest size exception"); + assert(*newList.get(2) == 3, "listCopyTest get exception"); + assert(newList.indexOf(c) == 2, "listCopyTest indexOf exception"); + } + + void listOperatorTest() { + using namespace zfoo; + using namespace std; + List list; + int64_t a = 1; + int64_t b = 2; + int64_t c = 3; + list.add(a); + list.add(b); + list.add(c); + + List newList; + newList = list; + assert(newList.size() == 3, "listOperatorTest size exception"); + assert(*newList.get(2) == 3, "listOperatorTest get exception"); + assert(newList.indexOf(c) == 2, "listOperatorTest indexOf exception"); + newList = newList; + newList = newList; + } + + void listIntTest() { + using namespace zfoo; + using namespace std; + List list; + assert(list.isEmpty(), "listIntTest isEmpty exception"); + int a = 1; + int b = 2; + int c = 3; + list.add(a); + list.add(b); + list.add(c); + assert(list.size() == 3, "listIntTest size exception"); + assert(*list.get(1) == 2, "listIntTest get exception"); + assert(list.indexOf(b) == 1, "listIntTest indexOf exception"); + } + + void listRemoveTest() { + using namespace zfoo; + using namespace std; + using namespace zfoo; + using namespace std; + List list; + int64_t a = 1; + int64_t b = 2; + int64_t c = 3; + int64_t d = 4; + int64_t e = 5; + int64_t f = 6; + int64_t g = 7; + list.add(a); + list.add(b); + list.add(c); + list.add(d); + list.add(e); + list.add(f); + + List list1 = list; + List list2 = list; + + assert(!list.remove(g), "listRemoveTest remove exception"); + assert(list.remove(f), "listRemoveTest remove exception"); + assert(*list.get(0) == a, "listRemoveTest get exception"); + assert(*list.get(4) == e, "listRemoveTest get exception"); + + list1.remove(a); + assert(list1.get(5) == nullptr, "listRemoveTest get exception"); + assert(*list1.get(0) == b, "listRemoveTest get exception"); + assert(*list1.get(4) == f, "listRemoveTest get exception"); + + list2.remove(c); + assert(*list2.get(0) == a, "listRemoveTest get exception"); + assert(*list2.get(4) == f, "listRemoveTest get exception"); + } + + + void list_all_test() { + using namespace std; + try { + listCopyTest(); + cout << "----------------------------------------------------------------------" << endl; + listOperatorTest(); + cout << "----------------------------------------------------------------------" << endl; + listIntTest(); + cout << "----------------------------------------------------------------------" << endl; + listRemoveTest(); + cout << "----------------------------------------------------------------------" << endl; + } catch (string &e) { + cout << e << endl; + } catch (...) { + cout << "unknown" << endl; + } + } +} +#endif diff --git a/protocol/src/test/cpp/test/serialization_test.h b/protocol/src/test/cpp/test/serialization_test.h new file mode 100644 index 00000000..75e840c5 --- /dev/null +++ b/protocol/src/test/cpp/test/serialization_test.h @@ -0,0 +1,120 @@ +#ifndef ZFOO_SERIALIZATION_TEST_H +#define ZFOO_SERIALIZATION_TEST_H + +#include +#include +#include +#include + +#include "zfoocpp/ProtocolManager.h" + + +namespace serialization_test { + using namespace zfoo; + using namespace std; + + void objectBTest() { + ByteBuffer buffer; + ObjectB objectB; + objectB.flag = true; + + write(buffer, &objectB); + + ObjectB obj = *((ObjectB *) read(buffer)); + cout << "Hello, World!" << endl; + } + + void objectATest() { + ByteBuffer buffer; + ObjectA objectA; + + ObjectB objectB; + objectB.flag = true; + + map map; + map.insert(pair(1, "a")); + map.insert(pair(2, "b")); + map.insert(pair(3, "c")); + + objectA.a = 1; + objectA.m = map; + objectA.objectB = objectB; + + write(buffer, &objectA); + + ObjectA obj = *((ObjectA *) read(buffer)); + cout << "Hello, World!" << endl; + } + + + void normalObjectTest() { + ByteBuffer buffer; + + ObjectA objectA; + ObjectB objectB; + objectB.flag = true; + + map map; + map.insert(pair(1, "a")); + map.insert(pair(2, "b")); + map.insert(pair(3, "c")); + + objectA.a = 1; + objectA.m = map; + objectA.objectB = objectB; + + NormalObject normalObject; + normalObject.kk = objectA; + normalObject.m = map; + + write(buffer, &normalObject); + NormalObject *p = (NormalObject *) read(buffer); + cout << "Hello, World!" << endl; + } + + + void complexObjectTest() { + // 读取二进制文件 + ifstream file("C:\\zfoo\\protocol\\src\\test\\resources\\ComplexObject.bytes", ios::out | ios::binary); + unsigned char carray[10000]; + int length = 0; + while (file.read((char *) &carray[length], sizeof(unsigned char))) { + length++; + } + file.close(); + + ByteBuffer buffer; + buffer.writeBytes(reinterpret_cast(carray), length); + ComplexObject obj = *((ComplexObject *) read(buffer)); + + ByteBuffer newBuffer; + write(newBuffer, &obj); + obj = *((ComplexObject *) read(newBuffer)); + cout << "Hello, World!" << endl; + + for (int i = 0; i < 3000; ++i) { + auto a = buffer.getByte(i); + auto b = newBuffer.getByte(i); + if (a != b) { + cout << i << endl; + } + } + } + + + void protocol_all_test() { + try { + initProtocol(); + objectBTest(); + objectATest(); + normalObjectTest(); + complexObjectTest(); + } catch (string &e) { + cout << e << endl; + } catch (...) { + cout << "unknown" << endl; + } + } + +} +#endif diff --git a/protocol/src/test/cpp/test/speed_test.h b/protocol/src/test/cpp/test/speed_test.h new file mode 100644 index 00000000..560ae84c --- /dev/null +++ b/protocol/src/test/cpp/test/speed_test.h @@ -0,0 +1,110 @@ +#ifndef ZFOO_SPEED_TEST_H +#define ZFOO_SPEED_TEST_H + +#include +#include +#include + +#include "zfoocpp/ProtocolManager.h" + +namespace speed_test { + + using namespace zfoo; + using namespace std; + + SimpleObject *pSimpleObject = nullptr; + NormalObject *pNormalObject = nullptr; + ComplexObject *pComplexObject = nullptr; + + int benchmark = 100000; + + void parseObject() { + // 读取二进制文件 + ifstream file("C:\\zfoo\\protocol\\src\\test\\resources\\ComplexObject.bytes", ios::out | ios::binary); + unsigned char carray[10000]; + int length = 0; + while (file.read((char *) &carray[length], sizeof(unsigned char))) { + length++; + } + file.close(); + + ByteBuffer buffer; + buffer.writeBytes(reinterpret_cast(carray), length); + ComplexObject obj = *((ComplexObject *) read(buffer)); + + ByteBuffer newBuffer; + write(newBuffer, &obj); + pComplexObject = (ComplexObject *) read(newBuffer); + + pSimpleObject = new SimpleObject(); + pSimpleObject->c = pComplexObject->c; + pSimpleObject->g = pComplexObject->g; + + pNormalObject = new NormalObject(); + pNormalObject->a = pComplexObject->a; + pNormalObject->aaa = pComplexObject->aaa; + pNormalObject->b = pComplexObject->b; + pNormalObject->c = pComplexObject->c; + pNormalObject->d = pComplexObject->d; + pNormalObject->e = pComplexObject->e; + pNormalObject->f = pComplexObject->f; + pNormalObject->g = pComplexObject->g; + pNormalObject->jj = pComplexObject->jj; + pNormalObject->kk = pComplexObject->kk; + pNormalObject->l = pComplexObject->l; + pNormalObject->ll = {static_cast(0x8000000000000000LL), -9999999999999999L, -99999999L, -99L, 0L, 99L, + 99999999L, 9999999999999999L, 0x7fffffffffffffffLL}; + pNormalObject->lll.emplace_back(pComplexObject->kk); + pNormalObject->lll.emplace_back(pComplexObject->kk); + pNormalObject->lll.emplace_back(pComplexObject->kk); + pNormalObject->llll = pComplexObject->llll; + pNormalObject->m = pComplexObject->m; + pNormalObject->mm = pComplexObject->mm; + pNormalObject->s = pComplexObject->s; + pNormalObject->ssss = pComplexObject->ssss; + } + + void zfooTest() { + ByteBuffer buffer; + + clock_t start = clock(); + for (int i = 0; i < benchmark; i++) { + buffer.clear(); + write(buffer, pSimpleObject); + auto packet = read(buffer); + delete packet; + } + cout << "[zfoo] [简单对象][size:" << buffer.writerIndex() << "] [time:" << (clock() - start) << "]" << endl; + + start = clock(); + for (int i = 0; i < benchmark; i++) { + buffer.clear(); + write(buffer, pNormalObject); + auto packet = read(buffer); + delete packet; + } + cout << "[zfoo] [常规对象][size:" << buffer.writerIndex() << "] [time:" << (clock() - start) << "]" << endl; + + start = clock(); + for (int i = 0; i < benchmark; i++) { + buffer.clear(); + write(buffer, pComplexObject); + auto packet = read(buffer); + delete packet; + } + cout << "[zfoo] [复杂对象][size:" << buffer.writerIndex() << "] [time:" << (clock() - start) << "]" << endl; + } + + void singleThreadBenchmarks() { + if (benchmark <= 0 || benchmark >= 1000000000) { + return; + } + cout << "[单线程性能测试-->[benchmark:" << benchmark << "]]" << endl; + zfooTest(); + benchmark = benchmark * 2; + singleThreadBenchmarks(); + } + +} + +#endif \ No newline at end of file diff --git a/protocol/src/test/cpp/zfoocpp/ByteBuffer.h b/protocol/src/test/cpp/zfoocpp/ByteBuffer.h new file mode 100644 index 00000000..fafe9735 --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/ByteBuffer.h @@ -0,0 +1,1386 @@ +#ifndef ZFOO_BYTEBUFFER_H +#define ZFOO_BYTEBUFFER_H + +#include +#include +#include +#include +#include +#include +#include + +// 网络传输默认使用大端传输 +namespace zfoo { + + using std::string; + using std::vector; + using std::list; + using std::set; + using std::map; + using std::make_pair; + using std::pair; + using std::unique_ptr; + + // Returns true if the current machine is little endian + static inline bool is_little_endian() { + static std::int32_t test = 1; + return (*reinterpret_cast(&test) == 1); + } + + // Default size of the buffer + static const int32_t DEFAULT_BUFFER_SIZE = 2048; + static const bool IS_LITTLE_ENDIAN = is_little_endian(); + static const string EMPTY_STRING = ""; + + + class ByteBuffer; + + class IPacket { + public: + virtual int16_t protocolId() = 0; + + virtual ~IPacket() { + } + }; + + class IProtocolRegistration { + public: + virtual int16_t protocolId() = 0; + + virtual void write(ByteBuffer &buffer, IPacket *packet) = 0; + + virtual IPacket *read(ByteBuffer &buffer) = 0; + }; + + IProtocolRegistration *getProtocol(int16_t protocolId); + + class ByteBuffer { + private: + int8_t *m_buffer; + int32_t m_max_capacity; + int32_t m_writerIndex; + int32_t m_readerIndex; + + public: + ByteBuffer(int32_t capacity = DEFAULT_BUFFER_SIZE) : m_max_capacity(capacity) { + m_buffer = (int8_t *) calloc(m_max_capacity, sizeof(int8_t)); + clear(); + } + + ~ByteBuffer() { + free(m_buffer); + m_buffer = nullptr; + } + + + ByteBuffer(const ByteBuffer &buffer) = delete; + + ByteBuffer &operator=(const ByteBuffer &buffer) = delete; + + + void clear() { + m_writerIndex = 0; + m_readerIndex = 0; + } + + int32_t writerIndex() const { + return m_writerIndex; + } + + int32_t readerIndex() const { + return m_readerIndex; + } + + void writerIndex(int32_t writeIndex) { + if (writeIndex > m_max_capacity) { + string errorMessage = + "writeIndex[" + std::to_string(writeIndex) + "] out of bounds exception: readerIndex: " + + std::to_string(m_readerIndex) + + ", writerIndex: " + std::to_string(m_writerIndex) + + "(expected: 0 <= readerIndex <= writerIndex <= capacity:" + std::to_string(m_max_capacity); + throw errorMessage; + } + m_writerIndex = writeIndex; + } + + void readerIndex(int32_t readerIndex) { + if (readerIndex > m_writerIndex) { + string errorMessage = + "readIndex[" + std::to_string(readerIndex) + "] out of bounds exception: readerIndex: " + + std::to_string(m_readerIndex) + + ", writerIndex: " + std::to_string(m_writerIndex) + + "(expected: 0 <= readerIndex <= writerIndex <= capacity:" + std::to_string(m_max_capacity); + throw errorMessage; + } + m_readerIndex = readerIndex; + } + + inline int32_t getCapacity() const { + return m_max_capacity - m_writerIndex; + } + + inline void ensureCapacity(const int32_t &capacity) { + while (capacity - getCapacity() > 0) { + int32_t newSize = m_max_capacity * 2; + int8_t *pBuf = (int8_t *) realloc(m_buffer, newSize); + if (!pBuf) { + std::cout << "relloc failed!" << std::endl; + exit(1); + } + m_buffer = pBuf; + m_max_capacity = newSize; + } + } + + inline void writeBool(const bool &value) { + ensureCapacity(1); + int8_t v = value ? 1 : 0; + m_buffer[m_writerIndex++] = v; + } + + inline bool readBool() { + int8_t value = m_buffer[m_readerIndex++]; + return value == 1; + } + + inline void writeByte(const int8_t &value) { + ensureCapacity(1); + m_buffer[m_writerIndex++] = value; + } + + inline int8_t readByte() { + return m_buffer[m_readerIndex++]; + } + + inline void setByte(const int32_t &index, const int8_t &value) { + m_buffer[index] = value; + } + + inline int8_t getByte(const int32_t &index) { + return m_buffer[index]; + } + + inline void writeBytes(const int8_t *buffer, const int32_t &length) { + ensureCapacity(length); + memcpy(&m_buffer[m_writerIndex], buffer, length); + m_writerIndex += length; + } + + inline int8_t *readBytes(const int32_t &length) { + int8_t *bytes = &m_buffer[m_readerIndex]; + m_readerIndex += length; + return bytes; + } + + + inline void writeShort(const int16_t &value) { + write(value); + } + + inline int16_t readShort() { + return read(); + } + + inline void writeInt(const int32_t &intValue) { + writeVarInt((uint32_t) ((intValue << 1) ^ (intValue >> 31))); + } + + inline void writeVarInt(const uint32_t &value) { + uint32_t a = value >> 7; + if (a == 0) { + writeByte((int8_t) value); + return; + } + + int32_t writeIndex = m_writerIndex; + ensureCapacity(5); + + setByte(writeIndex++, (int8_t) (value | 0x80)); + uint32_t b = value >> 14; + if (b == 0) { + setByte(writeIndex++, (int8_t) a); + writerIndex(writeIndex); + return; + } + + setByte(writeIndex++, (int8_t) (a | 0x80)); + a = value >> 21; + if (a == 0) { + setByte(writeIndex++, (int8_t) b); + writerIndex(writeIndex); + return; + } + + setByte(writeIndex++, (int8_t) (b | 0x80)); + b = value >> 28; + if (b == 0) { + setByte(writeIndex++, (int8_t) a); + writerIndex(writeIndex); + return; + } + + setByte(writeIndex++, (int8_t) (a | 0x80)); + setByte(writeIndex++, (int8_t) b); + writerIndex(writeIndex); + } + + inline int32_t readInt() { + int32_t readIndex = m_readerIndex; + + int32_t b = getByte(readIndex++); + uint32_t value = b; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x0000007F | b << 7; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x00003FFF | b << 14; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x001FFFFF | b << 21; + if (b < 0) { + value = value & 0x0FFFFFFF | getByte(readIndex++) << 28; + } + } + } + } + readerIndex(readIndex); + value = ((value >> 1) ^ -((int32_t) value & 1)); + return (int32_t) value; + } + + inline void writeLong(const int64_t &longValue) { + uint64_t mask = (uint64_t) ((longValue << 1) ^ (longValue >> 63)); + + if (mask >> 32 == 0) { + writeVarInt((uint32_t) mask); + return; + } + + int8_t bytes[9]; + bytes[0] = (int8_t) (mask | 0x80); + bytes[1] = (int8_t) (mask >> 7 | 0x80); + bytes[2] = (int8_t) (mask >> 14 | 0x80); + bytes[3] = (int8_t) (mask >> 21 | 0x80); + + uint32_t a = (uint32_t) (mask >> 28); + uint32_t b = (uint32_t) (mask >> 35); + if (b == 0) { + bytes[4] = (int8_t) a; + writeBytes(bytes, 5); + return; + } + + bytes[4] = (int8_t) (a | 0x80); + a = (uint32_t) (mask >> 42); + if (a == 0) { + bytes[5] = (int8_t) b; + writeBytes(bytes, 6); + return; + } + + bytes[5] = (int8_t) (b | 0x80); + b = (int) (mask >> 49); + if (b == 0) { + bytes[6] = (int8_t) a; + writeBytes(bytes, 7); + return; + } + + bytes[6] = (int8_t) (a | 0x80); + a = (int) (mask >> 56); + if (a == 0) { + bytes[7] = (int8_t) b; + writeBytes(bytes, 8); + return; + } + + bytes[7] = (int8_t) (b | 0x80); + bytes[8] = (int8_t) a; + writeBytes(bytes, 9); + } + + inline int64_t readLong() { + int32_t readIndex = m_readerIndex; + + int64_t b = getByte(readIndex++); + uint64_t value = b; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x000000000000007FLL | b << 7; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x0000000000003FFFLL | b << 14; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x00000000001FFFFFLL | b << 21; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x000000000FFFFFFFLL | b << 28; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x00000007FFFFFFFFLL | b << 35; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x000003FFFFFFFFFFLL | b << 42; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x0001FFFFFFFFFFFFLL | b << 49; + if (b < 0) { + b = getByte(readIndex++); + value = value & 0x00FFFFFFFFFFFFFFLL | b << 56; + } + } + } + } + } + } + } + } + + readerIndex(readIndex); + value = ((value >> 1) ^ -((int64_t) value & 1)); + return (int64_t) value; + } + + inline void writeFloat(const float &value) { + write(value); + } + + inline float readFloat() { + return read(); + } + + inline void writeDouble(const double &value) { + write(value); + } + + inline double readDouble() { + return read(); + } + + inline void writeString(const string &value) { + if (value.empty()) { + writeInt(0); + return; + } + int32_t length = value.size() * sizeof(value.front()); + writeInt(length); + writeBytes(reinterpret_cast(&value[0]), length); + } + + inline string readString() { + int32_t length = readInt(); + if (length <= 0) { + return EMPTY_STRING; + } + + auto bytes = readBytes(length); + string str(reinterpret_cast(bytes), length); + return str; + } + + // 很多脚本语言没有char,所以这里使用string代替 + inline void writeChar(const char &value) { + string str; + str.push_back(value); + writeString(str); + } + + inline char readChar() { + return readString()[0]; + } + + inline bool writePacketFlag(const IPacket *packet) { + bool flag = packet == nullptr; + writeBool(!flag); + return flag; + } + + inline void writePacket(IPacket *packet, const int16_t &protocolId) { + IProtocolRegistration *protocolRegistration = getProtocol(protocolId); + protocolRegistration->write(*this, packet); + } + + inline unique_ptr readPacket(const int16_t &protocolId) { + IProtocolRegistration *protocolRegistration = getProtocol(protocolId); + auto packet = protocolRegistration->read(*this); + return unique_ptr(packet); + } + + + //---------------------------------boolean-------------------------------------- + inline void writeBooleanArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeBool(value); + } + } + + inline vector readBooleanArray() { + int32_t length = readInt(); + int8_t *bytes = readBytes(length); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back((bytes[i] == 1)); + } + return array; + } + + inline void writeBooleanList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeBool(value); + } + } + + inline list readBooleanList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readBool()); + } + return list; + } + + inline void writeBooleanSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeBool(value); + } + } + + inline set readBooleanSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readBool()); + } + return set; + } + + //---------------------------------byte-------------------------------------- + inline void writeByteArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeByte(value); + } + } + + inline vector readByteArray() { + int32_t length = readInt(); + int8_t *bytes = readBytes(length); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(bytes[i]); + } + return array; + } + + inline void writeByteList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeByte(value); + } + } + + inline list readByteList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readByte()); + } + return list; + } + + inline void writeByteSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeByte(value); + } + } + + inline set readByteSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readByte()); + } + return set; + } + + //---------------------------------short-------------------------------------- + inline void writeShortArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeShort(value); + } + } + + inline vector readShortArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readShort()); + } + return array; + } + + inline void writeShortList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeShort(value); + } + } + + inline list readShortList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readShort()); + } + return list; + } + + inline void writeShortSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeShort(value); + } + } + + inline set readShortSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readShort()); + } + return set; + } + + //---------------------------------int-------------------------------------- + inline void writeIntArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeInt(value); + } + } + + inline vector readIntArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readInt()); + } + return array; + } + + inline void writeIntList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeInt(value); + } + } + + inline list readIntList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readInt()); + } + return list; + } + + inline void writeIntSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeInt(value); + } + } + + inline set readIntSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readInt()); + } + return set; + } + + //---------------------------------long-------------------------------------- + inline void writeLongArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeLong(value); + } + } + + inline vector readLongArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readLong()); + } + return array; + } + + inline void writeLongList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeLong(value); + } + } + + inline list readLongList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readLong()); + } + return list; + } + + inline void writeLongSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeLong(value); + } + } + + inline set readLongSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readLong()); + } + return set; + } + + //---------------------------------float-------------------------------------- + inline void writeFloatArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeFloat(value); + } + } + + inline vector readFloatArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readFloat()); + } + return array; + } + + inline void writeFloatList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeFloat(value); + } + } + + inline list readFloatList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readFloat()); + } + return list; + } + + inline void writeFloatSet(const set &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeFloat(value); + } + } + + inline set readFloatSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readFloat()); + } + return set; + } + + //---------------------------------double-------------------------------------- + inline void writeDoubleArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeDouble(value); + } + } + + inline vector readDoubleArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readDouble()); + } + return array; + } + + inline void writeDoubleList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeDouble(value); + } + } + + inline list readDoubleList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readDouble()); + } + return list; + } + + inline void writeDoubleSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeDouble(value); + } + } + + inline set readDoubleSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readDouble()); + } + return set; + } + + //---------------------------------char-------------------------------------- + inline void writeCharArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeChar(value); + } + } + + inline vector readCharArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readChar()); + } + return array; + } + + inline void writeCharList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeChar(value); + } + } + + inline list readCharList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readChar()); + } + return list; + } + + inline void writeCharSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeChar(value); + } + } + + inline set readCharSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readChar()); + } + return set; + } + + //---------------------------------string-------------------------------------- + inline void writeStringArray(const vector &array) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writeString(value); + } + } + + inline vector readStringArray() { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + array.emplace_back(readString()); + } + return array; + } + + inline void writeStringList(const list &list) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writeString(value); + } + } + + inline list readStringList() { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + list.emplace_back(readString()); + } + return list; + } + + inline void writeStringSet(const set &set) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writeString(value); + } + } + + inline set readStringSet() { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + set.emplace(readString()); + } + return set; + } + + inline void writeIntIntMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeInt(key); + writeInt(value); + } + } + + inline map readIntIntMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readInt(); + auto value = readInt(); + map.insert(pair(key, value)); + } + return map; + } + + inline void writeIntLongMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeInt(key); + writeLong(value); + } + } + + inline map readIntLongMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readInt(); + auto value = readLong(); + map.insert(pair(key, value)); + } + return map; + } + + inline void writeIntStringMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeInt(key); + writeString(value); + } + } + + inline map readIntStringMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readInt(); + auto value = readString(); + map.insert(pair(key, value)); + } + return map; + } + + template + inline void writeIntPacketMap(const map &map, const int16_t &protocolId) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeInt(key); + writePacket((IPacket *) &value, protocolId); + } + } + + template + inline map readIntPacketMap(const int16_t &protocolId) { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readInt(); + auto value = readPacket(protocolId); + auto *p = (T *) value.get(); + map.insert(pair(key, *p)); + } + return map; + } + + inline void writeLongIntMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeLong(key); + writeInt(value); + } + } + + inline map readLongIntMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readLong(); + auto value = readInt(); + map.insert(pair(key, value)); + } + return map; + } + + inline void writeLongLongMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeLong(key); + writeLong(value); + } + } + + inline map readLongLongMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readLong(); + auto value = readLong(); + map.insert(pair(key, value)); + } + return map; + } + + inline void writeLongStringMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeLong(key); + writeString(value); + } + } + + inline map readLongStringMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readLong(); + auto value = readString(); + map.insert(pair(key, value)); + } + return map; + } + + template + inline void writeLongPacketMap(const map &map, const int16_t &protocolId) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeLong(key); + writePacket((IPacket *) &value, protocolId); + } + } + + template + inline map readLongPacketMap(const int16_t &protocolId) { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readLong(); + auto value = readPacket(protocolId); + auto *p = (T *) value.get(); + map.insert(pair(key, *p)); + } + return map; + } + + inline void writeStringIntMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeString(key); + writeInt(value); + } + } + + inline map readStringIntMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readString(); + auto value = readInt(); + map.insert(pair(key, value)); + } + return map; + } + + inline void writeStringLongMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeString(key); + writeLong(value); + } + } + + inline map readStringLongMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readString(); + auto value = readLong(); + map.insert(pair(key, value)); + } + return map; + } + + inline void writeStringStringMap(const map &map) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeString(key); + writeString(value); + } + } + + inline map readStringStringMap() { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readString(); + auto value = readString(); + map.insert(pair(key, value)); + } + return map; + } + + template + inline void writeStringPacketMap(const map &map, const int16_t &protocolId) { + if (map.empty()) { + writeByte(0); + return; + } + writeInt(map.size()); + for (const auto&[key, value] : map) { + writeString(key); + writePacket((IPacket *) &value, protocolId); + } + } + + template + inline map readStringPacketMap(const int16_t &protocolId) { + int32_t length = readInt(); + map map; + for (auto i = 0; i < length; i++) { + auto key = readString(); + auto value = readPacket(protocolId); + auto *p = (T *) value.get(); + map.insert(pair(key, *p)); + } + return map; + } + + + //---------------------------------packet-------------------------------------- + template + inline void writePacketArray(const vector &array, const int16_t &protocolId) { + if (array.empty()) { + writeByte(0); + return; + } + int32_t length = array.size(); + writeInt(length); + for (auto value : array) { + writePacket((IPacket *) &value, protocolId); + } + } + + template + inline vector readPacketArray(const int16_t &protocolId) { + int32_t length = readInt(); + vector array; + for (auto i = 0; i < length; i++) { + auto value = readPacket(protocolId); + auto *p = (T *) value.get(); + array.emplace_back(*p); + } + return array; + } + + template + inline void writePacketList(const list &list, const int16_t &protocolId) { + if (list.empty()) { + writeByte(0); + return; + } + int32_t length = list.size(); + writeInt(length); + for (auto value : list) { + writePacket((IPacket *) &value, protocolId); + } + } + + template + inline list readPacketList(const int16_t &protocolId) { + int32_t length = readInt(); + list list; + for (auto i = 0; i < length; i++) { + auto value = readPacket(protocolId); + auto *p = (T *) value.get(); + list.emplace_back(*p); + } + return list; + } + + template + inline void writePacketSet(const set &set, const int16_t &protocolId) { + if (set.empty()) { + writeByte(0); + return; + } + int32_t length = set.size(); + writeInt(length); + for (auto value : set) { + writePacket((IPacket *) &value, protocolId); + } + } + + template + inline set readPacketSet(const int16_t &protocolId) { + int32_t length = readInt(); + set set; + for (auto i = 0; i < length; i++) { + auto value = readPacket(protocolId); + auto *p = (T *) value.get(); + set.emplace(*p); + } + return set; + } + + private: + template + inline void write(T value) { + ensureCapacity(sizeof(T)); + // MSDN: The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian). + // ** This mean the network byte order is big-endian ** + if (IS_LITTLE_ENDIAN) { + swap_bytes(reinterpret_cast(&value)); + } + memcpy(&m_buffer[m_writerIndex], (int8_t *) &value, sizeof(T)); + m_writerIndex += sizeof(T); + } + + template + inline T read() { + T value = *((T *) &m_buffer[m_readerIndex]); + if (IS_LITTLE_ENDIAN) { + swap_bytes(reinterpret_cast(&value)); + } + m_readerIndex += sizeof(T); + return value; + } + + // Swaps the order of bytes for some chunk of memory + template + inline void swap_bytes(int8_t *data) { + for (std::size_t i = 0, end = DataSize / 2; i < end; ++i) { + std::swap(data[i], data[DataSize - i - 1]); + } + } + }; + +} + +#endif diff --git a/protocol/src/test/cpp/zfoocpp/ComplexObject.h b/protocol/src/test/cpp/zfoocpp/ComplexObject.h new file mode 100644 index 00000000..55f1d28f --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/ComplexObject.h @@ -0,0 +1,555 @@ +#ifndef ZFOO_COMPLEXOBJECT_H +#define ZFOO_COMPLEXOBJECT_H + +#include "zfoocpp/ByteBuffer.h" +#include "zfoocpp/ObjectA.h" +#include "zfoocpp/ObjectB.h" + +namespace zfoo { + + // 复杂的对象 + // 包括了各种复杂的结构,数组,List,Set,Map + // + // @author jaysunxiao + // @version 3.0 + class ComplexObject : public IPacket { + public: + // byte类型,最简单的整形 + int8_t a; + // byte的包装类型 + // 优先使用基础类型,包装类型会有装箱拆箱 + int8_t aa; + // 数组类型 + vector aaa; + vector aaaa; + int16_t b; + int16_t bb; + vector bbb; + vector bbbb; + int32_t c; + int32_t cc; + vector ccc; + vector cccc; + int64_t d; + int64_t dd; + vector ddd; + vector dddd; + float e; + float ee; + vector eee; + vector eeee; + double f; + double ff; + vector fff; + vector ffff; + bool g; + bool gg; + vector ggg; + vector gggg; + char h; + char hh; + vector hhh; + vector hhhh; + string jj; + vector jjj; + ObjectA kk; + vector kkk; + list l; + list>> ll; + list> lll; + list llll; + list> lllll; + map m; + map mm; + map> mmm; + map>, list>>> mmmm; + map>, set>> mmmmm; + set s; + set>> ss; + set> sss; + set ssss; + set> sssss; + + ~ComplexObject() override = default; + + static ComplexObject valueOf(int8_t a, int8_t aa, vector aaa, vector aaaa, int16_t b, int16_t bb, vector bbb, vector bbbb, int32_t c, int32_t cc, vector ccc, vector cccc, int64_t d, int64_t dd, vector ddd, vector dddd, float e, float ee, vector eee, vector eeee, double f, double ff, vector fff, vector ffff, bool g, bool gg, vector ggg, vector gggg, char h, char hh, vector hhh, vector hhhh, string jj, vector jjj, ObjectA kk, vector kkk, list l, list>> ll, list> lll, list llll, list> lllll, map m, map mm, map> mmm, map>, list>>> mmmm, map>, set>> mmmmm, set s, set>> ss, set> sss, set ssss, set> sssss) { + auto packet = ComplexObject(); + packet.a = a; + packet.aa = aa; + packet.aaa = aaa; + packet.aaaa = aaaa; + packet.b = b; + packet.bb = bb; + packet.bbb = bbb; + packet.bbbb = bbbb; + packet.c = c; + packet.cc = cc; + packet.ccc = ccc; + packet.cccc = cccc; + packet.d = d; + packet.dd = dd; + packet.ddd = ddd; + packet.dddd = dddd; + packet.e = e; + packet.ee = ee; + packet.eee = eee; + packet.eeee = eeee; + packet.f = f; + packet.ff = ff; + packet.fff = fff; + packet.ffff = ffff; + packet.g = g; + packet.gg = gg; + packet.ggg = ggg; + packet.gggg = gggg; + packet.h = h; + packet.hh = hh; + packet.hhh = hhh; + packet.hhhh = hhhh; + packet.jj = jj; + packet.jjj = jjj; + packet.kk = kk; + packet.kkk = kkk; + packet.l = l; + packet.ll = ll; + packet.lll = lll; + packet.llll = llll; + packet.lllll = lllll; + packet.m = m; + packet.mm = mm; + packet.mmm = mmm; + packet.mmmm = mmmm; + packet.mmmmm = mmmmm; + packet.s = s; + packet.ss = ss; + packet.sss = sss; + packet.ssss = ssss; + packet.sssss = sssss; + return packet; + } + + int16_t protocolId() override { + return 100; + } + + bool operator<(const ComplexObject &_) const { + if (a < _.a) { return true; } + if (_.a < a) { return false; } + if (aa < _.aa) { return true; } + if (_.aa < aa) { return false; } + if (aaa < _.aaa) { return true; } + if (_.aaa < aaa) { return false; } + if (aaaa < _.aaaa) { return true; } + if (_.aaaa < aaaa) { return false; } + if (b < _.b) { return true; } + if (_.b < b) { return false; } + if (bb < _.bb) { return true; } + if (_.bb < bb) { return false; } + if (bbb < _.bbb) { return true; } + if (_.bbb < bbb) { return false; } + if (bbbb < _.bbbb) { return true; } + if (_.bbbb < bbbb) { return false; } + if (c < _.c) { return true; } + if (_.c < c) { return false; } + if (cc < _.cc) { return true; } + if (_.cc < cc) { return false; } + if (ccc < _.ccc) { return true; } + if (_.ccc < ccc) { return false; } + if (cccc < _.cccc) { return true; } + if (_.cccc < cccc) { return false; } + if (d < _.d) { return true; } + if (_.d < d) { return false; } + if (dd < _.dd) { return true; } + if (_.dd < dd) { return false; } + if (ddd < _.ddd) { return true; } + if (_.ddd < ddd) { return false; } + if (dddd < _.dddd) { return true; } + if (_.dddd < dddd) { return false; } + if (e < _.e) { return true; } + if (_.e < e) { return false; } + if (ee < _.ee) { return true; } + if (_.ee < ee) { return false; } + if (eee < _.eee) { return true; } + if (_.eee < eee) { return false; } + if (eeee < _.eeee) { return true; } + if (_.eeee < eeee) { return false; } + if (f < _.f) { return true; } + if (_.f < f) { return false; } + if (ff < _.ff) { return true; } + if (_.ff < ff) { return false; } + if (fff < _.fff) { return true; } + if (_.fff < fff) { return false; } + if (ffff < _.ffff) { return true; } + if (_.ffff < ffff) { return false; } + if (g < _.g) { return true; } + if (_.g < g) { return false; } + if (gg < _.gg) { return true; } + if (_.gg < gg) { return false; } + if (ggg < _.ggg) { return true; } + if (_.ggg < ggg) { return false; } + if (gggg < _.gggg) { return true; } + if (_.gggg < gggg) { return false; } + if (h < _.h) { return true; } + if (_.h < h) { return false; } + if (hh < _.hh) { return true; } + if (_.hh < hh) { return false; } + if (hhh < _.hhh) { return true; } + if (_.hhh < hhh) { return false; } + if (hhhh < _.hhhh) { return true; } + if (_.hhhh < hhhh) { return false; } + if (jj < _.jj) { return true; } + if (_.jj < jj) { return false; } + if (jjj < _.jjj) { return true; } + if (_.jjj < jjj) { return false; } + if (kk < _.kk) { return true; } + if (_.kk < kk) { return false; } + if (kkk < _.kkk) { return true; } + if (_.kkk < kkk) { return false; } + if (l < _.l) { return true; } + if (_.l < l) { return false; } + if (ll < _.ll) { return true; } + if (_.ll < ll) { return false; } + if (lll < _.lll) { return true; } + if (_.lll < lll) { return false; } + if (llll < _.llll) { return true; } + if (_.llll < llll) { return false; } + if (lllll < _.lllll) { return true; } + if (_.lllll < lllll) { return false; } + if (m < _.m) { return true; } + if (_.m < m) { return false; } + if (mm < _.mm) { return true; } + if (_.mm < mm) { return false; } + if (mmm < _.mmm) { return true; } + if (_.mmm < mmm) { return false; } + if (mmmm < _.mmmm) { return true; } + if (_.mmmm < mmmm) { return false; } + if (mmmmm < _.mmmmm) { return true; } + if (_.mmmmm < mmmmm) { return false; } + if (s < _.s) { return true; } + if (_.s < s) { return false; } + if (ss < _.ss) { return true; } + if (_.ss < ss) { return false; } + if (sss < _.sss) { return true; } + if (_.sss < sss) { return false; } + if (ssss < _.ssss) { return true; } + if (_.ssss < ssss) { return false; } + if (sssss < _.sssss) { return true; } + if (_.sssss < sssss) { return false; } + return false; + } + }; + + + class ComplexObjectRegistration : public IProtocolRegistration { + public: + int16_t protocolId() override { + return 100; + } + + void write(ByteBuffer &buffer, IPacket *packet) override { + if (buffer.writePacketFlag(packet)) { + return; + } + auto *message = (ComplexObject *) packet; + buffer.writeByte(message->a); + buffer.writeByte(message->aa); + buffer.writeByteArray(message->aaa); + buffer.writeByteArray(message->aaaa); + buffer.writeShort(message->b); + buffer.writeShort(message->bb); + buffer.writeShortArray(message->bbb); + buffer.writeShortArray(message->bbbb); + buffer.writeInt(message->c); + buffer.writeInt(message->cc); + buffer.writeIntArray(message->ccc); + buffer.writeIntArray(message->cccc); + buffer.writeLong(message->d); + buffer.writeLong(message->dd); + buffer.writeLongArray(message->ddd); + buffer.writeLongArray(message->dddd); + buffer.writeFloat(message->e); + buffer.writeFloat(message->ee); + buffer.writeFloatArray(message->eee); + buffer.writeFloatArray(message->eeee); + buffer.writeDouble(message->f); + buffer.writeDouble(message->ff); + buffer.writeDoubleArray(message->fff); + buffer.writeDoubleArray(message->ffff); + buffer.writeBool(message->g); + buffer.writeBool(message->gg); + buffer.writeBooleanArray(message->ggg); + buffer.writeBooleanArray(message->gggg); + buffer.writeChar(message->h); + buffer.writeChar(message->hh); + buffer.writeCharArray(message->hhh); + buffer.writeCharArray(message->hhhh); + buffer.writeString(message->jj); + buffer.writeStringArray(message->jjj); + buffer.writePacket(&message->kk, 102); + buffer.writePacketArray(message->kkk, 102); + buffer.writeIntList(message->l); + buffer.writeInt(message->ll.size()); + for (auto i0 : message->ll) { + buffer.writeInt(i0.size()); + for (auto i1 : i0) { + buffer.writeIntList(i1); + } + } + buffer.writeInt(message->lll.size()); + for (auto i2 : message->lll) { + buffer.writePacketList(i2, 102); + } + buffer.writeStringList(message->llll); + buffer.writeInt(message->lllll.size()); + for (auto i3 : message->lllll) { + buffer.writeIntStringMap(i3); + } + buffer.writeIntStringMap(message->m); + buffer.writeIntPacketMap(message->mm, 102); + buffer.writeInt(message->mmm.size()); + for (auto&[keyElement4, valueElement5] : message->mmm) { + buffer.writePacket((IPacket *) &keyElement4, 102); + buffer.writeIntList(valueElement5); + } + buffer.writeInt(message->mmmm.size()); + for (auto&[keyElement6, valueElement7] : message->mmmm) { + buffer.writeInt(keyElement6.size()); + for (auto i8 : keyElement6) { + buffer.writePacketList(i8, 102); + } + buffer.writeInt(valueElement7.size()); + for (auto i9 : valueElement7) { + buffer.writeInt(i9.size()); + for (auto i10 : i9) { + buffer.writeIntList(i10); + } + } + } + buffer.writeInt(message->mmmmm.size()); + for (auto&[keyElement11, valueElement12] : message->mmmmm) { + buffer.writeInt(keyElement11.size()); + for (auto i13 : keyElement11) { + buffer.writeIntStringMap(i13); + } + buffer.writeInt(valueElement12.size()); + for (auto i14 : valueElement12) { + buffer.writeIntStringMap(i14); + } + } + buffer.writeIntSet(message->s); + buffer.writeInt(message->ss.size()); + for (auto i15 : message->ss) { + buffer.writeInt(i15.size()); + for (auto i16 : i15) { + buffer.writeIntList(i16); + } + } + buffer.writeInt(message->sss.size()); + for (auto i17 : message->sss) { + buffer.writePacketSet(i17, 102); + } + buffer.writeStringSet(message->ssss); + buffer.writeInt(message->sssss.size()); + for (auto i18 : message->sssss) { + buffer.writeIntStringMap(i18); + } + } + + IPacket *read(ByteBuffer &buffer) override { + auto *packet = new ComplexObject(); + if (!buffer.readBool()) { + return packet; + } + int8_t result19 = buffer.readByte(); + packet->a = result19; + int8_t result20 = buffer.readByte(); + packet->aa = result20; + auto array21 = buffer.readByteArray(); + packet->aaa = array21; + auto array22 = buffer.readByteArray(); + packet->aaaa = array22; + auto result23 = buffer.readShort(); + packet->b = result23; + auto result24 = buffer.readShort(); + packet->bb = result24; + auto array25 = buffer.readShortArray(); + packet->bbb = array25; + auto array26 = buffer.readShortArray(); + packet->bbbb = array26; + int32_t result27 = buffer.readInt(); + packet->c = result27; + int32_t result28 = buffer.readInt(); + packet->cc = result28; + auto array29 = buffer.readIntArray(); + packet->ccc = array29; + auto array30 = buffer.readIntArray(); + packet->cccc = array30; + auto result31 = buffer.readLong(); + packet->d = result31; + auto result32 = buffer.readLong(); + packet->dd = result32; + auto array33 = buffer.readLongArray(); + packet->ddd = array33; + auto array34 = buffer.readLongArray(); + packet->dddd = array34; + float result35 = buffer.readFloat(); + packet->e = result35; + float result36 = buffer.readFloat(); + packet->ee = result36; + auto array37 = buffer.readFloatArray(); + packet->eee = array37; + auto array38 = buffer.readFloatArray(); + packet->eeee = array38; + double result39 = buffer.readDouble(); + packet->f = result39; + double result40 = buffer.readDouble(); + packet->ff = result40; + auto array41 = buffer.readDoubleArray(); + packet->fff = array41; + auto array42 = buffer.readDoubleArray(); + packet->ffff = array42; + bool result43 = buffer.readBool(); + packet->g = result43; + bool result44 = buffer.readBool(); + packet->gg = result44; + auto array45 = buffer.readBooleanArray(); + packet->ggg = array45; + auto array46 = buffer.readBooleanArray(); + packet->gggg = array46; + char result47 = buffer.readChar(); + packet->h = result47; + char result48 = buffer.readChar(); + packet->hh = result48; + auto array49 = buffer.readCharArray(); + packet->hhh = array49; + auto array50 = buffer.readCharArray(); + packet->hhhh = array50; + auto result51 = buffer.readString(); + packet->jj = result51; + auto array52 = buffer.readStringArray(); + packet->jjj = array52; + auto result53 = buffer.readPacket(102); + auto *result54 = (ObjectA *) result53.get(); + packet->kk = *result54; + auto array55 = buffer.readPacketArray(102); + packet->kkk = array55; + auto list56 = buffer.readIntList(); + packet->l = list56; + int32_t size59 = buffer.readInt(); + list>> result57; + for (int index58 = 0; index58 < size59; index58++) { + int32_t size62 = buffer.readInt(); + list> result60; + for (int index61 = 0; index61 < size62; index61++) { + auto list63 = buffer.readIntList(); + result60.emplace_back(list63); + } + result57.emplace_back(result60); + } + packet->ll = result57; + int32_t size66 = buffer.readInt(); + list> result64; + for (int index65 = 0; index65 < size66; index65++) { + auto list67 = buffer.readPacketList(102); + result64.emplace_back(list67); + } + packet->lll = result64; + auto list68 = buffer.readStringList(); + packet->llll = list68; + int32_t size71 = buffer.readInt(); + list> result69; + for (int index70 = 0; index70 < size71; index70++) { + auto map72 = buffer.readIntStringMap(); + result69.emplace_back(map72); + } + packet->lllll = result69; + auto map73 = buffer.readIntStringMap(); + packet->m = map73; + auto map74 = buffer.readIntPacketMap(102); + packet->mm = map74; + int32_t size76 = buffer.readInt(); + map> result75; + for (auto index77 = 0; index77 < size76; index77++) { + auto result78 = buffer.readPacket(102); + auto *result79 = (ObjectA *) result78.get(); + auto list80 = buffer.readIntList(); + result75.insert(make_pair(*result79, list80)); + } + packet->mmm = result75; + int32_t size82 = buffer.readInt(); + map>, list>>> result81; + for (auto index83 = 0; index83 < size82; index83++) { + int32_t size86 = buffer.readInt(); + list> result84; + for (int index85 = 0; index85 < size86; index85++) { + auto list87 = buffer.readPacketList(102); + result84.emplace_back(list87); + } + int32_t size90 = buffer.readInt(); + list>> result88; + for (int index89 = 0; index89 < size90; index89++) { + int32_t size93 = buffer.readInt(); + list> result91; + for (int index92 = 0; index92 < size93; index92++) { + auto list94 = buffer.readIntList(); + result91.emplace_back(list94); + } + result88.emplace_back(result91); + } + result81.insert(make_pair(result84, result88)); + } + packet->mmmm = result81; + int32_t size96 = buffer.readInt(); + map>, set>> result95; + for (auto index97 = 0; index97 < size96; index97++) { + int32_t size100 = buffer.readInt(); + list> result98; + for (int index99 = 0; index99 < size100; index99++) { + auto map101 = buffer.readIntStringMap(); + result98.emplace_back(map101); + } + int32_t size104 = buffer.readInt(); + set> result102; + for (int index103 = 0; index103 < size104; index103++) { + auto map105 = buffer.readIntStringMap(); + result102.emplace(map105); + } + result95.insert(make_pair(result98, result102)); + } + packet->mmmmm = result95; + auto set106 = buffer.readIntSet(); + packet->s = set106; + int32_t size109 = buffer.readInt(); + set>> result107; + for (int index108 = 0; index108 < size109; index108++) { + int32_t size112 = buffer.readInt(); + set> result110; + for (int index111 = 0; index111 < size112; index111++) { + auto list113 = buffer.readIntList(); + result110.emplace(list113); + } + result107.emplace(result110); + } + packet->ss = result107; + int32_t size116 = buffer.readInt(); + set> result114; + for (int index115 = 0; index115 < size116; index115++) { + auto set117 = buffer.readPacketSet(102); + result114.emplace(set117); + } + packet->sss = result114; + auto set118 = buffer.readStringSet(); + packet->ssss = set118; + int32_t size121 = buffer.readInt(); + set> result119; + for (int index120 = 0; index120 < size121; index120++) { + auto map122 = buffer.readIntStringMap(); + result119.emplace(map122); + } + packet->sssss = result119; + return packet; + } + }; +} + +#endif diff --git a/protocol/src/test/cpp/zfoocpp/NormalObject.h b/protocol/src/test/cpp/zfoocpp/NormalObject.h new file mode 100644 index 00000000..ee9ec1a3 --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/NormalObject.h @@ -0,0 +1,182 @@ +#ifndef ZFOO_NORMALOBJECT_H +#define ZFOO_NORMALOBJECT_H + +#include "zfoocpp/ByteBuffer.h" +#include "zfoocpp/ObjectA.h" +#include "zfoocpp/ObjectB.h" + +namespace zfoo { + + // @author jaysunxiao + // @version 3.0 + class NormalObject : public IPacket { + public: + int8_t a; + vector aaa; + int16_t b; + int32_t c; + int64_t d; + float e; + double f; + bool g; + string jj; + ObjectA kk; + list l; + list ll; + list lll; + list llll; + map m; + map mm; + set s; + set ssss; + + ~NormalObject() override = default; + + static NormalObject valueOf(int8_t a, vector aaa, int16_t b, int32_t c, int64_t d, float e, double f, bool g, string jj, ObjectA kk, list l, list ll, list lll, list llll, map m, map mm, set s, set ssss) { + auto packet = NormalObject(); + packet.a = a; + packet.aaa = aaa; + packet.b = b; + packet.c = c; + packet.d = d; + packet.e = e; + packet.f = f; + packet.g = g; + packet.jj = jj; + packet.kk = kk; + packet.l = l; + packet.ll = ll; + packet.lll = lll; + packet.llll = llll; + packet.m = m; + packet.mm = mm; + packet.s = s; + packet.ssss = ssss; + return packet; + } + + int16_t protocolId() override { + return 101; + } + + bool operator<(const NormalObject &_) const { + if (a < _.a) { return true; } + if (_.a < a) { return false; } + if (aaa < _.aaa) { return true; } + if (_.aaa < aaa) { return false; } + if (b < _.b) { return true; } + if (_.b < b) { return false; } + if (c < _.c) { return true; } + if (_.c < c) { return false; } + if (d < _.d) { return true; } + if (_.d < d) { return false; } + if (e < _.e) { return true; } + if (_.e < e) { return false; } + if (f < _.f) { return true; } + if (_.f < f) { return false; } + if (g < _.g) { return true; } + if (_.g < g) { return false; } + if (jj < _.jj) { return true; } + if (_.jj < jj) { return false; } + if (kk < _.kk) { return true; } + if (_.kk < kk) { return false; } + if (l < _.l) { return true; } + if (_.l < l) { return false; } + if (ll < _.ll) { return true; } + if (_.ll < ll) { return false; } + if (lll < _.lll) { return true; } + if (_.lll < lll) { return false; } + if (llll < _.llll) { return true; } + if (_.llll < llll) { return false; } + if (m < _.m) { return true; } + if (_.m < m) { return false; } + if (mm < _.mm) { return true; } + if (_.mm < mm) { return false; } + if (s < _.s) { return true; } + if (_.s < s) { return false; } + if (ssss < _.ssss) { return true; } + if (_.ssss < ssss) { return false; } + return false; + } + }; + + + class NormalObjectRegistration : public IProtocolRegistration { + public: + int16_t protocolId() override { + return 101; + } + + void write(ByteBuffer &buffer, IPacket *packet) override { + if (buffer.writePacketFlag(packet)) { + return; + } + auto *message = (NormalObject *) packet; + buffer.writeByte(message->a); + buffer.writeByteArray(message->aaa); + buffer.writeShort(message->b); + buffer.writeInt(message->c); + buffer.writeLong(message->d); + buffer.writeFloat(message->e); + buffer.writeDouble(message->f); + buffer.writeBool(message->g); + buffer.writeString(message->jj); + buffer.writePacket(&message->kk, 102); + buffer.writeIntList(message->l); + buffer.writeLongList(message->ll); + buffer.writePacketList(message->lll, 102); + buffer.writeStringList(message->llll); + buffer.writeIntStringMap(message->m); + buffer.writeIntPacketMap(message->mm, 102); + buffer.writeIntSet(message->s); + buffer.writeStringSet(message->ssss); + } + + IPacket *read(ByteBuffer &buffer) override { + auto *packet = new NormalObject(); + if (!buffer.readBool()) { + return packet; + } + int8_t result0 = buffer.readByte(); + packet->a = result0; + auto array1 = buffer.readByteArray(); + packet->aaa = array1; + auto result2 = buffer.readShort(); + packet->b = result2; + int32_t result3 = buffer.readInt(); + packet->c = result3; + auto result4 = buffer.readLong(); + packet->d = result4; + float result5 = buffer.readFloat(); + packet->e = result5; + double result6 = buffer.readDouble(); + packet->f = result6; + bool result7 = buffer.readBool(); + packet->g = result7; + auto result8 = buffer.readString(); + packet->jj = result8; + auto result9 = buffer.readPacket(102); + auto *result10 = (ObjectA *) result9.get(); + packet->kk = *result10; + auto list11 = buffer.readIntList(); + packet->l = list11; + auto list12 = buffer.readLongList(); + packet->ll = list12; + auto list13 = buffer.readPacketList(102); + packet->lll = list13; + auto list14 = buffer.readStringList(); + packet->llll = list14; + auto map15 = buffer.readIntStringMap(); + packet->m = map15; + auto map16 = buffer.readIntPacketMap(102); + packet->mm = map16; + auto set17 = buffer.readIntSet(); + packet->s = set17; + auto set18 = buffer.readStringSet(); + packet->ssss = set18; + return packet; + } + }; +} + +#endif diff --git a/protocol/src/test/cpp/zfoocpp/ObjectA.h b/protocol/src/test/cpp/zfoocpp/ObjectA.h new file mode 100644 index 00000000..aae18594 --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/ObjectA.h @@ -0,0 +1,76 @@ +#ifndef ZFOO_OBJECTA_H +#define ZFOO_OBJECTA_H + +#include "zfoocpp/ByteBuffer.h" +#include "zfoocpp/ObjectB.h" + +namespace zfoo { + + // @author jaysunxiao + // @version 3.0 + class ObjectA : public IPacket { + public: + int32_t a; + map m; + ObjectB objectB; + + ~ObjectA() override = default; + + static ObjectA valueOf(int32_t a, map m, ObjectB objectB) { + auto packet = ObjectA(); + packet.a = a; + packet.m = m; + packet.objectB = objectB; + return packet; + } + + int16_t protocolId() override { + return 102; + } + + bool operator<(const ObjectA &_) const { + if (a < _.a) { return true; } + if (_.a < a) { return false; } + if (m < _.m) { return true; } + if (_.m < m) { return false; } + if (objectB < _.objectB) { return true; } + if (_.objectB < objectB) { return false; } + return false; + } + }; + + + class ObjectARegistration : public IProtocolRegistration { + public: + int16_t protocolId() override { + return 102; + } + + void write(ByteBuffer &buffer, IPacket *packet) override { + if (buffer.writePacketFlag(packet)) { + return; + } + auto *message = (ObjectA *) packet; + buffer.writeInt(message->a); + buffer.writeIntStringMap(message->m); + buffer.writePacket(&message->objectB, 103); + } + + IPacket *read(ByteBuffer &buffer) override { + auto *packet = new ObjectA(); + if (!buffer.readBool()) { + return packet; + } + int32_t result0 = buffer.readInt(); + packet->a = result0; + auto map1 = buffer.readIntStringMap(); + packet->m = map1; + auto result2 = buffer.readPacket(103); + auto *result3 = (ObjectB *) result2.get(); + packet->objectB = *result3; + return packet; + } + }; +} + +#endif diff --git a/protocol/src/test/cpp/zfoocpp/ObjectB.h b/protocol/src/test/cpp/zfoocpp/ObjectB.h new file mode 100644 index 00000000..97b3da2b --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/ObjectB.h @@ -0,0 +1,60 @@ +#ifndef ZFOO_OBJECTB_H +#define ZFOO_OBJECTB_H + +#include "zfoocpp/ByteBuffer.h" + +namespace zfoo { + + // @author jaysunxiao + // @version 3.0 + class ObjectB : public IPacket { + public: + bool flag; + + ~ObjectB() override = default; + + static ObjectB valueOf(bool flag) { + auto packet = ObjectB(); + packet.flag = flag; + return packet; + } + + int16_t protocolId() override { + return 103; + } + + bool operator<(const ObjectB &_) const { + if (flag < _.flag) { return true; } + if (_.flag < flag) { return false; } + return false; + } + }; + + + class ObjectBRegistration : public IProtocolRegistration { + public: + int16_t protocolId() override { + return 103; + } + + void write(ByteBuffer &buffer, IPacket *packet) override { + if (buffer.writePacketFlag(packet)) { + return; + } + auto *message = (ObjectB *) packet; + buffer.writeBool(message->flag); + } + + IPacket *read(ByteBuffer &buffer) override { + auto *packet = new ObjectB(); + if (!buffer.readBool()) { + return packet; + } + bool result0 = buffer.readBool(); + packet->flag = result0; + return packet; + } + }; +} + +#endif diff --git a/protocol/src/test/cpp/zfoocpp/ProtocolManager.h b/protocol/src/test/cpp/zfoocpp/ProtocolManager.h new file mode 100644 index 00000000..3976f499 --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/ProtocolManager.h @@ -0,0 +1,42 @@ +#ifndef ZFOO_PROTOCOLMANAGER_H +#define ZFOO_PROTOCOLMANAGER_H + +#include "ByteBuffer.h" +#include "zfoocpp/ComplexObject.h" +#include "zfoocpp/NormalObject.h" +#include "zfoocpp/ObjectA.h" +#include "zfoocpp/ObjectB.h" +#include "zfoocpp/SimpleObject.h" + +namespace zfoo { + + const int16_t MAX_PROTOCOL_NUM = 32767; + const IProtocolRegistration *protocols[MAX_PROTOCOL_NUM]; + + void initProtocol() { + protocols[100] = new ComplexObjectRegistration(); + protocols[101] = new NormalObjectRegistration(); + protocols[102] = new ObjectARegistration(); + protocols[103] = new ObjectBRegistration(); + protocols[104] = new SimpleObjectRegistration(); + } + + inline IProtocolRegistration *getProtocol(int16_t protocolId) { + return const_cast(protocols[protocolId]); + } + + void write(ByteBuffer &buffer, IPacket *packet) { + auto protocolId = packet->protocolId(); + // 写入协议号 + buffer.writeShort(protocolId); + // 写入包体 + getProtocol(protocolId)->write(buffer, packet); + } + + IPacket *read(ByteBuffer &buffer) { + auto protocolId = buffer.readShort(); + return getProtocol(protocolId)->read(buffer); + } + +} +#endif diff --git a/protocol/src/test/cpp/zfoocpp/SimpleObject.h b/protocol/src/test/cpp/zfoocpp/SimpleObject.h new file mode 100644 index 00000000..499ca26e --- /dev/null +++ b/protocol/src/test/cpp/zfoocpp/SimpleObject.h @@ -0,0 +1,67 @@ +#ifndef ZFOO_SIMPLEOBJECT_H +#define ZFOO_SIMPLEOBJECT_H + +#include "zfoocpp/ByteBuffer.h" + +namespace zfoo { + + // @author jaysunxiao + // @version 3.0 + class SimpleObject : public IPacket { + public: + int32_t c; + bool g; + + ~SimpleObject() override = default; + + static SimpleObject valueOf(int32_t c, bool g) { + auto packet = SimpleObject(); + packet.c = c; + packet.g = g; + return packet; + } + + int16_t protocolId() override { + return 104; + } + + bool operator<(const SimpleObject &_) const { + if (c < _.c) { return true; } + if (_.c < c) { return false; } + if (g < _.g) { return true; } + if (_.g < g) { return false; } + return false; + } + }; + + + class SimpleObjectRegistration : public IProtocolRegistration { + public: + int16_t protocolId() override { + return 104; + } + + void write(ByteBuffer &buffer, IPacket *packet) override { + if (buffer.writePacketFlag(packet)) { + return; + } + auto *message = (SimpleObject *) packet; + buffer.writeInt(message->c); + buffer.writeBool(message->g); + } + + IPacket *read(ByteBuffer &buffer) override { + auto *packet = new SimpleObject(); + if (!buffer.readBool()) { + return packet; + } + int32_t result0 = buffer.readInt(); + packet->c = result0; + bool result1 = buffer.readBool(); + packet->g = result1; + return packet; + } + }; +} + +#endif