mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-08 19:44:45 +08:00
improve ubjson
This commit is contained in:
parent
ca4a3278c9
commit
f8dfd03f9e
@ -2,6 +2,7 @@
|
||||
|
||||
2025/02/14
|
||||
* endian类增加了小端的支持和修改了注释(增加测试用例)(感谢智明提供补丁)
|
||||
* 实现了 ubjson 规范中的使用类型和计数进行数组优化(感谢林福提供补丁)
|
||||
|
||||
2025/02/13
|
||||
* 更新1m资源(感谢泽武提供补丁)
|
||||
|
@ -48,7 +48,11 @@ typedef enum _ubjson_marker_t {
|
||||
UBJSON_MARKER_ARRAY_BEGIN = '[',
|
||||
UBJSON_MARKER_ARRAY_END = ']',
|
||||
UBJSON_MARKER_OBJECT_BEGIN = '{',
|
||||
UBJSON_MARKER_OBJECT_END = '}'
|
||||
UBJSON_MARKER_OBJECT_END = '}',
|
||||
|
||||
/* container optimized format */
|
||||
UBJSON_MARKER_CONTAINER_TYPE = '&',
|
||||
UBJSON_MARKER_CONTAINER_COUNT = '#',
|
||||
} ubjson_marker_t;
|
||||
|
||||
END_C_DECLS
|
||||
|
@ -39,6 +39,8 @@ typedef struct _ubjson_parser_t {
|
||||
bool_t error;
|
||||
uint32_t level;
|
||||
tk_object_t* stack[MAX_LEVEL + 1];
|
||||
|
||||
uint32_t optimized_type;
|
||||
} ubjson_parser_t;
|
||||
|
||||
static ret_t ubjson_do_parse_object(ubjson_parser_t* parser);
|
||||
@ -123,6 +125,65 @@ static ret_t ubjson_parser_read(ubjson_parser_t* parser, value_t* v) {
|
||||
return ubjson_reader_read(reader, v);
|
||||
}
|
||||
|
||||
static ret_t ubjson_on_optimized_array_object(ubjson_parser_t* parser, const char* key,
|
||||
value_t* v) {
|
||||
ret_t ret = RET_OK;
|
||||
uint32_t type = parser->optimized_type;
|
||||
parser->optimized_type = 0;
|
||||
|
||||
if (type == UBJSON_MARKER_UINT8) {
|
||||
uint8_t* p = v->value.binary_data.data;
|
||||
for (uint32_t i = 0; i < v->value.binary_data.size; i++) {
|
||||
ret = tk_object_set_prop_uint8(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_INT8) {
|
||||
int8_t* p = v->value.binary_data.data;
|
||||
for (uint32_t i = 0; i < v->value.binary_data.size; i++) {
|
||||
ret = tk_object_set_prop_int8(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_INT16) {
|
||||
int16_t* p = v->value.binary_data.data;
|
||||
uint32_t count = v->value.binary_data.size / sizeof(int16_t);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
ret = tk_object_set_prop_int16(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_INT32) {
|
||||
int32_t* p = v->value.binary_data.data;
|
||||
uint32_t count = v->value.binary_data.size / sizeof(int32_t);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
ret = tk_object_set_prop_int32(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_INT64) {
|
||||
int64_t* p = v->value.binary_data.data;
|
||||
uint32_t count = v->value.binary_data.size / sizeof(int64_t);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
ret = tk_object_set_prop_int64(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_FLOAT32) {
|
||||
float* p = v->value.binary_data.data;
|
||||
uint32_t count = v->value.binary_data.size / sizeof(float);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
ret = tk_object_set_prop_float(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_FLOAT64) {
|
||||
double* p = v->value.binary_data.data;
|
||||
uint32_t count = v->value.binary_data.size / sizeof(double);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
ret = tk_object_set_prop_double(parser->obj, key, p[i]);
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
}
|
||||
} else {
|
||||
return_value_if_fail(!"not support!", RET_FAIL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t ubjson_on_key_value_object(void* ctx, const char* key, value_t* v) {
|
||||
ret_t ret = RET_OK;
|
||||
ubjson_parser_t* parser = (ubjson_parser_t*)ctx;
|
||||
@ -134,6 +195,7 @@ static ret_t ubjson_on_key_value_object(void* ctx, const char* key, value_t* v)
|
||||
|
||||
if (v->type == VALUE_TYPE_TOKEN) {
|
||||
uint32_t token = value_token(v);
|
||||
|
||||
if (token == UBJSON_MARKER_OBJECT_BEGIN || token == UBJSON_MARKER_ARRAY_BEGIN) {
|
||||
tk_object_t* obj =
|
||||
token == UBJSON_MARKER_OBJECT_BEGIN ? object_default_create() : object_array_create();
|
||||
@ -152,12 +214,26 @@ static ret_t ubjson_on_key_value_object(void* ctx, const char* key, value_t* v)
|
||||
tk_object_unref(obj);
|
||||
} else if (token == UBJSON_MARKER_OBJECT_END || token == UBJSON_MARKER_ARRAY_END) {
|
||||
ret = ubjson_parser_pop(parser);
|
||||
|
||||
} else if (token == UBJSON_MARKER_UINT8 || token == UBJSON_MARKER_INT8 ||
|
||||
token == UBJSON_MARKER_INT16 || token == UBJSON_MARKER_INT32 ||
|
||||
token == UBJSON_MARKER_INT64 || token == UBJSON_MARKER_FLOAT32 ||
|
||||
token == UBJSON_MARKER_FLOAT64) {
|
||||
parser->optimized_type = token;
|
||||
} else {
|
||||
assert(!"not supported");
|
||||
ret = RET_NOT_IMPL;
|
||||
}
|
||||
} else {
|
||||
ret = tk_object_set_prop(parser->obj, key, v);
|
||||
if (parser->optimized_type != 0) {
|
||||
return_value_if_fail(v->type == VALUE_TYPE_BINARY, RET_FAIL);
|
||||
|
||||
ubjson_on_optimized_array_object(parser, key, v);
|
||||
ret = ubjson_parser_pop(parser);
|
||||
|
||||
} else {
|
||||
ret = tk_object_set_prop(parser->obj, key, v);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -248,8 +324,11 @@ static ret_t ubjson_do_parse_array(ubjson_parser_t* parser) {
|
||||
ubjson_do_parse_array(parser);
|
||||
continue;
|
||||
} else {
|
||||
assert(!"invalid format");
|
||||
return RET_BAD_PARAMS;
|
||||
ubjson_parser_on_key_value(parser, NULL, v); /* 上报优化数组的类型 */
|
||||
|
||||
return_value_if_fail(ubjson_parser_read(parser, &value) == RET_OK, RET_FAIL);
|
||||
ubjson_parser_on_key_value(parser, NULL, v);
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +57,78 @@ static bool_t is_binary(const char* str, uint32_t len) {
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
static ret_t ubjson_reader_read_optimized_array(ubjson_reader_t* reader, uint8_t type, int count,
|
||||
value_t* v) {
|
||||
return_value_if_fail(reader != NULL && reader->read != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
ret_t ret = RET_OK;
|
||||
value_t vlen;
|
||||
int len = 0;
|
||||
str_t* str = &(reader->str);
|
||||
|
||||
if (type == UBJSON_MARKER_UINT8 || type == UBJSON_MARKER_INT8) {
|
||||
len = count;
|
||||
} else if (type == UBJSON_MARKER_INT16) {
|
||||
len = count * sizeof(int16_t);
|
||||
} else if (type == UBJSON_MARKER_INT32) {
|
||||
len = count * sizeof(int32_t);
|
||||
} else if (type == UBJSON_MARKER_INT64) {
|
||||
len = count * sizeof(int64_t);
|
||||
} else if (type == UBJSON_MARKER_FLOAT32) {
|
||||
len = count * sizeof(float);
|
||||
} else if (type == UBJSON_MARKER_FLOAT64) {
|
||||
len = count * sizeof(double);
|
||||
}
|
||||
|
||||
return_value_if_fail(str_extend(str, len + 1) == RET_OK, RET_OOM);
|
||||
return_value_if_fail(ubjson_reader_read_data(reader, str->str, len) == RET_OK, RET_FAIL);
|
||||
|
||||
str->size = len;
|
||||
str->str[len] = '\0';
|
||||
|
||||
if (type == UBJSON_MARKER_INT16) {
|
||||
int16_t* p = (int16_t*)str->str;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int16_t vp = uint16_from_big_endian(p[i]);
|
||||
p[i] = vp;
|
||||
}
|
||||
|
||||
} else if (type == UBJSON_MARKER_INT32) {
|
||||
int32_t* p = (int32_t*)str->str;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int32_t vp = int32_from_big_endian(p[i]);
|
||||
p[i] = vp;
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_INT64) {
|
||||
int64_t* p = (int64_t*)str->str;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int64_t vp = int64_from_big_endian(p[i]);
|
||||
p[i] = vp;
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_FLOAT32) {
|
||||
float* p = (float*)str->str;
|
||||
for (int i = 0; i < count; i++) {
|
||||
float vp = float_from_big_endian(p[i]);
|
||||
p[i] = vp;
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_FLOAT64) {
|
||||
double* p = (double*)str->str;
|
||||
for (int i = 0; i < count; i++) {
|
||||
double vp = double_from_big_endian(p[i]);
|
||||
p[i] = vp;
|
||||
}
|
||||
}
|
||||
|
||||
value_set_binary_data(v, str->str, len);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t ubjson_reader_read(ubjson_reader_t* reader, value_t* v) {
|
||||
ret_t ret = RET_OK;
|
||||
uint8_t marker = 0;
|
||||
return_value_if_fail(reader != NULL && reader->read != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
ret = ubjson_reader_read_data(reader, &marker, 1);
|
||||
|
||||
if (ret != RET_OK) {
|
||||
@ -219,6 +286,24 @@ ret_t ubjson_reader_read(ubjson_reader_t* reader, value_t* v) {
|
||||
value_set_token(v, UBJSON_MARKER_OBJECT_END);
|
||||
break;
|
||||
}
|
||||
case UBJSON_MARKER_CONTAINER_TYPE: {
|
||||
ret = ubjson_reader_read_data(reader, &marker, 1);
|
||||
return_value_if_fail(ret == RET_OK, RET_FAIL);
|
||||
value_set_token(v, marker);
|
||||
|
||||
reader->optimized_type = marker;
|
||||
break;
|
||||
}
|
||||
case UBJSON_MARKER_CONTAINER_COUNT: {
|
||||
value_t vlen;
|
||||
ret = ubjson_reader_read(reader, &vlen);
|
||||
return_value_if_fail(ret == RET_OK, RET_FAIL);
|
||||
|
||||
ret = ubjson_reader_read_optimized_array(reader, reader->optimized_type, value_int(&vlen), v);
|
||||
reader->optimized_type = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = RET_FAIL;
|
||||
break;
|
||||
|
@ -38,6 +38,7 @@ struct _ubjson_reader_t {
|
||||
str_t str;
|
||||
wstr_t wstr;
|
||||
ubjson_read_callback_t read;
|
||||
uint8_t optimized_type;
|
||||
};
|
||||
|
||||
ubjson_reader_t* ubjson_reader_init(ubjson_reader_t* reader, ubjson_read_callback_t read,
|
||||
|
@ -45,18 +45,23 @@ static ret_t ubjson_writer_write_marker(ubjson_writer_t* writer, uint8_t marker)
|
||||
return ubjson_writer_write_data(writer, &marker, 1);
|
||||
}
|
||||
|
||||
static ret_t ubjson_writer_write_length(ubjson_writer_t* writer, uint32_t len) {
|
||||
ret_t ret = RET_BAD_PARAMS;
|
||||
if (len <= INT8_MAX) {
|
||||
ret = ubjson_writer_write_int8(writer, (int8_t)len);
|
||||
} else if (len <= INT16_MAX) {
|
||||
ret = ubjson_writer_write_int16(writer, (int16_t)len);
|
||||
} else if (len <= INT_MAX) {
|
||||
ret = ubjson_writer_write_int32(writer, (int32_t)len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t ubjson_writer_write_key_len(ubjson_writer_t* writer, const char* value, uint32_t len) {
|
||||
return_value_if_fail(writer != NULL && value != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (len <= INT8_MAX) {
|
||||
ubjson_writer_write_int8(writer, (int8_t)len);
|
||||
} else if (len <= INT16_MAX) {
|
||||
ubjson_writer_write_int16(writer, (int16_t)len);
|
||||
} else if (len <= INT_MAX) {
|
||||
ubjson_writer_write_int32(writer, (int32_t)len);
|
||||
} else {
|
||||
return RET_BAD_PARAMS;
|
||||
}
|
||||
return_value_if_fail(ubjson_writer_write_length(writer, len) == RET_OK, RET_OOM);
|
||||
|
||||
return_value_if_fail(ubjson_writer_write_data(writer, value, len) == RET_OK, RET_OOM);
|
||||
|
||||
@ -496,3 +501,104 @@ ret_t ubjson_writer_write_object_end(ubjson_writer_t* writer) {
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t ubjson_writer_write_optimized_array(ubjson_writer_t* writer, char type, uint32_t count,
|
||||
void* array) {
|
||||
ret_t ret;
|
||||
return_value_if_fail(writer != NULL && array != NULL && count > 0, RET_BAD_PARAMS);
|
||||
|
||||
return_value_if_fail(ubjson_writer_write_marker(writer, UBJSON_MARKER_ARRAY_BEGIN) == RET_OK,
|
||||
RET_OOM);
|
||||
return_value_if_fail(ubjson_writer_write_marker(writer, UBJSON_MARKER_CONTAINER_TYPE) == RET_OK,
|
||||
RET_OOM);
|
||||
return_value_if_fail(ubjson_writer_write_marker(writer, type) == RET_OK, RET_OOM);
|
||||
return_value_if_fail(ubjson_writer_write_marker(writer, UBJSON_MARKER_CONTAINER_COUNT) == RET_OK,
|
||||
RET_OOM);
|
||||
|
||||
return_value_if_fail(ubjson_writer_write_length(writer, count) == RET_OK, RET_OOM);
|
||||
|
||||
if (type == UBJSON_MARKER_INT8 || type == UBJSON_MARKER_UINT8) {
|
||||
ret = ubjson_writer_write_data(writer, array, count);
|
||||
return_value_if_fail(ret == RET_OK, RET_OOM);
|
||||
|
||||
} else if (type == UBJSON_MARKER_INT16) {
|
||||
int16_t* p = (int16_t*)array;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
int16_t val = p[i];
|
||||
val = int16_to_big_endian(val);
|
||||
ret = ubjson_writer_write_data(writer, &val, sizeof(val));
|
||||
return_value_if_fail(ret == RET_OK, RET_OOM);
|
||||
}
|
||||
|
||||
} else if (type == UBJSON_MARKER_INT32) {
|
||||
int32_t* p = (int32_t*)array;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
int32_t val = p[i];
|
||||
val = int32_to_big_endian(val);
|
||||
ret = ubjson_writer_write_data(writer, &val, sizeof(val));
|
||||
return_value_if_fail(ret == RET_OK, RET_OOM);
|
||||
}
|
||||
|
||||
} else if (type == UBJSON_MARKER_INT64) {
|
||||
int64_t* p = (int64_t*)array;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
int64_t val = p[i];
|
||||
val = int64_to_big_endian(val);
|
||||
ret = ubjson_writer_write_data(writer, &val, sizeof(val));
|
||||
return_value_if_fail(ret == RET_OK, RET_OOM);
|
||||
}
|
||||
|
||||
} else if (type == UBJSON_MARKER_FLOAT32) {
|
||||
float* p = (float*)array;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
float val = p[i];
|
||||
val = float_to_big_endian(val);
|
||||
ret = ubjson_writer_write_data(writer, &val, sizeof(val));
|
||||
return_value_if_fail(ret == RET_OK, RET_OOM);
|
||||
}
|
||||
} else if (type == UBJSON_MARKER_FLOAT64) {
|
||||
double* p = (double*)array;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
double val = p[i];
|
||||
val = double_to_big_endian(val);
|
||||
ret = ubjson_writer_write_data(writer, &val, sizeof(val));
|
||||
return_value_if_fail(ret == RET_OK, RET_OOM);
|
||||
}
|
||||
}
|
||||
|
||||
/* 优化数组,没有结束标记 */
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_array_uint8(ubjson_writer_t* writer, uint8_t* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_UINT8, count, data);
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_array_int8(ubjson_writer_t* writer, int8_t* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_INT8, count, data);
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_array_int16(ubjson_writer_t* writer, int16_t* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_INT16, count, data);
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_array_int32(ubjson_writer_t* writer, int32_t* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_INT32, count, data);
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_array_int64(ubjson_writer_t* writer, int64_t* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_INT64, count, data);
|
||||
}
|
||||
ret_t ubjson_writer_write_array_float32(ubjson_writer_t* writer, float* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_FLOAT32, count, data);
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_array_float64(ubjson_writer_t* writer, double* data, uint32_t count) {
|
||||
return ubjson_writer_write_optimized_array(writer, UBJSON_MARKER_FLOAT64, count, data);
|
||||
}
|
@ -705,6 +705,91 @@ ret_t ubjson_writer_write_kv_wstr_len(ubjson_writer_t* writer, const char* key,
|
||||
*/
|
||||
ret_t ubjson_writer_write_kv_value(ubjson_writer_t* writer, const char* key, const value_t* value);
|
||||
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_uint8
|
||||
* 写入 uint8 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {uint8_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_uint8(ubjson_writer_t* writer, uint8_t* data, uint32_t count);
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_int8
|
||||
* 写入 int8 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {int8_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_int8(ubjson_writer_t* writer, int8_t* data, uint32_t count);
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_int16
|
||||
* 写入 int16 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {int16_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_int16(ubjson_writer_t* writer, int16_t* data, uint32_t count);
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_int32
|
||||
* 写入 int32 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {int32_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_int32(ubjson_writer_t* writer, int32_t* data, uint32_t count);
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_int64
|
||||
* 写入 int64 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {int32_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_int64(ubjson_writer_t* writer, int64_t* data, uint32_t count);
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_float32
|
||||
* 写入 float32 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {int32_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_float32(ubjson_writer_t* writer, float* data, uint32_t count);
|
||||
|
||||
/**
|
||||
* @method ubjson_writer_write_array_float64
|
||||
* 写入 float64 数组。
|
||||
*
|
||||
* @param {ubjson_writer_t*} writer writer对象。
|
||||
* @param {int32_t*} data 数组。
|
||||
* @param {uint32_t} count 数组元素计数。
|
||||
*
|
||||
* @return {ret_t} 返回 ret_t 值
|
||||
*/
|
||||
ret_t ubjson_writer_write_array_float64(ubjson_writer_t* writer, double* data, uint32_t count);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_UBJSON_WRITER_H*/
|
||||
|
@ -271,3 +271,99 @@ TEST(UBJsonParser, ubjson_writer_write_kv_value) {
|
||||
|
||||
tk_object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(UBJsonParser, optimized_array_uint8) {
|
||||
uint8_t buff[256];
|
||||
uint8_t data[] = {100, 200, 255};
|
||||
value_t v;
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
tk_object_t* obj = NULL;
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_begin(&ub), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_key(&ub, "values"), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_uint8(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_end(&ub), RET_OK);
|
||||
|
||||
obj = object_from_ubjson(wb.data, wb.cursor);
|
||||
ASSERT_EQ(tk_object_get_prop_by_path(obj, "values.0", &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_UINT8, true);
|
||||
ASSERT_EQ(value_int(&v), 100);
|
||||
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.1", 0), 200);
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.2", 0), 255);
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.size", 0), 3);
|
||||
|
||||
tk_object_unref(obj);
|
||||
}
|
||||
TEST(UBJsonParser, optimized_array_int32) {
|
||||
uint8_t buff[256];
|
||||
int32_t data[] = {100, 200, 300};
|
||||
value_t v;
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
tk_object_t* obj = NULL;
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_begin(&ub), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_key(&ub, "values"), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_int32(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_end(&ub), RET_OK);
|
||||
|
||||
obj = object_from_ubjson(wb.data, wb.cursor);
|
||||
ASSERT_EQ(tk_object_get_prop_by_path(obj, "values.0", &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_INT32, true);
|
||||
ASSERT_EQ(value_int(&v), 100);
|
||||
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.1", 0), 200);
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.2", 0), 300);
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.size", 0), 3);
|
||||
|
||||
tk_object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(UBJsonParser, optimized_array_float64) {
|
||||
uint8_t buff[256];
|
||||
double data[] = {100.11, 200.11, 300.11};
|
||||
value_t v;
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
tk_object_t* obj = NULL;
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_begin(&ub), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_key(&ub, "values"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_array_float64(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_kv_str(&ub, "name", "optimized_array"), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_end(&ub), RET_OK);
|
||||
|
||||
obj = object_from_ubjson(wb.data, wb.cursor);
|
||||
ASSERT_EQ(tk_object_get_prop_by_path(obj, "values.0", &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_DOUBLE, true);
|
||||
ASSERT_EQ(value_double(&v), 100.11);
|
||||
|
||||
ASSERT_EQ(tk_object_get_prop_by_path(obj, "values.1", &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_DOUBLE, true);
|
||||
ASSERT_EQ(value_double(&v), 200.11);
|
||||
|
||||
ASSERT_EQ(tk_object_get_prop_by_path(obj, "values.2", &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_DOUBLE, true);
|
||||
ASSERT_EQ(value_double(&v), 300.11);
|
||||
|
||||
ASSERT_EQ(tk_object_get_prop_int_by_path(obj, "values.size", 0), 3);
|
||||
|
||||
ASSERT_STREQ(tk_object_get_prop_str_by_path(obj, "name"), "optimized_array");
|
||||
|
||||
tk_object_unref(obj);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "ubjson/ubjson_reader.h"
|
||||
|
||||
#define PREPARE_TEST() \
|
||||
uint8_t buff[256]; \
|
||||
uint8_t buff[4096]; \
|
||||
value_t v; \
|
||||
wbuffer_t wb; \
|
||||
rbuffer_t rb; \
|
||||
@ -267,3 +267,90 @@ TEST(UBJsonReader, wstring) {
|
||||
|
||||
ubjson_reader_reset(&ur);
|
||||
}
|
||||
|
||||
TEST(UBJsonReader, optimized_array_uint8) {
|
||||
PREPARE_TEST();
|
||||
|
||||
uint8_t data[120];
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_uint8(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
rb.capacity = wb.cursor;
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_TOKEN, true);
|
||||
ASSERT_EQ(value_token(&v), UBJSON_MARKER_ARRAY_BEGIN);
|
||||
|
||||
// 优化数组的类型
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_TOKEN, true);
|
||||
ASSERT_EQ(value_token(&v), UBJSON_MARKER_UINT8);
|
||||
|
||||
// 数据
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type, VALUE_TYPE_BINARY);
|
||||
ASSERT_TRUE(memcmp(v.value.binary_data.data, data, ARRAY_SIZE(data)) == 0);
|
||||
ASSERT_EQ(v.value.binary_data.size, ARRAY_SIZE(data));
|
||||
|
||||
ubjson_reader_reset(&ur);
|
||||
}
|
||||
|
||||
TEST(UBJsonReader, optimized_array_int32) {
|
||||
PREPARE_TEST();
|
||||
|
||||
int32_t data[120];
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_int32(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
rb.capacity = wb.cursor;
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_TOKEN, true);
|
||||
ASSERT_EQ(value_token(&v), UBJSON_MARKER_ARRAY_BEGIN);
|
||||
|
||||
// 优化数组的类型
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_TOKEN, true);
|
||||
ASSERT_EQ(value_token(&v), UBJSON_MARKER_INT32);
|
||||
|
||||
// 数据
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type, VALUE_TYPE_BINARY);
|
||||
ASSERT_TRUE(memcmp(v.value.binary_data.data, data, sizeof(data)) == 0);
|
||||
ASSERT_EQ(v.value.binary_data.size, sizeof(data));
|
||||
|
||||
ubjson_reader_reset(&ur);
|
||||
}
|
||||
|
||||
TEST(UBJsonReader, optimized_array_double) {
|
||||
PREPARE_TEST();
|
||||
|
||||
double data[120];
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
data[i] = i * 1.11;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_float64(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
rb.capacity = wb.cursor;
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_TOKEN, true);
|
||||
ASSERT_EQ(value_token(&v), UBJSON_MARKER_ARRAY_BEGIN);
|
||||
|
||||
// 优化数组的类型
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type == VALUE_TYPE_TOKEN, true);
|
||||
ASSERT_EQ(value_token(&v), UBJSON_MARKER_FLOAT64);
|
||||
|
||||
// 数据
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
ASSERT_EQ(v.type, VALUE_TYPE_BINARY);
|
||||
ASSERT_TRUE(memcmp(v.value.binary_data.data, data, sizeof(data)) == 0);
|
||||
ASSERT_EQ(v.value.binary_data.size, sizeof(data));
|
||||
|
||||
ubjson_reader_reset(&ur);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "tkc/buffer.h"
|
||||
#include "tkc/endian.h"
|
||||
#include "ubjson/ubjson_writer.h"
|
||||
|
||||
TEST(UBJsonWriter, null) {
|
||||
@ -355,3 +356,85 @@ TEST(UBJsonWriter, kv_wstring_len) {
|
||||
ASSERT_EQ(buff[6], 'b');
|
||||
ASSERT_EQ(wb.cursor, 7u);
|
||||
}
|
||||
|
||||
TEST(UBJsonWriter, optimized_array_uint8) {
|
||||
uint8_t buff[256];
|
||||
uint8_t data[120];
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_uint8(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
ASSERT_EQ(wb.cursor, 6 + sizeof(data));
|
||||
ASSERT_EQ(buff[0], UBJSON_MARKER_ARRAY_BEGIN);
|
||||
ASSERT_EQ(buff[1], UBJSON_MARKER_CONTAINER_TYPE);
|
||||
ASSERT_EQ(buff[2], UBJSON_MARKER_UINT8);
|
||||
ASSERT_EQ(buff[3], UBJSON_MARKER_CONTAINER_COUNT);
|
||||
ASSERT_EQ(buff[4], UBJSON_MARKER_INT8);
|
||||
ASSERT_EQ(buff[5], ARRAY_SIZE(data));
|
||||
ASSERT_EQ(memcmp(buff + 6, data, sizeof(data)), 0);
|
||||
}
|
||||
|
||||
TEST(UBJsonWriter, optimized_array_int32) {
|
||||
uint8_t buff[256 + 120 * sizeof(int32_t)];
|
||||
int32_t data[120];
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_int32(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
ASSERT_EQ(wb.cursor, 6 + sizeof(data));
|
||||
ASSERT_EQ(buff[0], UBJSON_MARKER_ARRAY_BEGIN);
|
||||
ASSERT_EQ(buff[1], UBJSON_MARKER_CONTAINER_TYPE);
|
||||
ASSERT_EQ(buff[2], UBJSON_MARKER_INT32);
|
||||
ASSERT_EQ(buff[3], UBJSON_MARKER_CONTAINER_COUNT);
|
||||
ASSERT_EQ(buff[4], UBJSON_MARKER_INT8);
|
||||
ASSERT_EQ(buff[5], ARRAY_SIZE(data));
|
||||
|
||||
int32_t* p = (int32_t*)(buff + 6);
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
int32_t v = int32_from_big_endian(p[i]);
|
||||
ASSERT_EQ(v, data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(UBJsonWriter, optimized_array_float64) {
|
||||
uint8_t buff[256 + 120 * sizeof(double)];
|
||||
double data[120];
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
data[i] = i * 1.11;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_array_float64(&ub, data, ARRAY_SIZE(data)), RET_OK);
|
||||
|
||||
ASSERT_EQ(wb.cursor, 6 + sizeof(data));
|
||||
ASSERT_EQ(buff[0], UBJSON_MARKER_ARRAY_BEGIN);
|
||||
ASSERT_EQ(buff[1], UBJSON_MARKER_CONTAINER_TYPE);
|
||||
ASSERT_EQ(buff[2], UBJSON_MARKER_FLOAT64);
|
||||
ASSERT_EQ(buff[3], UBJSON_MARKER_CONTAINER_COUNT);
|
||||
ASSERT_EQ(buff[4], UBJSON_MARKER_INT8);
|
||||
ASSERT_EQ(buff[5], ARRAY_SIZE(data));
|
||||
|
||||
double* p = (double*)(buff + 6);
|
||||
for (int i = 0; i < ARRAY_SIZE(data); i++) {
|
||||
double v = double_from_big_endian(p[i]);
|
||||
ASSERT_EQ(v, data[i]);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user