Merge pull request #9561 from taosdata/feature/vnode

Feature/vnode
This commit is contained in:
Shengliang Guan 2022-01-04 10:07:49 +08:00 committed by GitHub
commit b30a26fc89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 847 additions and 506 deletions

View File

@ -57,46 +57,6 @@ extern int tMsgDict[];
typedef uint16_t tmsg_t;
/* ------------------------ ENCODE/DECODE FUNCTIONS AND MACROS ------------------------ */
struct SMEListNode {
TD_SLIST_NODE(SMEListNode);
SEncoder coder;
};
typedef struct SMsgEncoder {
SEncoder coder;
TD_SLIST(SMEListNode) eStack; // encode stack
} SMsgEncoder;
struct SMDFreeListNode {
TD_SLIST_NODE(SMDFreeListNode);
char payload[];
};
struct SMDListNode {
TD_SLIST_NODE(SMDListNode);
SDecoder coder;
};
typedef struct SMsgDecoder {
SDecoder coder;
TD_SLIST(SMDListNode) dStack;
TD_SLIST(SMDFreeListNode) freeList;
} SMsgDecoder;
#define TMSG_MALLOC(SIZE, DECODER) \
({ \
void* ptr = malloc((SIZE) + sizeof(struct SMDFreeListNode)); \
if (ptr) { \
TD_SLIST_PUSH(&((DECODER)->freeList), (struct SMDFreeListNode*)ptr); \
ptr = POINTER_SHIFT(ptr, sizeof(struct SMDFreeListNode*)); \
} \
ptr; \
})
void tmsgInitMsgDecoder(SMsgDecoder* pMD, td_endian_t endian, uint8_t* data, int64_t size);
void tmsgClearMsgDecoder(SMsgDecoder* pMD);
/* ------------------------ OTHER DEFINITIONS ------------------------ */
// IE type
#define TSDB_IE_TYPE_SEC 1
@ -1283,8 +1243,6 @@ typedef struct {
SArray* pArray;
} SVCreateTbBatchReq;
int tmsgSVCreateTbReqEncode(SMsgEncoder* pCoder, SVCreateTbReq* pReq);
int tmsgSVCreateTbReqDecode(SMsgDecoder* pCoder, SVCreateTbReq* pReq);
int tSerializeSVCreateTbReq(void** buf, SVCreateTbReq* pReq);
void* tDeserializeSVCreateTbReq(void* buf, SVCreateTbReq* pReq);
int tSVCreateTbBatchReqSerialize(void** buf, SVCreateTbBatchReq* pReq);

View File

