diff --git a/include/os/osString.h b/include/os/osString.h index a4100652c340e5a48446c9d97fb5d9bd44acb83e..026cb33ad9ddf2e8f18ac84bd8f2779c81701c57 100644 --- a/include/os/osString.h +++ b/include/os/osString.h @@ -59,6 +59,8 @@ bool taosMbsToUcs4(const char *mbs, size_t mbs_len, TdUcs4 *ucs4, int32_t ucs int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes); TdUcs4* tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4); bool taosValidateEncodec(const char *encodec); +int32_t taosHexEncode(const char *src, char *dst, int32_t len); +int32_t taosHexDecode(const char *src, char *dst, int32_t len); int32_t taosWcharWidth(TdWchar wchar); int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size); diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 0e6ec4f945af8ba7a920e25e3a0a1ffeb6cf387e..8320aa5a1bec5c0cc5bb9cb41d90ecfb651b2dd3 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -1699,7 +1699,18 @@ static int32_t datumToJson(const void* pObj, SJson* pJson) { case TSDB_DATA_TYPE_DOUBLE: code = tjsonAddDoubleToObject(pJson, jkValueDatum, pNode->datum.d); break; - case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_NCHAR: { + //cJSON only support utf-8 encoding. Convert memory content to hex string. + char *buf = taosMemoryCalloc(varDataLen(pNode->datum.p) * 2 + 1, sizeof(char)); + code = taosHexEncode(varDataVal(pNode->datum.p), buf, varDataLen(pNode->datum.p)); + if(code != TSDB_CODE_SUCCESS) { + taosMemoryFree(buf); + return TSDB_CODE_TSC_INVALID_VALUE; + } + code = tjsonAddStringToObject(pJson, jkValueDatum, buf); + taosMemoryFree(buf); + break; + } case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARBINARY: code = tjsonAddStringToObject(pJson, jkValueDatum, varDataVal(pNode->datum.p)); @@ -1773,8 +1784,27 @@ static int32_t jsonToDatum(const SJson* pJson, void* pObj) { code = TSDB_CODE_OUT_OF_MEMORY; break; } - varDataSetLen(pNode->datum.p, pNode->node.resType.bytes); - code = tjsonGetStringValue(pJson, jkValueDatum, varDataVal(pNode->datum.p)); + varDataSetLen(pNode->datum.p, pNode->node.resType.bytes - VARSTR_HEADER_SIZE); + if (TSDB_DATA_TYPE_NCHAR == pNode->node.resType.type) { + char *buf = taosMemoryCalloc(1, pNode->node.resType.bytes * 2 + VARSTR_HEADER_SIZE + 1); + if (NULL == buf) { + code = TSDB_CODE_OUT_OF_MEMORY; + break; + } + code = tjsonGetStringValue(pJson, jkValueDatum, buf); + if (code != TSDB_CODE_SUCCESS) { + taosMemoryFree(buf); + break; + } + code = taosHexDecode(buf, varDataVal(pNode->datum.p), pNode->node.resType.bytes - VARSTR_HEADER_SIZE); + if (code != TSDB_CODE_SUCCESS) { + taosMemoryFree(buf); + break; + } + taosMemoryFree(buf); + } else { + code = tjsonGetStringValue(pJson, jkValueDatum, varDataVal(pNode->datum.p)); + } break; } case TSDB_DATA_TYPE_JSON: diff --git a/source/os/src/osString.c b/source/os/src/osString.c index ed596a051d34b003a016211a48356f2da2b431de..375c5001f4a1025cdaa44e317e57548170022fd5 100644 --- a/source/os/src/osString.c +++ b/source/os/src/osString.c @@ -195,6 +195,36 @@ int32_t taosUcs4len(TdUcs4 *ucs4) { return n; } +//dst buffer size should be at least 2*len + 1 +int32_t taosHexEncode(const char *src, char *dst, int32_t len) { + if (!dst) { + return -1; + } + + for (int32_t i = 0; i < len; ++i) { + sprintf(dst + i * 2, "%02x", src[i] & 0xff); + } + + return 0; +} + +int32_t taosHexDecode(const char *src, char *dst, int32_t len) { + if (!dst) { + return -1; + } + + uint16_t hn, ln, out; + for (int i = 0, j = 0; i < len * 2; i += 2, ++j ) { + hn = src[i] > '9' ? src[i] - 'A' + 10 : src[i] - '0'; + ln = src[i + 1] > '9' ? src[i + 1] - 'A' + 10 : src[i + 1] - '0'; + + out = (hn << 4) | ln; + memcpy(dst + j, &out, 1); + } + + return 0; +} + int32_t taosWcharWidth(TdWchar wchar) { return wcwidth(wchar); } int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size) { return wcswidth(pWchar, size); }