mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
add ubjson parser
This commit is contained in:
parent
90301d46bf
commit
85c308c7aa
@ -1,5 +1,12 @@
|
||||
# 最新动态
|
||||
|
||||
* 2019/09/15
|
||||
* ubjson reader
|
||||
* ubjson parser
|
||||
|
||||
* 2019/09/14
|
||||
* ubjson writer
|
||||
|
||||
* 2019/09/13
|
||||
* 窗口切换到后台时自动失去焦点。
|
||||
|
||||
|
160
src/ubjson/ubjson_parser.c
Normal file
160
src/ubjson/ubjson_parser.c
Normal file
@ -0,0 +1,160 @@
|
||||
/**
|
||||
* File: ubjson_parser.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: ubjson parser
|
||||
*
|
||||
* Copyright (c) 2019 - 2019 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* 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. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-09-15 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/buffer.h"
|
||||
#include "ubjson/ubjson_parser.h"
|
||||
|
||||
typedef enum _parse_state_t {
|
||||
STATE_NONE,
|
||||
STATE_KEY,
|
||||
STATE_VALUE,
|
||||
STATE_ARRAY,
|
||||
} parse_state_t;
|
||||
|
||||
typedef struct _ubjson_parser_t {
|
||||
void* ctx;
|
||||
str_t temp;
|
||||
rbuffer_t rb;
|
||||
object_t* obj;
|
||||
object_t* root;
|
||||
parse_state_t state;
|
||||
ubjson_reader_t reader;
|
||||
} ubjson_parser_t;
|
||||
|
||||
#define PROP_PARENT "__parent__"
|
||||
|
||||
static ubjson_parser_t* ubjson_parser_init(ubjson_parser_t* parser, void* data, uint32_t size) {
|
||||
str_t* temp = &(parser->temp);
|
||||
rbuffer_t* rb = &(parser->rb);
|
||||
ubjson_reader_t* reader = &(parser->reader);
|
||||
|
||||
str_init(temp, 64);
|
||||
rbuffer_init(rb, data, size);
|
||||
parser->state = STATE_NONE;
|
||||
ubjson_reader_init(reader, (ubjson_read_callback_t)rbuffer_read_binary, rb);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
static ret_t ubjson_parser_deinit(ubjson_parser_t* parser) {
|
||||
str_t* temp = &(parser->temp);
|
||||
ubjson_reader_t* reader = &(parser->reader);
|
||||
|
||||
str_reset(temp);
|
||||
ubjson_reader_reset(reader);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t ubjson_parser_read(ubjson_parser_t* parser, value_t* v) {
|
||||
ubjson_reader_t* reader = &(parser->reader);
|
||||
|
||||
return ubjson_reader_read(reader, v);
|
||||
}
|
||||
|
||||
static ret_t ubjson_parser_on_value(ubjson_parser_t* parser, value_t* v) {
|
||||
str_t* str = &(parser->temp);
|
||||
|
||||
switch (parser->state) {
|
||||
case STATE_NONE: {
|
||||
if (v->type == VALUE_TYPE_TOKEN && value_token(v) == UBJSON_MARKER_OBJECT_BEGIN) {
|
||||
parser->obj = object_default_create();
|
||||
return_value_if_fail(parser->obj != NULL, RET_OOM);
|
||||
|
||||
parser->state = STATE_KEY;
|
||||
parser->root = parser->obj;
|
||||
} else {
|
||||
assert(!"invalid format");
|
||||
return RET_BAD_PARAMS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_KEY: {
|
||||
if (v->type == VALUE_TYPE_TOKEN) {
|
||||
if (value_token(v) == UBJSON_MARKER_OBJECT_END) {
|
||||
object_t* parent = (object_t*)object_get_prop_pointer(parser->obj, PROP_PARENT);
|
||||
parser->obj = parent;
|
||||
} else {
|
||||
assert(!"invalid format");
|
||||
return RET_BAD_PARAMS;
|
||||
}
|
||||
} else if (v->type == VALUE_TYPE_STRING) {
|
||||
return_value_if_fail(str_set(str, value_str(v)) == RET_OK, RET_OOM);
|
||||
parser->state = STATE_VALUE;
|
||||
} else {
|
||||
assert(!"invalid format");
|
||||
return RET_BAD_PARAMS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_VALUE: {
|
||||
if (v->type == VALUE_TYPE_TOKEN) {
|
||||
if (value_token(v) == UBJSON_MARKER_OBJECT_BEGIN) {
|
||||
object_t* obj = object_default_create();
|
||||
return_value_if_fail(obj != NULL, RET_OOM);
|
||||
|
||||
parser->state = STATE_KEY;
|
||||
object_set_prop_object(parser->obj, str->str, obj);
|
||||
object_set_prop_pointer(obj, PROP_PARENT, parser->obj);
|
||||
parser->obj = obj;
|
||||
|
||||
object_unref(obj);
|
||||
} else {
|
||||
assert(!"invalid format");
|
||||
return RET_BAD_PARAMS;
|
||||
}
|
||||
} else {
|
||||
parser->state = STATE_KEY;
|
||||
object_set_prop(parser->obj, str->str, v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t ubjson_do_parse(ubjson_parser_t* parser) {
|
||||
value_t v;
|
||||
|
||||
while (TRUE) {
|
||||
if (ubjson_parser_read(parser, &v) != RET_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
ubjson_parser_on_value(parser, &v);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
object_t* ubjson_parse(void* data, uint32_t size) {
|
||||
ubjson_parser_t parser;
|
||||
return_value_if_fail(data != NULL && size > 0, NULL);
|
||||
|
||||
ubjson_parser_init(&parser, data, size);
|
||||
ubjson_do_parse(&parser);
|
||||
ubjson_parser_deinit(&parser);
|
||||
|
||||
return parser.root;
|
||||
}
|
34
src/ubjson/ubjson_parser.h
Normal file
34
src/ubjson/ubjson_parser.h
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* File: ubjson_parser.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: ubjson parser
|
||||
*
|
||||
* Copyright (c) 2019 - 2019 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* 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. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-09-15 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_UBJSON_PARSER_H
|
||||
#define TK_UBJSON_PARSER_H
|
||||
|
||||
#include "tkc/object_default.h"
|
||||
#include "ubjson/ubjson_reader.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
object_t* ubjson_parse(void* data, uint32_t size);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_UBJSON_PARSER_H*/
|
@ -137,6 +137,7 @@ ret_t ubjson_reader_read(ubjson_reader_t* reader, value_t* v) {
|
||||
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->str[len] = '\0';
|
||||
value_set_str(v, str->str);
|
||||
break;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ ret_t ubjson_writer_write_char(ubjson_writer_t* writer, char value) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t ubjson_writer_write_string(ubjson_writer_t* writer, const char* value) {
|
||||
ret_t ubjson_writer_write_str(ubjson_writer_t* writer, const char* value) {
|
||||
uint32_t len = 0;
|
||||
return_value_if_fail(writer != NULL && value != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(ubjson_writer_write_marker(writer, UBJSON_MARKER_STRING) == RET_OK, RET_OOM);
|
||||
|
@ -52,7 +52,7 @@ ret_t ubjson_writer_write_int64(ubjson_writer_t* writer, int64_t value);
|
||||
ret_t ubjson_writer_write_float32(ubjson_writer_t* writer, float value);
|
||||
ret_t ubjson_writer_write_float64(ubjson_writer_t* writer, double value);
|
||||
ret_t ubjson_writer_write_char(ubjson_writer_t* writer, char value);
|
||||
ret_t ubjson_writer_write_string(ubjson_writer_t* writer, const char* value);
|
||||
ret_t ubjson_writer_write_str(ubjson_writer_t* writer, const char* value);
|
||||
ret_t ubjson_writer_write_array_begin(ubjson_writer_t* writer);
|
||||
ret_t ubjson_writer_write_array_end(ubjson_writer_t* writer);
|
||||
ret_t ubjson_writer_write_object_begin(ubjson_writer_t* writer);
|
||||
|
63
tests/ubjson_parser_test.cc
Normal file
63
tests/ubjson_parser_test.cc
Normal file
@ -0,0 +1,63 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "tkc/buffer.h"
|
||||
#include "ubjson/ubjson_writer.h"
|
||||
#include "ubjson/ubjson_parser.h"
|
||||
|
||||
TEST(UBJsonWriter, basic) {
|
||||
uint8_t buff[256];
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
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_str(&ub, "name"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "aaa"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "age"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_int32(&ub, 100), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_object_end(&ub), RET_OK);
|
||||
|
||||
obj = ubjson_parse(wb.data, wb.cursor);
|
||||
ASSERT_STREQ(object_get_prop_str(obj, "name"), "aaa");
|
||||
ASSERT_EQ(object_get_prop_int(obj, "age", 0), 100);
|
||||
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(UBJsonWriter, embedded) {
|
||||
uint8_t buff[256];
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t ub;
|
||||
object_t* obj = NULL;
|
||||
object_t* addr = 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_str(&ub, "name"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "aaa"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "age"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_int32(&ub, 100), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "addr"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_object_begin(&ub), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "city"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "shenzhen"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "post"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "518000"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_object_end(&ub), RET_OK);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_object_end(&ub), RET_OK);
|
||||
|
||||
obj = ubjson_parse(wb.data, wb.cursor);
|
||||
ASSERT_STREQ(object_get_prop_str(obj, "name"), "aaa");
|
||||
ASSERT_EQ(object_get_prop_int(obj, "age", 0), 100);
|
||||
addr = object_get_prop_object(obj, "addr");
|
||||
ASSERT_EQ(addr != NULL, true);
|
||||
|
||||
ASSERT_STREQ(object_get_prop_str(addr, "city"), "shenzhen");
|
||||
ASSERT_STREQ(object_get_prop_str(addr, "post"), "518000");
|
||||
|
||||
object_unref(obj);
|
||||
}
|
@ -180,7 +180,7 @@ TEST(UBJsonReader, double) {
|
||||
TEST(UBJsonReader, string) {
|
||||
PREPARE_TEST();
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_string(&ub, "a"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "a"), RET_OK);
|
||||
|
||||
rb.capacity = wb.cursor;
|
||||
ASSERT_EQ(ubjson_reader_read(&ur, &v), RET_OK);
|
||||
|
@ -184,7 +184,7 @@ TEST(UBJsonWriter, string) {
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
ubjson_writer_init(&ub, (ubjson_write_callback_t)wbuffer_write_binary, &wb);
|
||||
|
||||
ASSERT_EQ(ubjson_writer_write_string(&ub, "a"), RET_OK);
|
||||
ASSERT_EQ(ubjson_writer_write_str(&ub, "a"), RET_OK);
|
||||
|
||||
ASSERT_EQ(buff[0], UBJSON_MARKER_STRING);
|
||||
ASSERT_EQ(buff[1], UBJSON_MARKER_INT8);
|
||||
|
Loading…
Reference in New Issue
Block a user