@ -16,6 +16,7 @@
#ifndef _TD_UTIL_ENCODE_H_
#define _TD_UTIL_ENCODE_H_
#include "freelist.h"
#include "tcoding.h"
#include "tmacro.h"
@ -23,13 +24,6 @@
extern "C" {
#endif
typedef struct {
td_endian_t endian;
uint8_t* data;
int32_t size;
int32_t pos;
} SEncoder, SDecoder;
#define tPut(TYPE, BUF, VAL) ((TYPE*)(BUF))[0] = (VAL)
#define tGet(TYPE, BUF, VAL) (VAL) = ((TYPE*)(BUF))[0]
@ -57,31 +51,157 @@ typedef struct {
#define tRGet32 tRPut32
#define tRGet64 tRPut64
typedef enum { TD_ENCODER, TD_DECODER } td_coder_t;
#define CODER_NODE_FIELDS \
uint8_t* data; \
int32_t size; \
int32_t pos;
struct SCoderNode {
TD_SLIST_NODE(SCoderNode);
CODER_NODE_FIELDS
};
typedef struct {
td_coder_t type;
td_endian_t endian;
SFreeList fl;
CODER_NODE_FIELDS
TD_SLIST(SCoderNode) stack;
} SCoder;
#define TD_CODER_POS(CODER) ((CODER)->pos)
#define TD_CODER_CURRENT(CODER) ((CODER)->data + (CODER)->pos)
#define TD_CODER_MOVE_POS(CODER, MOVE) ((CODER)->pos += (MOVE))
#define TD_CHECK_CODER_CAPACITY_FAILED(CODER, EXPSIZE) (((CODER)->size - (CODER)->pos) < (EXPSIZE))
#define TD_CODER_CHECK_CAPACITY_FAILED(CODER, EXPSIZE) (((CODER)->size - (CODER)->pos) < (EXPSIZE))
#define TCODER_MALLOC(SIZE, CODER) TFL_MALLOC(SIZE, &((CODER)->fl))
/* ------------------------ FOR ENCODER ------------------------ */
static FORCE_INLINE void tInitEncoder(SEncoder* pEncoder, td_endian_t endian, uint8_t* data, int32_t size) {
pEncoder->endian = endian;
pEncoder->data = data;
pEncoder->size = (data) ? size : 0;
pEncoder->pos = 0;
}
void tCoderInit(SCoder* pCoder, td_endian_t endian, uint8_t* data, int32_t size, td_coder_t type);
void tCoderClear(SCoder* pCoder);
/* ------------------------ ENCODE ------------------------ */
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 ------------------------ */
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);
static int tDecodeI16(SCoder* pDecoder, int16_t* val);
static int tDecodeU32(SCoder* pDecoder, uint32_t* val);
static int tDecodeI32(SCoder* pDecoder, int32_t* val);
static int tDecodeU64(SCoder* pDecoder, uint64_t* val);
static int tDecodeI64(SCoder* pDecoder, int64_t* val);
static int tDecodeU16v(SCoder* pDecoder, uint16_t* val);
static int tDecodeI16v(SCoder* pDecoder, int16_t* val);
static int tDecodeU32v(SCoder* pDecoder, uint32_t* val);
static int tDecodeI32v(SCoder* pDecoder, int32_t* val);
static int tDecodeU64v(SCoder* pDecoder, uint64_t* val);
static int tDecodeI64v(SCoder* pDecoder, int64_t* val);
static int tDecodeFloat(SCoder* pDecoder, float* val);
static int tDecodeDouble(SCoder* pDecoder, double* val);
static int tDecodeBinary(SCoder* pDecoder, const void** val, uint64_t* len);
static int tDecodeCStrAndLen(SCoder* pDecoder, const char** val, uint64_t* len);
static int tDecodeCStr(SCoder* pDecoder, const char** val);
static int tDecodeCStrTo(SCoder* pDecoder, char* val);
/* ------------------------ IMPL ------------------------ */
#define TD_ENCODE_MACRO(CODER, VAL, TYPE, BITS) \
if ((CODER)->data) { \
if (TD_CODER_CHECK_CAPACITY_FAILED(CODER, sizeof(VAL))) return -1; \
if (TD_RT_ENDIAN() == (CODER)->endian) { \
tPut(TYPE, TD_CODER_CURRENT(CODER), (VAL)); \
} else { \
tRPut##BITS(TD_CODER_CURRENT(CODER), &(VAL)); \
} \
} \
TD_CODER_MOVE_POS(CODER, sizeof(VAL)); \
return 0;
#define TD_ENCODE_VARIANT_MACRO(CODER, VAL) \
while ((VAL) >= ENCODE_LIMIT) { \
if ((CODER)->data) { \
if (TD_CODER_CHECK_CAPACITY_FAILED(CODER, 1)) return -1; \
TD_CODER_CURRENT(CODER)[0] = ((VAL) | ENCODE_LIMIT) & 0xff; \
} \
\
(VAL) >>= 7; \
TD_CODER_MOVE_POS(CODER, 1); \
} \
\
if ((CODER)->data) { \
if (TD_CODER_CHECK_CAPACITY_FAILED(CODER, 1)) return -1; \
TD_CODER_CURRENT(CODER)[0] = (uint8_t)(VAL); \
} \
TD_CODER_MOVE_POS(CODER, 1); \
return 0;
#define TD_DECODE_MACRO(CODER, PVAL, TYPE, BITS) \
if (TD_CODER_CHECK_CAPACITY_FAILED(CODER, sizeof(*(PVAL)))) return -1; \
if (TD_RT_ENDIAN() == (CODER)->endian) { \
tGet(TYPE, TD_CODER_CURRENT(CODER), *(PVAL)); \
} else { \
tRGet##BITS(PVAL, TD_CODER_CURRENT(CODER)); \
} \
\
TD_CODER_MOVE_POS(CODER, sizeof(*(PVAL))); \
return 0;
#define TD_DECODE_VARIANT_MACRO(CODER, PVAL, TYPE) \
int32_t i = 0; \
*(PVAL) = 0; \
for (;;) { \
if (TD_CODER_CHECK_CAPACITY_FAILED(CODER, 1)) return -1; \
TYPE tval = TD_CODER_CURRENT(CODER)[0]; \
if (tval < ENCODE_LIMIT) { \
*(PVAL) |= (tval << (7 * i)); \
TD_CODER_MOVE_POS(pDecoder, 1); \
break; \
} else { \
*(PVAL) |= (((tval) & (ENCODE_LIMIT - 1)) << (7 * i)); \
i++; \
TD_CODER_MOVE_POS(pDecoder, 1); \
} \
} \
\
return 0;
// 8
static FORCE_INLINE int tEncodeU8(SEncoder* pEncoder, uint8_t val) {
static FORCE_INLINE int tEncodeU8(SCoder* pEncoder, uint8_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_CODER_CHECK_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
tPut(uint8_t, TD_CODER_CURRENT(pEncoder), val);
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeI8(SEncoder* pEncoder, int8_t val) {
static FORCE_INLINE int tEncodeI8(SCoder* pEncoder, int8_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_CODER_CHECK_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
tPut(int8_t, TD_CODER_CURRENT(pEncoder), val);
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
@ -89,303 +209,99 @@ static FORCE_INLINE int tEncodeI8(SEncoder* pEncoder, int8_t val) {
}
// 16
static FORCE_INLINE int tEncodeU16(SEncoder* pEncoder, uint16_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_RT_ENDIAN() == pEncoder->endian) {
tPut(uint16_t, TD_CODER_CURRENT(pEncoder), val);
} else {
tRPut16(TD_CODER_CURRENT(pEncoder), &val);
}
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeI16(SEncoder* pEncoder, int16_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_RT_ENDIAN() == pEncoder->endian) {
tPut(int16_t, TD_CODER_CURRENT(pEncoder), val);
} else {
tRPut16(TD_CODER_CURRENT(pEncoder), &val);
}
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeU16(SCoder* pEncoder, uint16_t val) { TD_ENCODE_MACRO(pEncoder, val, uint16_t, 16); }
static FORCE_INLINE int tEncodeI16(SCoder* pEncoder, int16_t val) { TD_ENCODE_MACRO(pEncoder, val, int16_t, 16); }
// 32
static FORCE_INLINE int tEncodeU32(SEncoder* pEncoder, uint32_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_RT_ENDIAN() == pEncoder->endian) {
tPut(uint32_t, TD_CODER_CURRENT(pEncoder), val);
} else {
tRPut32(TD_CODER_CURRENT(pEncoder), &val);
}
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeI32(SEncoder* pEncoder, int32_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_RT_ENDIAN() == pEncoder->endian) {
tPut(int32_t, TD_CODER_CURRENT(pEncoder), val);
} else {
tRPut32(TD_CODER_CURRENT(pEncoder), &val);
}
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeU32(SCoder* pEncoder, uint32_t val) { TD_ENCODE_MACRO(pEncoder, val, uint32_t, 32); }
static FORCE_INLINE int tEncodeI32(SCoder* pEncoder, int32_t val) { TD_ENCODE_MACRO(pEncoder, val, int32_t, 32); }
// 64
static FORCE_INLINE int tEncodeU64(SEncoder* pEncoder, uint64_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_RT_ENDIAN() == pEncoder->endian) {
tPut(uint64_t, TD_CODER_CURRENT(pEncoder), val);
} else {
tRPut64(TD_CODER_CURRENT(pEncoder), &val);
}
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeI64(SEncoder* pEncoder, int64_t val) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, sizeof(val))) return -1;
if (TD_RT_ENDIAN() == pEncoder->endian) {
tPut(int64_t, TD_CODER_CURRENT(pEncoder), val);
} else {
tRPut64(TD_CODER_CURRENT(pEncoder), &val);
}
}
TD_CODER_MOVE_POS(pEncoder, sizeof(val));
return 0;
}
static FORCE_INLINE int tEncodeU64(SCoder* pEncoder, uint64_t val) { TD_ENCODE_MACRO(pEncoder, val, uint64_t, 64); }
static FORCE_INLINE int tEncodeI64(SCoder* pEncoder, int64_t val) { TD_ENCODE_MACRO(pEncoder, val, int64_t, 64); }
// 16v
static FORCE_INLINE int tEncodeU16v(SEncoder* pEncoder, uint16_t val) {
int64_t i = 0;
while (val >= ENCODE_LIMIT) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, 1)) return -1;
TD_CODER_CURRENT(pEncoder)[i] = (val | ENCODE_LIMIT) & 0xff;
}
val >>= 7;
i++;
}
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, 1)) return -1;
TD_CODER_CURRENT(pEncoder)[i] = (uint8_t)val;
}
TD_CODER_MOVE_POS(pEncoder, i + 1);
return 0;
}
static FORCE_INLINE int tEncodeI16v(SEncoder* pEncoder, int16_t val) {
static FORCE_INLINE int tEncodeU16v(SCoder* pEncoder, uint16_t val) { TD_ENCODE_VARIANT_MACRO(pEncoder, val); }
static FORCE_INLINE int tEncodeI16v(SCoder* pEncoder, int16_t val) {
return tEncodeU16v(pEncoder, ZIGZAGE(int16_t, val));
}
// 32v
static FORCE_INLINE int tEncodeU32v(SEncoder* pEncoder, uint32_t val) {
int64_t i = 0;
while (val >= ENCODE_LIMIT) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, 1)) return -1;
TD_CODER_CURRENT(pEncoder)[i] = (val | ENCODE_LIMIT) & 0xff;
}
val >>= 7;
i++;
}
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, 1)) return -1;
TD_CODER_CURRENT(pEncoder)[i] = (uint8_t)val;
}
TD_CODER_MOVE_POS(pEncoder, i + 1);
return 0;
}
static FORCE_INLINE int tEncodeI32v(SEncoder* pEncoder, int32_t val) {
static FORCE_INLINE int tEncodeU32v(SCoder* pEncoder, uint32_t val) { TD_ENCODE_VARIANT_MACRO(pEncoder, val); }
static FORCE_INLINE int tEncodeI32v(SCoder* pEncoder, int32_t val) {
return tEncodeU32v(pEncoder, ZIGZAGE(int32_t, val));
}
// 64v
static FORCE_INLINE int tEncodeU64v(SEncoder* pEncoder, uint64_t val) {
int64_t i = 0;
while (val >= ENCODE_LIMIT) {
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, 1)) return -1;
TD_CODER_CURRENT(pEncoder)[i] = (val | ENCODE_LIMIT) & 0xff;
}
val >>= 7;
i++;
}
if (pEncoder->data) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pEncoder, 1)) return -1;
TD_CODER_CURRENT(pEncoder)[i] = (uint8_t)val;
}
TD_CODER_MOVE_POS(pEncoder, i + 1);
return 0;
}
static FORCE_INLINE int tEncodeI64v(SEncoder* pEncoder, int64_t val) {
static FORCE_INLINE int tEncodeU64v(SCoder* pEncoder, uint64_t val) { TD_ENCODE_VARIANT_MACRO(pEncoder, val); }
static FORCE_INLINE int tEncodeI64v(SCoder* pEncoder, int64_t val) {
return tEncodeU64v(pEncoder, ZIGZAGE(int64_t, val));
}
static FORCE_INLINE int tEncodeFloat(SEncoder* pEncoder, float val) {
// TODO
static FORCE_INLINE int tEncodeFloat(SCoder* pEncoder, float val) {
union {
uint32_t ui;
float f;
} v = {.f = val};
return tEncodeU32(pEncoder, v.ui);
}
static FORCE_INLINE int tEncodeDouble(SCoder* pEncoder, double val) {
union {
uint64_t ui;
double d;
} v = {.d = val};
return tEncodeU64(pEncoder, v.ui);
}
static FORCE_INLINE int tEncodeBinary(SCoder* pEncoder, const void* val, uint64_t len) {
if (tEncodeU64v(pEncoder, len) < 0) return -1;
if (pEncoder->data) {
if (TD_CODER_CHECK_CAPACITY_FAILED(pEncoder, len)) return -1;
memcpy(TD_CODER_CURRENT(pEncoder), val, len);
}
TD_CODER_MOVE_POS(pEncoder, len);
return 0;
}
static FORCE_INLINE int tEncodeDouble(SEncoder* pEncoder, double val) {
// TODO
return 0;
static FORCE_INLINE int tEncodeCStrWithLen(SCoder* pEncoder, const char* val, uint64_t len) {
return tEncodeBinary(pEncoder, (void*)val, len + 1);
}
static FORCE_INLINE int tEncodeCStr(SEncoder* pEncoder, const char* val) {
// TODO
return 0;
static FORCE_INLINE int tEncodeCStr(SCoder* pEncoder, const char* val) {
return tEncodeCStrWithLen(pEncoder, val, (uint64_t)strlen(val));
}
/* ------------------------ FOR DECODER ------------------------ */
static FORCE_INLINE void tInitDecoder(SDecoder* pDecoder, td_endian_t endian, uint8_t* data, int32_t size) {
ASSERT(!TD_IS_NULL(data));
pDecoder->endian = endian;
pDecoder->data = data;
pDecoder->size = size;
pDecoder->pos = 0;
}
// 8
static FORCE_INLINE int tDecodeU8(SDecoder* pDecoder, uint8_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
static FORCE_INLINE int tDecodeU8(SCoder* pDecoder, uint8_t* val) {
if (TD_CODER_CHECK_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
tGet(uint8_t, TD_CODER_CURRENT(pDecoder), *val);
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeI8(SDecoder* pDecoder, int8_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
static FORCE_INLINE int tDecodeI8(SCoder* pDecoder, int8_t* val) {
if (TD_CODER_CHECK_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
tGet(int8_t, TD_CODER_CURRENT(pDecoder), *val);
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
// 16
static FORCE_INLINE int tDecodeU16(SDecoder* pDecoder, uint16_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
if (TD_RT_ENDIAN() == pDecoder->endian) {
tGet(uint16_t, TD_CODER_CURRENT(pDecoder), *val);
} else {
tRGet16(val, TD_CODER_CURRENT(pDecoder));
}
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeI16(SDecoder* pDecoder, int16_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
if (TD_RT_ENDIAN() == pDecoder->endian) {
tGet(int16_t, TD_CODER_CURRENT(pDecoder), *val);
} else {
tRGet16(val, TD_CODER_CURRENT(pDecoder));
}
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeU16(SCoder* pDecoder, uint16_t* val) { TD_DECODE_MACRO(pDecoder, val, uint16_t, 16); }
static FORCE_INLINE int tDecodeI16(SCoder* pDecoder, int16_t* val) { TD_DECODE_MACRO(pDecoder, val, int16_t, 16); }
// 32
static FORCE_INLINE int tDecodeU32(SDecoder* pDecoder, uint32_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
if (TD_RT_ENDIAN() == pDecoder->endian) {
tGet(uint32_t, TD_CODER_CURRENT(pDecoder), *val);
} else {
tRGet32(val, TD_CODER_CURRENT(pDecoder));
}
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeI32(SDecoder* pDecoder, int32_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
if (TD_RT_ENDIAN() == pDecoder->endian) {
tGet(int32_t, TD_CODER_CURRENT(pDecoder), *val);
} else {
tRGet32(val, TD_CODER_CURRENT(pDecoder));
}
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeU32(SCoder* pDecoder, uint32_t* val) { TD_DECODE_MACRO(pDecoder, val, uint32_t, 32); }
static FORCE_INLINE int tDecodeI32(SCoder* pDecoder, int32_t* val) { TD_DECODE_MACRO(pDecoder, val, int32_t, 32); }
// 64
static FORCE_INLINE int tDecodeU64(SDecoder* pDecoder, uint64_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
if (TD_RT_ENDIAN() == pDecoder->endian) {
tGet(uint64_t, TD_CODER_CURRENT(pDecoder), *val);
} else {
tRGet64(val, TD_CODER_CURRENT(pDecoder));
}
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeI64(SDecoder* pDecoder, int64_t* val) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, sizeof(*val))) return -1;
if (TD_RT_ENDIAN() == pDecoder->endian) {
tGet(int64_t, TD_CODER_CURRENT(pDecoder), *val);
} else {
tRGet64(val, TD_CODER_CURRENT(pDecoder));
}
TD_CODER_MOVE_POS(pDecoder, sizeof(*val));
return 0;
}
static FORCE_INLINE int tDecodeU64(SCoder* pDecoder, uint64_t* val) { TD_DECODE_MACRO(pDecoder, val, uint64_t, 64); }
static FORCE_INLINE int tDecodeI64(SCoder* pDecoder, int64_t* val) { TD_DECODE_MACRO(pDecoder, val, int64_t, 64); }
// 16v
static FORCE_INLINE int tDecodeU16v(SDecoder* pDecoder, uint16_t* val) {
int64_t i = 0;
*val = 0;
for (;;) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, 1)) return -1;
uint16_t tval = TD_CODER_CURRENT(pDecoder)[i];
if (tval < ENCODE_LIMIT) {
(*val) |= (tval << (7 * i));
break;
} else {
(*val) |= (((tval) & (ENCODE_LIMIT - 1)) << (7 * i));
i++;
}
}
TD_CODER_MOVE_POS(pDecoder, i);
return 0;
static FORCE_INLINE int tDecodeU16v(SCoder* pDecoder, uint16_t* val) {
TD_DECODE_VARIANT_MACRO(pDecoder, val, uint16_t);
}
static FORCE_INLINE int tDecodeI16v(SDecoder* pDecoder, int16_t* val) {
static FORCE_INLINE int tDecodeI16v(SCoder* pDecoder, int16_t* val) {
uint16_t tval;
if (tDecodeU16v(pDecoder, &tval) < 0) {
return -1;
@ -395,27 +311,11 @@ static FORCE_INLINE int tDecodeI16v(SDecoder* pDecoder, int16_t* val) {
}
// 32v
static FORCE_INLINE int tDecodeU32v(SDecoder* pDecoder, uint32_t* val) {
int64_t i = 0;
*val = 0;
for (;;) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, 1)) return -1;
uint32_t tval = TD_CODER_CURRENT(pDecoder)[i];
if (tval < ENCODE_LIMIT) {
(*val) |= (tval << (7 * i));
break;
} else {
(*val) |= (((tval) & (ENCODE_LIMIT - 1)) << (7 * i));
i++;
}
}
TD_CODER_MOVE_POS(pDecoder, i);
return 0;
static FORCE_INLINE int tDecodeU32v(SCoder* pDecoder, uint32_t* val) {
TD_DECODE_VARIANT_MACRO(pDecoder, val, uint32_t);
}
static FORCE_INLINE int tDecodeI32v(SDecoder* pDecoder, int32_t* val) {
static FORCE_INLINE int tDecodeI32v(SCoder* pDecoder, int32_t* val) {
uint32_t tval;
if (tDecodeU32v(pDecoder, &tval) < 0) {
return -1;
@ -425,27 +325,11 @@ static FORCE_INLINE int tDecodeI32v(SDecoder* pDecoder, int32_t* val) {
}
// 64v
static FORCE_INLINE int tDecodeU64v(SDecoder* pDecoder, uint64_t* val) {
int64_t i = 0;
*val = 0;
for (;;) {
if (TD_CHECK_CODER_CAPACITY_FAILED(pDecoder, 1)) return -1;
uint64_t tval = TD_CODER_CURRENT(pDecoder)[i];
if (tval < ENCODE_LIMIT) {
(*val) |= (tval << (7 * i));
break;
} else {
(*val) |= (((tval) & (ENCODE_LIMIT - 1)) << (7 * i));
i++;
}
}
TD_CODER_MOVE_POS(pDecoder, i);
return 0;
static FORCE_INLINE int tDecodeU64v(SCoder* pDecoder, uint64_t* val) {
TD_DECODE_VARIANT_MACRO(pDecoder, val, uint64_t);
}
static FORCE_INLINE int tDecodeI64v(SDecoder* pDecoder, int64_t* val) {
static FORCE_INLINE int tDecodeI64v(SCoder* pDecoder, int64_t* val) {
uint64_t tval;
if (tDecodeU64v(pDecoder, &tval) < 0) {
return -1;
@ -454,21 +338,66 @@ static FORCE_INLINE int tDecodeI64v(SDecoder* pDecoder, int64_t* val) {
return 0;
}
static FORCE_INLINE int tDecodeFloat(SDecoder* pDecoder, float* val) {
// TODO
static FORCE_INLINE int tDecodeFloat(SCoder* pDecoder, float* val) {
union {
uint32_t ui;
float f;
} v;
if (tDecodeU32(pDecoder, &(v.ui)) < 0) {
return -1;
}
*val = v.f;
return 0;
}
static FORCE_INLINE int tDecodeDouble(SDecoder* pDecoder, double* val) {
// TODO
static FORCE_INLINE int tDecodeDouble(SCoder* pDecoder, double* val) {
union {
uint64_t ui;
double d;
} v;
if (tDecodeU64(pDecoder, &(v.ui)) < 0) {
return -1;
}
*val = v.d;
return 0;
}
static FORCE_INLINE int tDecodeCStr(SDecoder* pEncoder, const char** val) {
// TODO
static FORCE_INLINE int tDecodeBinary(SCoder* pDecoder, const void** val, uint64_t* len) {
if (tDecodeU64v(pDecoder, len) < 0) return -1;
if (TD_CODER_CHECK_CAPACITY_FAILED(pDecoder, *len)) return -1;
*val = (void*)TD_CODER_CURRENT(pDecoder);
TD_CODER_MOVE_POS(pDecoder, *len);
return 0;
}
static FORCE_INLINE int tDecodeCStrAndLen(SCoder* pDecoder, const char** val, uint64_t* len) {
if (tDecodeBinary(pDecoder, (const void**)val, len) < 0) return -1;
(*len) -= 1;
return 0;
}
static FORCE_INLINE int tDecodeCStr(SCoder* pDecoder, const char** val) {
uint64_t len;
return tDecodeCStrAndLen(pDecoder, val, &len);
}
static int tDecodeCStrTo(SCoder* pDecoder, char* val) {
const char* pStr;
uint64_t len;
if (tDecodeCStrAndLen(pDecoder, &pStr, &len) < 0) return -1;
memcpy(val, pStr, len + 1);
return 0;
}
static FORCE_INLINE bool tDecodeIsEnd(SCoder* pCoder) { return (pCoder->size == pCoder->pos); }
#ifdef __cplusplus
}
#endif

View File

@ -11,4 +11,6 @@ target_link_libraries(
PRIVATE os util common transport parser planner catalog scheduler function qcom
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -12,4 +12,6 @@ target_link_libraries(
INTERFACE api
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -27,77 +27,6 @@
#undef TD_MSG_SEG_CODE_
#include "tmsgdef.h"
static int tmsgStartEncode(SMsgEncoder *pME);
static void tmsgEndEncode(SMsgEncoder *pME);
static int tmsgStartDecode(SMsgDecoder *pMD);
static void tmsgEndDecode(SMsgDecoder *pMD);
/* ------------------------ ENCODE/DECODE FUNCTIONS ------------------------ */
void tmsgInitMsgEncoder(SMsgEncoder *pME, td_endian_t endian, uint8_t *data, int64_t size) {
tInitEncoder(&(pME->coder), endian, data, size);
TD_SLIST_INIT(&(pME->eStack));
}
void tmsgClearMsgEncoder(SMsgEncoder *pME) {
struct SMEListNode *pNode;
for (;;) {
pNode = TD_SLIST_HEAD(&(pME->eStack));
if (TD_IS_NULL(pNode)) break;
TD_SLIST_POP(&(pME->eStack));
free(pNode);
}
}
void tmsgInitMsgDecoder(SMsgDecoder *pMD, td_endian_t endian, uint8_t *data, int64_t size) {
tInitDecoder(&pMD->coder, endian, data, size);
TD_SLIST_INIT(&(pMD->dStack));
TD_SLIST_INIT(&(pMD->freeList));
}
void tmsgClearMsgDecoder(SMsgDecoder *pMD) {
{
struct SMDFreeListNode *pNode;
for (;;) {
pNode = TD_SLIST_HEAD(&(pMD->freeList));
if (TD_IS_NULL(pNode)) break;
TD_SLIST_POP(&(pMD->freeList));
free(pNode);
}
}
{
struct SMDListNode *pNode;
for (;;) {
pNode = TD_SLIST_HEAD(&(pMD->dStack));
if (TD_IS_NULL(pNode)) break;
TD_SLIST_POP(&(pMD->dStack));
free(pNode);
}
}
}
/* ------------------------ MESSAGE ENCODE/DECODE ------------------------ */
int tmsgSVCreateTbReqEncode(SMsgEncoder *pCoder, SVCreateTbReq *pReq) {
tmsgStartEncode(pCoder);
// TODO
tmsgEndEncode(pCoder);
return 0;
}
int tmsgSVCreateTbReqDecode(SMsgDecoder *pCoder, SVCreateTbReq *pReq) {
tmsgStartDecode(pCoder);
// TODO: decode
// Decode is not end
if (pCoder->coder.pos != pCoder->coder.size) {
// Continue decode
}
tmsgEndDecode(pCoder);
return 0;
}
int tSerializeSVCreateTbReq(void **buf, SVCreateTbReq *pReq) {
int tlen = 0;
@ -218,64 +147,4 @@ void *tSVCreateTbBatchReqDeserialize(void *buf, SVCreateTbBatchReq *pReq) {
}
return buf;
}
/* ------------------------ STATIC METHODS ------------------------ */
static int tmsgStartEncode(SMsgEncoder *pME) {
struct SMEListNode *pNode = (struct SMEListNode *)malloc(sizeof(*pNode));
if (TD_IS_NULL(pNode)) return -1;
pNode->coder = pME->coder;
TD_SLIST_PUSH(&(pME->eStack), pNode);
TD_CODER_MOVE_POS(&(pME->coder), sizeof(int32_t));
return 0;
}
static void tmsgEndEncode(SMsgEncoder *pME) {
int32_t size;
struct SMEListNode *pNode;
pNode = TD_SLIST_HEAD(&(pME->eStack));
ASSERT(pNode);
TD_SLIST_POP(&(pME->eStack));
size = pME->coder.pos - pNode->coder.pos;
tEncodeI32(&(pNode->coder), size);
free(pNode);
}
static int tmsgStartDecode(SMsgDecoder *pMD) {
struct SMDListNode *pNode;
int32_t size;
pNode = (struct SMDListNode *)malloc(sizeof(*pNode));
if (pNode == NULL) return -1;
tDecodeI32(&(pMD->coder), &size);
pNode->coder = pMD->coder;
TD_SLIST_PUSH(&(pMD->dStack), pNode);
pMD->coder.pos = 0;
pMD->coder.size = size - sizeof(int32_t);
pMD->coder.data = TD_CODER_CURRENT(&(pNode->coder));
return 0;
}
static void tmsgEndDecode(SMsgDecoder *pMD) {
ASSERT(pMD->coder.pos == pMD->coder.size);
struct SMDListNode *pNode;
pNode = TD_SLIST_HEAD(&(pMD->dStack));
ASSERT(pNode);
TD_SLIST_POP(&(pMD->dStack));
pNode->coder.pos += pMD->coder.size;
pMD->coder = pNode->coder;
free(pNode);
}

View File

@ -11,4 +11,6 @@ target_link_libraries(
PRIVATE os util transport qcom
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -11,4 +11,6 @@ target_link_libraries(
PRIVATE os util catalog function transport qcom
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -11,4 +11,6 @@ target_link_libraries(
PRIVATE os util catalog cjson parser transport function qcom
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -7,8 +7,10 @@ target_include_directories(
)
target_link_libraries(
qcom
PRIVATE os util transport
qcom
PRIVATE os util transport
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -11,4 +11,6 @@ target_link_libraries(
PRIVATE os util transport planner qcom
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -12,4 +12,6 @@ target_link_libraries(
PRIVATE os util planner qcom common catalog transport
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

View File

@ -14,4 +14,7 @@ target_link_libraries(
PUBLIC api
)
ADD_SUBDIRECTORY(test)
if(${BUILD_TEST})
ADD_SUBDIRECTORY(test)
endif(${BUILD_TEST})

141
source/util/src/encode.c Normal file
View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "encode.h"
#if __STDC_VERSION__ >= 201112L
static_assert(sizeof(float) == sizeof(uint32_t), "sizeof(float) must equal to sizeof(uint32_t)");
static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) must equal to sizeof(uint64_t)");
#endif
void tCoderInit(SCoder* pCoder, td_endian_t endian, uint8_t* data, int32_t size, td_coder_t type) {
if (type == TD_ENCODER) {
if (data == NULL) size = 0;
} else {
ASSERT(data && size > 0);
}
pCoder->type = type;
pCoder->endian = endian;
pCoder->data = data;
pCoder->size = size;
pCoder->pos = 0;
tFreeListInit(&(pCoder->fl));
TD_SLIST_INIT(&(pCoder->stack));
}
void tCoderClear(SCoder* pCoder) {
tFreeListClear(&(pCoder->fl));
struct SCoderNode* pNode;
for (;;) {
pNode = TD_SLIST_HEAD(&(pCoder->stack));
if (pNode == NULL) break;
TD_SLIST_POP(&(pCoder->stack));
free(pNode);
}
}
int tStartEncode(SCoder* pCoder) {
struct SCoderNode* pNode;
ASSERT(pCoder->type == TD_ENCODER);
if (pCoder->data) {
if (pCoder->size - pCoder->pos < sizeof(int32_t)) return -1;
pNode = malloc(sizeof(*pNode));
if (pNode == NULL) return -1;
pNode->data = pCoder->data;
pNode->pos = pCoder->pos;
pNode->size = pCoder->size;
pCoder->data = pNode->data + pNode->pos + sizeof(int32_t);
pCoder->pos = 0;
pCoder->size = pNode->size - pNode->pos - sizeof(int32_t);
TD_SLIST_PUSH(&(pCoder->stack), pNode);
} else {
pCoder->pos += sizeof(int32_t);
}
return 0;
}
void tEndEncode(SCoder* pCoder) {
struct SCoderNode* pNode;
int32_t len;
ASSERT(pCoder->type == TD_ENCODER);
if (pCoder->data) {
pNode = TD_SLIST_HEAD(&(pCoder->stack));
ASSERT(pNode);
TD_SLIST_POP(&(pCoder->stack));
len = pCoder->pos;
pCoder->data = pNode->data;
pCoder->size = pNode->size;
pCoder->pos = pNode->pos;
if (TD_RT_ENDIAN() == pCoder->endian) {
tPut(int32_t, pCoder->data + pCoder->pos, len);
} else {
tRPut32(pCoder->data + pCoder->pos, len);
}
TD_CODER_MOVE_POS(pCoder, len + sizeof(int32_t));
free(pNode);
}
}
int tStartDecode(SCoder* pCoder) {
int32_t len;
struct SCoderNode* pNode;
ASSERT(pCoder->type == TD_DECODER);
if (tDecodeI32(pCoder, &len) < 0) return -1;
pNode = malloc(sizeof(*pNode));
if (pNode == NULL) return -1;
pNode->data = pCoder->data;
pNode->pos = pCoder->pos;
pNode->size = pCoder->size;
pCoder->data = pNode->data + pNode->pos;
pCoder->size = len;
pCoder->pos = 0;
TD_SLIST_PUSH(&(pCoder->stack), pNode);
return 0;
}
void tEndDecode(SCoder* pCoder) {
struct SCoderNode* pNode;
ASSERT(pCoder->type == TD_DECODER);
ASSERT(tDecodeIsEnd(pCoder));
pNode = TD_SLIST_HEAD(&(pCoder->stack));
ASSERT(pNode);
TD_SLIST_POP(&(pCoder->stack));
pCoder->data = pNode->data;
pCoder->size = pNode->size;
pCoder->pos = pCoder->pos + pNode->pos;
free(pNode);
}

View File

@ -41,4 +41,8 @@ target_sources(freelistTest
)
target_link_libraries(freelistTest os util gtest gtest_main)
# encodeTest
add_executable(encodeTest "encodeTest.cpp")
target_link_libraries(encodeTest os util gtest gtest_main)

View File

@ -0,0 +1,421 @@
#include <iostream>
#include "gtest/gtest.h"
#include "encode.h"
#define BUF_SIZE 64
td_endian_t endian_arr[2] = {TD_LITTLE_ENDIAN, TD_BIG_ENDIAN};
static int encode(SCoder *pCoder, int8_t val) { return tEncodeI8(pCoder, val); }
static int encode(SCoder *pCoder, uint8_t val) { return tEncodeU8(pCoder, val); }
static int encode(SCoder *pCoder, int16_t val) { return tEncodeI16(pCoder, val); }
static int encode(SCoder *pCoder, uint16_t val) { return tEncodeU16(pCoder, val); }
static int encode(SCoder *pCoder, int32_t val) { return tEncodeI32(pCoder, val); }
static int encode(SCoder *pCoder, uint32_t val) { return tEncodeU32(pCoder, val); }
static int encode(SCoder *pCoder, int64_t val) { return tEncodeI64(pCoder, val); }
static int encode(SCoder *pCoder, uint64_t val) { return tEncodeU64(pCoder, val); }
static int decode(SCoder *pCoder, int8_t *val) { return tDecodeI8(pCoder, val); }
static int decode(SCoder *pCoder, uint8_t *val) { return tDecodeU8(pCoder, val); }
static int decode(SCoder *pCoder, int16_t *val) { return tDecodeI16(pCoder, val); }
static int decode(SCoder *pCoder, uint16_t *val) { return tDecodeU16(pCoder, val); }
static int decode(SCoder *pCoder, int32_t *val) { return tDecodeI32(pCoder, val); }
static int decode(SCoder *pCoder, uint32_t *val) { return tDecodeU32(pCoder, val); }
static int decode(SCoder *pCoder, int64_t *val) { return tDecodeI64(pCoder, val); }
static int decode(SCoder *pCoder, uint64_t *val) { return tDecodeU64(pCoder, val); }
static int encodev(SCoder *pCoder, int8_t val) { return tEncodeI8(pCoder, val); }
static int encodev(SCoder *pCoder, uint8_t val) { return tEncodeU8(pCoder, val); }
static int encodev(SCoder *pCoder, int16_t val) { return tEncodeI16v(pCoder, val); }
static int encodev(SCoder *pCoder, uint16_t val) { return tEncodeU16v(pCoder, val); }
static int encodev(SCoder *pCoder, int32_t val) { return tEncodeI32v(pCoder, val); }
static int encodev(SCoder *pCoder, uint32_t val) { return tEncodeU32v(pCoder, val); }
static int encodev(SCoder *pCoder, int64_t val) { return tEncodeI64v(pCoder, val); }
static int encodev(SCoder *pCoder, uint64_t val) { return tEncodeU64v(pCoder, val); }
static int decodev(SCoder *pCoder, int8_t *val) { return tDecodeI8(pCoder, val); }
static int decodev(SCoder *pCoder, uint8_t *val) { return tDecodeU8(pCoder, val); }
static int decodev(SCoder *pCoder, int16_t *val) { return tDecodeI16v(pCoder, val); }
static int decodev(SCoder *pCoder, uint16_t *val) { return tDecodeU16v(pCoder, val); }
static int decodev(SCoder *pCoder, int32_t *val) { return tDecodeI32v(pCoder, val); }
static int decodev(SCoder *pCoder, uint32_t *val) { return tDecodeU32v(pCoder, val); }
static int decodev(SCoder *pCoder, int64_t *val) { return tDecodeI64v(pCoder, val); }
static int decodev(SCoder *pCoder, uint64_t *val) { return tDecodeU64v(pCoder, val); }
template <typename T>
static void simple_encode_decode_func(bool var_len) {
uint8_t buf[BUF_SIZE];
SCoder coder;
T min_val, max_val;
T step = 1;
if (typeid(T) == typeid(int8_t)) {
min_val = INT8_MIN;
max_val = INT8_MAX;
step = 1;
} else if (typeid(T) == typeid(uint8_t)) {
min_val = 0;
max_val = UINT8_MAX;
step = 1;
} else if (typeid(T) == typeid(int16_t)) {
min_val = INT16_MIN;
max_val = INT16_MAX;
step = 1;
} else if (typeid(T) == typeid(uint16_t)) {
min_val = 0;
max_val = UINT16_MAX;
step = 1;
} else if (typeid(T) == typeid(int32_t)) {
min_val = INT32_MIN;
max_val = INT32_MAX;
step = ((T)1) << 16;
} else if (typeid(T) == typeid(uint32_t)) {
min_val = 0;
max_val = UINT32_MAX;
step = ((T)1) << 16;
} else if (typeid(T) == typeid(int64_t)) {
min_val = INT64_MIN;
max_val = INT64_MAX;
step = ((T)1) << 48;
} else if (typeid(T) == typeid(uint64_t)) {
min_val = 0;
max_val = UINT64_MAX;
step = ((T)1) << 48;
}
T i = min_val;
for (;; /*T i = min_val; i <= max_val; i += step*/) {
T dval;
// Encode NULL
for (td_endian_t endian : endian_arr) {
tCoderInit(&coder, endian, NULL, 0, TD_ENCODER);
if (var_len) {
GTEST_ASSERT_EQ(encodev(&coder, i), 0);
} else {
GTEST_ASSERT_EQ(encode(&coder, i), 0);
GTEST_ASSERT_EQ(coder.pos, sizeof(T));
}
tCoderClear(&coder);
}
// Encode and decode
for (td_endian_t e_endian : endian_arr) {
for (td_endian_t d_endian : endian_arr) {
// Encode
tCoderInit(&coder, e_endian, buf, BUF_SIZE, TD_ENCODER);
if (var_len) {
GTEST_ASSERT_EQ(encodev(&coder, i), 0);
} else {
GTEST_ASSERT_EQ(encode(&coder, i), 0);
GTEST_ASSERT_EQ(coder.pos, sizeof(T));
}
int32_t epos = coder.pos;
tCoderClear(&coder);
// Decode
tCoderInit(&coder, d_endian, buf, BUF_SIZE, TD_DECODER);
if (var_len) {
GTEST_ASSERT_EQ(decodev(&coder, &dval), 0);
} else {
GTEST_ASSERT_EQ(decode(&coder, &dval), 0);
GTEST_ASSERT_EQ(coder.pos, sizeof(T));
}
GTEST_ASSERT_EQ(coder.pos, epos);
if (typeid(T) == typeid(int8_t) || typeid(T) == typeid(uint8_t) || e_endian == d_endian) {
GTEST_ASSERT_EQ(i, dval);
}
tCoderClear(&coder);
}
}
if (i == max_val) break;
if (max_val - i < step) {
i = max_val;
} else {
i = i + step;
}
}
}
TEST(td_encode_test, encode_decode_fixed_len_integer) {
simple_encode_decode_func<int8_t>(false);
simple_encode_decode_func<uint8_t>(false);
simple_encode_decode_func<int16_t>(false);
simple_encode_decode_func<uint16_t>(false);
simple_encode_decode_func<int32_t>(false);
simple_encode_decode_func<uint32_t>(false);
simple_encode_decode_func<int64_t>(false);
simple_encode_decode_func<uint64_t>(false);
}
TEST(td_encode_test, encode_decode_variant_len_integer) {
simple_encode_decode_func<int16_t>(true);
simple_encode_decode_func<uint16_t>(true);
simple_encode_decode_func<int32_t>(true);
simple_encode_decode_func<uint32_t>(true);
simple_encode_decode_func<int64_t>(true);
simple_encode_decode_func<uint64_t>(true);
}
TEST(td_encode_test, encode_decode_cstr) {
uint8_t * buf = new uint8_t[1024 * 1024];
char * cstr = new char[1024 * 1024];
const char *dcstr;
SCoder encoder;
SCoder decoder;
for (size_t i = 0; i < 1024 * 2 - 1; i++) {
memset(cstr, 'a', i);
cstr[i] = '\0';
for (td_endian_t endian : endian_arr) {
// Encode
tCoderInit(&encoder, endian, buf, 1024 * 1024, TD_ENCODER);
GTEST_ASSERT_EQ(tEncodeCStr(&encoder, cstr), 0);
tCoderClear(&encoder);
// Decode
tCoderInit(&decoder, endian, buf, 1024 * 1024, TD_DECODER);
GTEST_ASSERT_EQ(tDecodeCStr(&decoder, &dcstr), 0);
GTEST_ASSERT_EQ(memcmp(dcstr, cstr, i + 1), 0);
tCoderClear(&decoder);
}
}
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;
tEndDecode(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;
}
tEndDecode(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);
GTEST_ASSERT_EQ(dreq1.pA->A_a, req1.pA->A_a);
GTEST_ASSERT_EQ(dreq1.pA->A_b, req1.pA->A_b);
GTEST_ASSERT_EQ(strcmp(dreq1.pA->A_c, req1.pA->A_c), 0);
GTEST_ASSERT_EQ(dreq1.v_a, req1.v_a);
GTEST_ASSERT_EQ(dreq1.v_b, req1.v_b);
tCoderClear(&decoder);
tCoderInit(&decoder, TD_LITTLE_ENDIAN, buf1, buf1size, TD_DECODER);
GTEST_ASSERT_EQ(tSFinalReq_v2_decode(&decoder, &dreq21), 0);
GTEST_ASSERT_EQ(dreq21.pA->A_a, req1.pA->A_a);
GTEST_ASSERT_EQ(dreq21.pA->A_b, req1.pA->A_b);
GTEST_ASSERT_EQ(strcmp(dreq21.pA->A_c, req1.pA->A_c), 0);
GTEST_ASSERT_EQ(dreq21.pA->A_d, 0);
GTEST_ASSERT_EQ(dreq21.pA->A_e, 0);
GTEST_ASSERT_EQ(dreq21.v_a, req1.v_a);
GTEST_ASSERT_EQ(dreq21.v_b, req1.v_b);
GTEST_ASSERT_EQ(dreq21.v_c, 0);
tCoderClear(&decoder);
tCoderInit(&decoder, TD_LITTLE_ENDIAN, buf2, buf2size, TD_DECODER);
GTEST_ASSERT_EQ(tSFinalReq_v2_decode(&decoder, &dreq22), 0);
GTEST_ASSERT_EQ(dreq22.pA->A_a, req2.pA->A_a);
GTEST_ASSERT_EQ(dreq22.pA->A_b, req2.pA->A_b);
GTEST_ASSERT_EQ(strcmp(dreq22.pA->A_c, req2.pA->A_c), 0);
GTEST_ASSERT_EQ(dreq22.pA->A_d, req2.pA->A_d);
GTEST_ASSERT_EQ(dreq22.pA->A_e, req2.pA->A_e);
GTEST_ASSERT_EQ(dreq22.v_a, req2.v_a);
GTEST_ASSERT_EQ(dreq22.v_b, req2.v_b);
GTEST_ASSERT_EQ(dreq22.v_c, req2.v_c);
tCoderClear(&decoder);
}