From 086a2202ce9c807f776bf4cc8e2f9385760ceba2 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 3 Jan 2022 08:45:31 +0000 Subject: [PATCH] more --- include/util/encode.h | 49 ++++---- source/util/src/encode.c | 21 ++-- source/util/test/encodeTest.cpp | 199 ++++++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+), 32 deletions(-) diff --git a/include/util/encode.h b/include/util/encode.h index 31d386c450..ba63759737 100644 --- a/include/util/encode.h +++ b/include/util/encode.h @@ -81,31 +81,32 @@ void tCoderInit(SCoder* pCoder, td_endian_t endian, uint8_t* data, int32_t size, void tCoderClear(SCoder* pCoder); /* ------------------------ ENCODE ------------------------ */ -static int tStartEncode(SCoder* pEncoder); -static void tEndEncode(SCoder* pEncoder); -static int tEncodeU8(SCoder* pEncoder, uint8_t val); -static int tEncodeI8(SCoder* pEncoder, int8_t val); -static int tEncodeU16(SCoder* pEncoder, uint16_t val); -static int tEncodeI16(SCoder* pEncoder, int16_t val); -static int tEncodeU32(SCoder* pEncoder, uint32_t val); -static int tEncodeI32(SCoder* pEncoder, int32_t val); -static int tEncodeU64(SCoder* pEncoder, uint64_t val); -static int tEncodeI64(SCoder* pEncoder, int64_t val); -static int tEncodeU16v(SCoder* pEncoder, uint16_t val); -static int tEncodeI16v(SCoder* pEncoder, int16_t val); -static int tEncodeU32v(SCoder* pEncoder, uint32_t val); -static int tEncodeI32v(SCoder* pEncoder, int32_t val); -static int tEncodeU64v(SCoder* pEncoder, uint64_t val); -static int tEncodeI64v(SCoder* pEncoder, int64_t val); -static int tEncodeFloat(SCoder* pEncoder, float val); -static int tEncodeDouble(SCoder* pEncoder, double val); -static int tEncodeBinary(SCoder* pEncoder, const void* val, uint64_t len); -static int tEncodeCStrWithLen(SCoder* pEncoder, const char* val, uint64_t len); -static int tEncodeCStr(SCoder* pEncoder, const char* val); +int tStartEncode(SCoder* pEncoder); +void tEndEncode(SCoder* pEncoder); +static int tEncodeU8(SCoder* pEncoder, uint8_t val); +static int tEncodeI8(SCoder* pEncoder, int8_t val); +static int tEncodeU16(SCoder* pEncoder, uint16_t val); +static int tEncodeI16(SCoder* pEncoder, int16_t val); +static int tEncodeU32(SCoder* pEncoder, uint32_t val); +static int tEncodeI32(SCoder* pEncoder, int32_t val); +static int tEncodeU64(SCoder* pEncoder, uint64_t val); +static int tEncodeI64(SCoder* pEncoder, int64_t val); +static int tEncodeU16v(SCoder* pEncoder, uint16_t val); +static int tEncodeI16v(SCoder* pEncoder, int16_t val); +static int tEncodeU32v(SCoder* pEncoder, uint32_t val); +static int tEncodeI32v(SCoder* pEncoder, int32_t val); +static int tEncodeU64v(SCoder* pEncoder, uint64_t val); +static int tEncodeI64v(SCoder* pEncoder, int64_t val); +static int tEncodeFloat(SCoder* pEncoder, float val); +static int tEncodeDouble(SCoder* pEncoder, double val); +static int tEncodeBinary(SCoder* pEncoder, const void* val, uint64_t len); +static int tEncodeCStrWithLen(SCoder* pEncoder, const char* val, uint64_t len); +static int tEncodeCStr(SCoder* pEncoder, const char* val); /* ------------------------ DECODE ------------------------ */ -static int tStartDecode(SCoder* pDecoder); -static void tEndDecode(SCoder* pDecoder); +int tStartDecode(SCoder* pDecoder); +void tEndDecode(SCoder* pDecoder); +static bool tDecodeIsEnd(SCoder* pCoder); static int tDecodeU8(SCoder* pDecoder, uint8_t* val); static int tDecodeI8(SCoder* pDecoder, int8_t* val); static int tDecodeU16(SCoder* pDecoder, uint16_t* val); @@ -395,6 +396,8 @@ static int tDecodeCStrTo(SCoder* pDecoder, char* val) { return 0; } +static FORCE_INLINE bool tDecodeIsEnd(SCoder* pCoder) { return (pCoder->size == pCoder->pos); } + #ifdef __cplusplus } #endif diff --git a/source/util/src/encode.c b/source/util/src/encode.c index a3946daf5c..24d033f697 100644 --- a/source/util/src/encode.c +++ b/source/util/src/encode.c @@ -47,8 +47,6 @@ void tCoderClear(SCoder* pCoder) { } } -bool tDecodeIsEnd(SCoder* pCoder) { return (pCoder->size == pCoder->pos); } - int tStartEncode(SCoder* pCoder) { struct SCoderNode* pNode; @@ -62,7 +60,7 @@ int tStartEncode(SCoder* pCoder) { pNode->pos = pCoder->pos; pNode->size = pCoder->size; - pCoder->data = pNode->data + sizeof(int32_t); + pCoder->data = pNode->data + pNode->pos + sizeof(int32_t); pCoder->pos = 0; pCoder->size = pNode->size - pNode->pos - sizeof(int32_t); @@ -75,27 +73,32 @@ int tStartEncode(SCoder* pCoder) { void tEndEncode(SCoder* pCoder) { struct SCoderNode* pNode; + int32_t len; if (pCoder->data) { pNode = TD_SLIST_HEAD(&(pCoder->stack)); ASSERT(pNode); TD_SLIST_POP(&(pCoder->stack)); - // TODO: tEncodeI32(pNode, pCoder->pos); + len = pCoder->pos; pCoder->data = pNode->data; pCoder->size = pNode->size; - pCoder->pos = pNode->pos + pCoder->pos; + pCoder->pos = pNode->pos; + + tEncodeI32(pCoder, len); + + TD_CODER_MOVE_POS(pCoder, len); free(pNode); } } int tStartDecode(SCoder* pCoder) { - int32_t size; + int32_t len; struct SCoderNode* pNode; - // TODO: if (tDecodeI32(pCoder, &size) < 0) return -1; + if (tDecodeI32(pCoder, &len) < 0) return -1; pNode = malloc(sizeof(*pNode)); if (pNode == NULL) return -1; @@ -104,8 +107,8 @@ int tStartDecode(SCoder* pCoder) { pNode->pos = pCoder->pos; pNode->size = pCoder->size; - pCoder->data = pCoder->data; - pCoder->size = size; + pCoder->data = pNode->data + pNode->pos; + pCoder->size = len; pCoder->pos = 0; TD_SLIST_PUSH(&(pCoder->stack), pNode); diff --git a/source/util/test/encodeTest.cpp b/source/util/test/encodeTest.cpp index dc10cec443..b0e970eb07 100644 --- a/source/util/test/encodeTest.cpp +++ b/source/util/test/encodeTest.cpp @@ -198,4 +198,203 @@ TEST(td_encode_test, encode_decode_cstr) { delete buf; delete cstr; +} + +typedef struct { + int32_t A_a; + int64_t A_b; + char * A_c; +} SStructA_v1; + +static int tSStructA_v1_encode(SCoder *pCoder, const SStructA_v1 *pSAV1) { + if (tStartEncode(pCoder) < 0) return -1; + + if (tEncodeI32(pCoder, pSAV1->A_a) < 0) return -1; + if (tEncodeI64(pCoder, pSAV1->A_b) < 0) return -1; + if (tEncodeCStr(pCoder, pSAV1->A_c) < 0) return -1; + + tEndEncode(pCoder); + return 0; +} + +static int tSStructA_v1_decode(SCoder *pCoder, SStructA_v1 *pSAV1) { + if (tStartDecode(pCoder) < 0) return -1; + + if (tDecodeI32(pCoder, &pSAV1->A_a) < 0) return -1; + if (tDecodeI64(pCoder, &pSAV1->A_b) < 0) return -1; + const char *tstr; + uint64_t len; + if (tDecodeCStrAndLen(pCoder, &tstr, &len) < 0) return -1; + pSAV1->A_c = (char *)TCODER_MALLOC(len + 1, pCoder); + memcpy(pSAV1->A_c, tstr, len + 1); + + tEndDecode(pCoder); + return 0; +} + +typedef struct { + int32_t A_a; + int64_t A_b; + char * A_c; + // -------------------BELOW FEILDS ARE ADDED IN A NEW VERSION-------------- + int16_t A_d; + int16_t A_e; +} SStructA_v2; + +static int tSStructA_v2_encode(SCoder *pCoder, const SStructA_v2 *pSAV2) { + if (tStartEncode(pCoder) < 0) return -1; + + if (tEncodeI32(pCoder, pSAV2->A_a) < 0) return -1; + if (tEncodeI64(pCoder, pSAV2->A_b) < 0) return -1; + if (tEncodeCStr(pCoder, pSAV2->A_c) < 0) return -1; + + // ------------------------NEW FIELDS ENCODE------------------------------- + if (tEncodeI16(pCoder, pSAV2->A_d) < 0) return -1; + if (tEncodeI16(pCoder, pSAV2->A_e) < 0) return -1; + + tEndEncode(pCoder); + return 0; +} + +static int tSStructA_v2_decode(SCoder *pCoder, SStructA_v2 *pSAV2) { + if (tStartDecode(pCoder) < 0) return -1; + + if (tDecodeI32(pCoder, &pSAV2->A_a) < 0) return -1; + if (tDecodeI64(pCoder, &pSAV2->A_b) < 0) return -1; + const char *tstr; + uint64_t len; + if (tDecodeCStrAndLen(pCoder, &tstr, &len) < 0) return -1; + pSAV2->A_c = (char *)TCODER_MALLOC(len + 1, pCoder); + memcpy(pSAV2->A_c, tstr, len + 1); + + // ------------------------NEW FIELDS DECODE------------------------------- + if (!tDecodeIsEnd(pCoder)) { + if (tDecodeI16(pCoder, &pSAV2->A_d) < 0) return -1; + if (tDecodeI16(pCoder, &pSAV2->A_e) < 0) return -1; + } else { + pSAV2->A_d = 0; + pSAV2->A_e = 0; + } + + tEndDecode(pCoder); + return 0; +} + +typedef struct { + SStructA_v1 *pA; + int32_t v_a; + int8_t v_b; +} SFinalReq_v1; + +static int tSFinalReq_v1_encode(SCoder *pCoder, const SFinalReq_v1 *ps1) { + if (tStartEncode(pCoder) < 0) return -1; + + if (tSStructA_v1_encode(pCoder, ps1->pA) < 0) return -1; + if (tEncodeI32(pCoder, ps1->v_a) < 0) return -1; + if (tEncodeI8(pCoder, ps1->v_b) < 0) return -1; + + tEndEncode(pCoder); + return 0; +} + +static int tSFinalReq_v1_decode(SCoder *pCoder, SFinalReq_v1 *ps1) { + if (tStartDecode(pCoder) < 0) return -1; + + ps1->pA = (SStructA_v1 *)TCODER_MALLOC(sizeof(*(ps1->pA)), pCoder); + if (tSStructA_v1_decode(pCoder, ps1->pA) < 0) return -1; + if (tDecodeI32(pCoder, &ps1->v_a) < 0) return -1; + if (tDecodeI8(pCoder, &ps1->v_b) < 0) return -1; + + tEndEncode(pCoder); + return 0; +} + +typedef struct { + SStructA_v2 *pA; + int32_t v_a; + int8_t v_b; + // ----------------------- Feilds added ----------------------- + int16_t v_c; +} SFinalReq_v2; + +static int tSFinalReq_v2_encode(SCoder *pCoder, const SFinalReq_v2 *ps2) { + if (tStartEncode(pCoder) < 0) return -1; + + if (tSStructA_v2_encode(pCoder, ps2->pA) < 0) return -1; + if (tEncodeI32(pCoder, ps2->v_a) < 0) return -1; + if (tEncodeI8(pCoder, ps2->v_b) < 0) return -1; + + // ----------------------- Feilds added encode ----------------------- + if (tEncodeI16(pCoder, ps2->v_c) < 0) return -1; + + tEndEncode(pCoder); + return 0; +} + +static int tSFinalReq_v2_decode(SCoder *pCoder, SFinalReq_v2 *ps2) { + if (tStartDecode(pCoder) < 0) return -1; + + ps2->pA = (SStructA_v2 *)TCODER_MALLOC(sizeof(*(ps2->pA)), pCoder); + if (tSStructA_v2_decode(pCoder, ps2->pA) < 0) return -1; + if (tDecodeI32(pCoder, &ps2->v_a) < 0) return -1; + if (tDecodeI8(pCoder, &ps2->v_b) < 0) return -1; + + // ----------------------- Feilds added decode ----------------------- + if (tDecodeIsEnd(pCoder)) { + ps2->v_c = 0; + } else { + if (tDecodeI16(pCoder, &ps2->v_c) < 0) return -1; + } + + tEndEncode(pCoder); + return 0; +} + +TEST(td_encode_test, compound_struct_encode_test) { + SCoder encoder, decoder; + uint8_t * buf1; + int32_t buf1size; + uint8_t * buf2; + int32_t buf2size; + SStructA_v1 sa1 = {.A_a = 10, .A_b = 65478, .A_c = "Hello"}; + SStructA_v2 sa2 = {.A_a = 10, .A_b = 65478, .A_c = "Hello", .A_d = 67, .A_e = 13}; + SFinalReq_v1 req1 = {.pA = &sa1, .v_a = 15, .v_b = 35}; + SFinalReq_v2 req2 = {.pA = &sa2, .v_a = 15, .v_b = 32, .v_c = 37}; + SFinalReq_v1 dreq1; + SFinalReq_v2 dreq21, dreq22; + + // Get size + tCoderInit(&encoder, TD_LITTLE_ENDIAN, nullptr, 0, TD_ENCODER); + GTEST_ASSERT_EQ(tSFinalReq_v1_encode(&encoder, &req1), 0); + buf1size = encoder.pos; + buf1 = new uint8_t[encoder.pos]; + tCoderClear(&encoder); + + tCoderInit(&encoder, TD_LITTLE_ENDIAN, nullptr, 0, TD_ENCODER); + GTEST_ASSERT_EQ(tSFinalReq_v2_encode(&encoder, &req2), 0); + buf2size = encoder.pos; + buf2 = new uint8_t[encoder.pos]; + tCoderClear(&encoder); + + // Encode + tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf1, buf1size, TD_ENCODER); + GTEST_ASSERT_EQ(tSFinalReq_v1_encode(&encoder, &req1), 0); + tCoderClear(&encoder); + + tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf2, buf2size, TD_ENCODER); + GTEST_ASSERT_EQ(tSFinalReq_v2_encode(&encoder, &req2), 0); + tCoderClear(&encoder); + + // Decode + tCoderInit(&decoder, TD_LITTLE_ENDIAN, buf1, buf1size, TD_DECODER); + GTEST_ASSERT_EQ(tSFinalReq_v1_decode(&decoder, &dreq1), 0); + tCoderClear(&decoder); + + tCoderInit(&decoder, TD_LITTLE_ENDIAN, buf1, buf1size, TD_DECODER); + GTEST_ASSERT_EQ(tSFinalReq_v2_decode(&decoder, &dreq21), 0); + tCoderClear(&decoder); + + tCoderInit(&decoder, TD_LITTLE_ENDIAN, buf2, buf2size, TD_DECODER); + GTEST_ASSERT_EQ(tSFinalReq_v2_decode(&decoder, &dreq22), 0); + tCoderClear(&decoder); } \ No newline at end of file