1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka */
5*437bfbebSnyanmisaka
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_cfg_io"
7*437bfbebSnyanmisaka
8*437bfbebSnyanmisaka #include <errno.h>
9*437bfbebSnyanmisaka #include <float.h>
10*437bfbebSnyanmisaka #include <string.h>
11*437bfbebSnyanmisaka #include <limits.h>
12*437bfbebSnyanmisaka
13*437bfbebSnyanmisaka #include "mpp_env.h"
14*437bfbebSnyanmisaka #include "mpp_mem.h"
15*437bfbebSnyanmisaka #include "mpp_list.h"
16*437bfbebSnyanmisaka #include "mpp_debug.h"
17*437bfbebSnyanmisaka #include "mpp_common.h"
18*437bfbebSnyanmisaka
19*437bfbebSnyanmisaka #include "mpp_trie.h"
20*437bfbebSnyanmisaka #include "mpp_cfg.h"
21*437bfbebSnyanmisaka #include "mpp_cfg_io.h"
22*437bfbebSnyanmisaka #include "rk_venc_cfg.h"
23*437bfbebSnyanmisaka
24*437bfbebSnyanmisaka #define MAX_CFG_DEPTH (64)
25*437bfbebSnyanmisaka
26*437bfbebSnyanmisaka #define CFG_IO_DBG_FLOW (0x00000001)
27*437bfbebSnyanmisaka #define CFG_IO_DBG_BYTE (0x00000002)
28*437bfbebSnyanmisaka #define CFG_IO_DBG_TO (0x00000004)
29*437bfbebSnyanmisaka #define CFG_IO_DBG_FROM (0x00000008)
30*437bfbebSnyanmisaka #define CFG_IO_DBG_FREE (0x00000010)
31*437bfbebSnyanmisaka #define CFG_IO_DBG_NAME (0x00000020)
32*437bfbebSnyanmisaka #define CFG_IO_DBG_SHOW (0x00000040)
33*437bfbebSnyanmisaka #define CFG_IO_DBG_INFO (0x00000080)
34*437bfbebSnyanmisaka
35*437bfbebSnyanmisaka #define cfg_io_dbg(flag, fmt, ...) _mpp_dbg(mpp_cfg_io_debug, flag, fmt, ## __VA_ARGS__)
36*437bfbebSnyanmisaka #define cfg_io_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_cfg_io_debug, flag, fmt, ## __VA_ARGS__)
37*437bfbebSnyanmisaka
38*437bfbebSnyanmisaka #define cfg_io_dbg_flow(fmt, ...) cfg_io_dbg(CFG_IO_DBG_FLOW, fmt, ## __VA_ARGS__)
39*437bfbebSnyanmisaka #define cfg_io_dbg_byte(fmt, ...) cfg_io_dbg(CFG_IO_DBG_BYTE, fmt, ## __VA_ARGS__)
40*437bfbebSnyanmisaka #define cfg_io_dbg_to(fmt, ...) cfg_io_dbg(CFG_IO_DBG_TO, fmt, ## __VA_ARGS__)
41*437bfbebSnyanmisaka #define cfg_io_dbg_from(fmt, ...) cfg_io_dbg(CFG_IO_DBG_FROM, fmt, ## __VA_ARGS__)
42*437bfbebSnyanmisaka #define cfg_io_dbg_free(fmt, ...) cfg_io_dbg(CFG_IO_DBG_FREE, fmt, ## __VA_ARGS__)
43*437bfbebSnyanmisaka #define cfg_io_dbg_name(fmt, ...) cfg_io_dbg(CFG_IO_DBG_NAME, fmt, ## __VA_ARGS__)
44*437bfbebSnyanmisaka #define cfg_io_dbg_show(fmt, ...) cfg_io_dbg_f(CFG_IO_DBG_SHOW, fmt, ## __VA_ARGS__)
45*437bfbebSnyanmisaka #define cfg_io_dbg_info(fmt, ...) cfg_io_dbg(CFG_IO_DBG_INFO, fmt, ## __VA_ARGS__)
46*437bfbebSnyanmisaka
47*437bfbebSnyanmisaka typedef enum MppCfgParserType_e {
48*437bfbebSnyanmisaka MPP_CFG_PARSER_TYPE_KEY = 0,
49*437bfbebSnyanmisaka MPP_CFG_PARSER_TYPE_VALUE,
50*437bfbebSnyanmisaka MPP_CFG_PARSER_TYPE_TABLE,
51*437bfbebSnyanmisaka MPP_CFG_PARSER_TYPE_ARRAY_TABLE,
52*437bfbebSnyanmisaka MPP_CFG_PARSER_TYPE_BUTT,
53*437bfbebSnyanmisaka } MppCfgParserType;
54*437bfbebSnyanmisaka
55*437bfbebSnyanmisaka typedef struct MppCfgIoImpl_t MppCfgIoImpl;
56*437bfbebSnyanmisaka typedef void (*MppCfgIoFunc)(MppCfgIoImpl *obj, void *data);
57*437bfbebSnyanmisaka
58*437bfbebSnyanmisaka struct MppCfgIoImpl_t {
59*437bfbebSnyanmisaka /* list for bothers */
60*437bfbebSnyanmisaka struct list_head list;
61*437bfbebSnyanmisaka /* list for children */
62*437bfbebSnyanmisaka struct list_head child;
63*437bfbebSnyanmisaka /* parent of current object */
64*437bfbebSnyanmisaka MppCfgIoImpl *parent;
65*437bfbebSnyanmisaka /* valid condition callback for the current object */
66*437bfbebSnyanmisaka MppCfgObjCond cond;
67*437bfbebSnyanmisaka
68*437bfbebSnyanmisaka MppCfgType type;
69*437bfbebSnyanmisaka MppCfgVal val;
70*437bfbebSnyanmisaka
71*437bfbebSnyanmisaka rk_s32 buf_size;
72*437bfbebSnyanmisaka /* depth in tree */
73*437bfbebSnyanmisaka rk_s32 depth;
74*437bfbebSnyanmisaka
75*437bfbebSnyanmisaka /* internal name storage */
76*437bfbebSnyanmisaka char *name;
77*437bfbebSnyanmisaka rk_s32 name_len;
78*437bfbebSnyanmisaka rk_s32 name_buf_len;
79*437bfbebSnyanmisaka
80*437bfbebSnyanmisaka /* location info for structure access */
81*437bfbebSnyanmisaka MppTrie trie;
82*437bfbebSnyanmisaka MppCfgInfo info;
83*437bfbebSnyanmisaka
84*437bfbebSnyanmisaka union {
85*437bfbebSnyanmisaka /* MPP_CFG_TYPE_STRING */
86*437bfbebSnyanmisaka struct {
87*437bfbebSnyanmisaka char *string;
88*437bfbebSnyanmisaka rk_s32 str_len;
89*437bfbebSnyanmisaka };
90*437bfbebSnyanmisaka /* MPP_CFG_TYPE_ARRAY */
91*437bfbebSnyanmisaka struct {
92*437bfbebSnyanmisaka MppCfgIoImpl **elems;
93*437bfbebSnyanmisaka rk_s32 array_size;
94*437bfbebSnyanmisaka };
95*437bfbebSnyanmisaka };
96*437bfbebSnyanmisaka };
97*437bfbebSnyanmisaka
98*437bfbebSnyanmisaka typedef struct MppCfgStrBuf_t {
99*437bfbebSnyanmisaka char *buf;
100*437bfbebSnyanmisaka rk_s32 buf_size;
101*437bfbebSnyanmisaka rk_s32 offset;
102*437bfbebSnyanmisaka rk_s32 depth;
103*437bfbebSnyanmisaka MppCfgStrFmt type;
104*437bfbebSnyanmisaka } MppCfgStrBuf;
105*437bfbebSnyanmisaka
106*437bfbebSnyanmisaka static rk_u32 mpp_cfg_io_debug = 0;
107*437bfbebSnyanmisaka
strof_type(MppCfgType type)108*437bfbebSnyanmisaka static const char *strof_type(MppCfgType type)
109*437bfbebSnyanmisaka {
110*437bfbebSnyanmisaka static const char *str[MPP_CFG_TYPE_BUTT + 1] = {
111*437bfbebSnyanmisaka [MPP_CFG_TYPE_INVALID] = "invalid",
112*437bfbebSnyanmisaka [MPP_CFG_TYPE_NULL] = "null",
113*437bfbebSnyanmisaka [MPP_CFG_TYPE_BOOL] = "bool",
114*437bfbebSnyanmisaka [MPP_CFG_TYPE_s32] = "s32",
115*437bfbebSnyanmisaka [MPP_CFG_TYPE_u32] = "u32",
116*437bfbebSnyanmisaka [MPP_CFG_TYPE_s64] = "s64",
117*437bfbebSnyanmisaka [MPP_CFG_TYPE_u64] = "u64",
118*437bfbebSnyanmisaka [MPP_CFG_TYPE_f32] = "f32",
119*437bfbebSnyanmisaka [MPP_CFG_TYPE_f64] = "f64",
120*437bfbebSnyanmisaka [MPP_CFG_TYPE_STRING] = "string",
121*437bfbebSnyanmisaka [MPP_CFG_TYPE_RAW] = "raw",
122*437bfbebSnyanmisaka [MPP_CFG_TYPE_OBJECT] = "object",
123*437bfbebSnyanmisaka [MPP_CFG_TYPE_ARRAY] = "array",
124*437bfbebSnyanmisaka [MPP_CFG_TYPE_BUTT] = "unknown",
125*437bfbebSnyanmisaka };
126*437bfbebSnyanmisaka
127*437bfbebSnyanmisaka if (type < 0 || type > MPP_CFG_TYPE_BUTT)
128*437bfbebSnyanmisaka type = MPP_CFG_TYPE_BUTT;
129*437bfbebSnyanmisaka
130*437bfbebSnyanmisaka return str[type];
131*437bfbebSnyanmisaka }
132*437bfbebSnyanmisaka
dup_str(const char * str,rk_s32 len)133*437bfbebSnyanmisaka static char *dup_str(const char *str, rk_s32 len)
134*437bfbebSnyanmisaka {
135*437bfbebSnyanmisaka char *ret = NULL;
136*437bfbebSnyanmisaka
137*437bfbebSnyanmisaka if (str && len > 0) {
138*437bfbebSnyanmisaka ret = mpp_calloc_size(char, len + 1);
139*437bfbebSnyanmisaka if (ret) {
140*437bfbebSnyanmisaka memcpy(ret, str, len);
141*437bfbebSnyanmisaka ret[len] = '\0';
142*437bfbebSnyanmisaka }
143*437bfbebSnyanmisaka }
144*437bfbebSnyanmisaka
145*437bfbebSnyanmisaka return ret;
146*437bfbebSnyanmisaka }
147*437bfbebSnyanmisaka
get_full_name(MppCfgIoImpl * obj,char * buf,rk_s32 buf_size)148*437bfbebSnyanmisaka static rk_s32 get_full_name(MppCfgIoImpl *obj, char *buf, rk_s32 buf_size)
149*437bfbebSnyanmisaka {
150*437bfbebSnyanmisaka MppCfgIoImpl *curr = obj;
151*437bfbebSnyanmisaka char *name[MAX_CFG_DEPTH];
152*437bfbebSnyanmisaka char *delmiter = ":";
153*437bfbebSnyanmisaka rk_s32 depth = 0;
154*437bfbebSnyanmisaka rk_s32 len = 0;
155*437bfbebSnyanmisaka rk_s32 i = 0;
156*437bfbebSnyanmisaka
157*437bfbebSnyanmisaka while (curr && curr->parent) {
158*437bfbebSnyanmisaka /* skip the root */
159*437bfbebSnyanmisaka if (curr->name) {
160*437bfbebSnyanmisaka /* Add delimiter on object */
161*437bfbebSnyanmisaka if (curr->type >= MPP_CFG_TYPE_OBJECT)
162*437bfbebSnyanmisaka name[i++] = delmiter;
163*437bfbebSnyanmisaka
164*437bfbebSnyanmisaka name[i++] = curr->name;
165*437bfbebSnyanmisaka }
166*437bfbebSnyanmisaka
167*437bfbebSnyanmisaka curr = curr->parent;
168*437bfbebSnyanmisaka depth++;
169*437bfbebSnyanmisaka
170*437bfbebSnyanmisaka if (i >= MAX_CFG_DEPTH) {
171*437bfbebSnyanmisaka mpp_loge_f("too deep depth %d\n", depth);
172*437bfbebSnyanmisaka return 0;
173*437bfbebSnyanmisaka }
174*437bfbebSnyanmisaka }
175*437bfbebSnyanmisaka
176*437bfbebSnyanmisaka if (!i) {
177*437bfbebSnyanmisaka buf[0] = '\0';
178*437bfbebSnyanmisaka return 0;
179*437bfbebSnyanmisaka }
180*437bfbebSnyanmisaka
181*437bfbebSnyanmisaka depth = i;
182*437bfbebSnyanmisaka for (i = depth - 1; i >= 0; i--) {
183*437bfbebSnyanmisaka len += snprintf(buf + len, buf_size - len, "%s", name[i]);
184*437bfbebSnyanmisaka
185*437bfbebSnyanmisaka if (len >= buf_size) {
186*437bfbebSnyanmisaka mpp_loge_f("buffer overflow len %d buf_size %d\n", len, buf_size);
187*437bfbebSnyanmisaka break;
188*437bfbebSnyanmisaka }
189*437bfbebSnyanmisaka }
190*437bfbebSnyanmisaka
191*437bfbebSnyanmisaka cfg_io_dbg_name("depth %d obj %-16s -> %s\n", obj->depth, obj->name, buf);
192*437bfbebSnyanmisaka
193*437bfbebSnyanmisaka return len;
194*437bfbebSnyanmisaka }
195*437bfbebSnyanmisaka
loop_all_children(MppCfgIoImpl * impl,MppCfgIoFunc func,void * data)196*437bfbebSnyanmisaka void loop_all_children(MppCfgIoImpl *impl, MppCfgIoFunc func, void *data)
197*437bfbebSnyanmisaka {
198*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
199*437bfbebSnyanmisaka
200*437bfbebSnyanmisaka func(impl, data);
201*437bfbebSnyanmisaka
202*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
203*437bfbebSnyanmisaka loop_all_children(pos, func, data);
204*437bfbebSnyanmisaka }
205*437bfbebSnyanmisaka }
206*437bfbebSnyanmisaka
mpp_cfg_get_object(MppCfgObj * obj,const char * name,MppCfgType type,MppCfgVal * val)207*437bfbebSnyanmisaka rk_s32 mpp_cfg_get_object(MppCfgObj *obj, const char *name, MppCfgType type, MppCfgVal *val)
208*437bfbebSnyanmisaka {
209*437bfbebSnyanmisaka MppCfgIoImpl *impl = NULL;
210*437bfbebSnyanmisaka rk_s32 name_buf_len = 0;
211*437bfbebSnyanmisaka rk_s32 name_len = 0;
212*437bfbebSnyanmisaka rk_s32 buf_size = 0;
213*437bfbebSnyanmisaka rk_s32 str_len = 0;
214*437bfbebSnyanmisaka
215*437bfbebSnyanmisaka if (!obj || type <= MPP_CFG_TYPE_INVALID || type >= MPP_CFG_TYPE_BUTT) {
216*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p name %s type %d val %p\n", obj, name, type, val);
217*437bfbebSnyanmisaka return rk_nok;
218*437bfbebSnyanmisaka }
219*437bfbebSnyanmisaka
220*437bfbebSnyanmisaka mpp_env_get_u32("mpp_cfg_io_debug", &mpp_cfg_io_debug, mpp_cfg_io_debug);
221*437bfbebSnyanmisaka
222*437bfbebSnyanmisaka if (*obj)
223*437bfbebSnyanmisaka mpp_logw_f("obj %p overwrite\n", *obj);
224*437bfbebSnyanmisaka
225*437bfbebSnyanmisaka *obj = NULL;
226*437bfbebSnyanmisaka
227*437bfbebSnyanmisaka if (name) {
228*437bfbebSnyanmisaka name_len = strlen(name);
229*437bfbebSnyanmisaka name_buf_len = MPP_ALIGN(name_len + 1, 4);
230*437bfbebSnyanmisaka }
231*437bfbebSnyanmisaka
232*437bfbebSnyanmisaka if (type == MPP_CFG_TYPE_STRING && val && val->str)
233*437bfbebSnyanmisaka str_len = MPP_ALIGN(strlen(val->str) + 1, 4);
234*437bfbebSnyanmisaka
235*437bfbebSnyanmisaka buf_size = sizeof(MppCfgIoImpl) + name_buf_len + str_len;
236*437bfbebSnyanmisaka impl = mpp_calloc_size(MppCfgIoImpl, buf_size);
237*437bfbebSnyanmisaka
238*437bfbebSnyanmisaka if (!impl) {
239*437bfbebSnyanmisaka mpp_loge_f("failed to alloc impl size %d\n", buf_size);
240*437bfbebSnyanmisaka return rk_nok;
241*437bfbebSnyanmisaka }
242*437bfbebSnyanmisaka
243*437bfbebSnyanmisaka INIT_LIST_HEAD(&impl->list);
244*437bfbebSnyanmisaka INIT_LIST_HEAD(&impl->child);
245*437bfbebSnyanmisaka
246*437bfbebSnyanmisaka if (name_buf_len) {
247*437bfbebSnyanmisaka impl->name = (char *)(impl + 1);
248*437bfbebSnyanmisaka memcpy(impl->name, name, name_len);
249*437bfbebSnyanmisaka impl->name[name_len] = '\0';
250*437bfbebSnyanmisaka impl->name_len = name_len;
251*437bfbebSnyanmisaka impl->name_buf_len = name_buf_len;
252*437bfbebSnyanmisaka }
253*437bfbebSnyanmisaka
254*437bfbebSnyanmisaka if (str_len) {
255*437bfbebSnyanmisaka impl->string = (char *)(impl + 1) + name_buf_len;
256*437bfbebSnyanmisaka strncpy(impl->string, val->str, str_len);
257*437bfbebSnyanmisaka impl->str_len = str_len;
258*437bfbebSnyanmisaka }
259*437bfbebSnyanmisaka
260*437bfbebSnyanmisaka impl->type = type;
261*437bfbebSnyanmisaka if (val)
262*437bfbebSnyanmisaka impl->val = *val;
263*437bfbebSnyanmisaka impl->buf_size = buf_size;
264*437bfbebSnyanmisaka /* set invalid data type by default */
265*437bfbebSnyanmisaka impl->info.data_type = CFG_FUNC_TYPE_BUTT;
266*437bfbebSnyanmisaka
267*437bfbebSnyanmisaka if (type == MPP_CFG_TYPE_STRING)
268*437bfbebSnyanmisaka impl->val.str = impl->string;
269*437bfbebSnyanmisaka
270*437bfbebSnyanmisaka *obj = impl;
271*437bfbebSnyanmisaka
272*437bfbebSnyanmisaka return rk_ok;
273*437bfbebSnyanmisaka }
274*437bfbebSnyanmisaka
mpp_cfg_get_array(MppCfgObj * obj,const char * name,rk_s32 count)275*437bfbebSnyanmisaka rk_s32 mpp_cfg_get_array(MppCfgObj *obj, const char *name, rk_s32 count)
276*437bfbebSnyanmisaka {
277*437bfbebSnyanmisaka MppCfgIoImpl *impl = NULL;
278*437bfbebSnyanmisaka rk_s32 name_buf_len = 0;
279*437bfbebSnyanmisaka rk_s32 name_len = 0;
280*437bfbebSnyanmisaka rk_s32 buf_size = 0;
281*437bfbebSnyanmisaka
282*437bfbebSnyanmisaka if (!obj) {
283*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p name %s count %d\n", obj, name, count);
284*437bfbebSnyanmisaka return rk_nok;
285*437bfbebSnyanmisaka }
286*437bfbebSnyanmisaka
287*437bfbebSnyanmisaka if (*obj)
288*437bfbebSnyanmisaka mpp_logw_f("obj %p overwrite\n", *obj);
289*437bfbebSnyanmisaka
290*437bfbebSnyanmisaka *obj = NULL;
291*437bfbebSnyanmisaka
292*437bfbebSnyanmisaka if (name) {
293*437bfbebSnyanmisaka name_len = strlen(name);
294*437bfbebSnyanmisaka name_buf_len = MPP_ALIGN(name_len + 1, 4);
295*437bfbebSnyanmisaka }
296*437bfbebSnyanmisaka
297*437bfbebSnyanmisaka buf_size = sizeof(MppCfgIoImpl) + name_buf_len + count * sizeof(MppCfgObj);
298*437bfbebSnyanmisaka impl = mpp_calloc_size(MppCfgIoImpl, buf_size);
299*437bfbebSnyanmisaka
300*437bfbebSnyanmisaka if (!impl) {
301*437bfbebSnyanmisaka mpp_loge_f("failed to alloc impl size %d\n", buf_size);
302*437bfbebSnyanmisaka return rk_nok;
303*437bfbebSnyanmisaka }
304*437bfbebSnyanmisaka
305*437bfbebSnyanmisaka INIT_LIST_HEAD(&impl->list);
306*437bfbebSnyanmisaka INIT_LIST_HEAD(&impl->child);
307*437bfbebSnyanmisaka
308*437bfbebSnyanmisaka if (name_len) {
309*437bfbebSnyanmisaka impl->name = (char *)(impl + 1);
310*437bfbebSnyanmisaka memcpy(impl->name, name, name_len);
311*437bfbebSnyanmisaka impl->name[name_len] = '\0';
312*437bfbebSnyanmisaka impl->name_len = name_len;
313*437bfbebSnyanmisaka impl->name_buf_len = name_buf_len;
314*437bfbebSnyanmisaka }
315*437bfbebSnyanmisaka
316*437bfbebSnyanmisaka impl->type = MPP_CFG_TYPE_ARRAY;
317*437bfbebSnyanmisaka impl->buf_size = buf_size;
318*437bfbebSnyanmisaka /* set invalid data type by default */
319*437bfbebSnyanmisaka impl->info.data_type = CFG_FUNC_TYPE_BUTT;
320*437bfbebSnyanmisaka
321*437bfbebSnyanmisaka if (count) {
322*437bfbebSnyanmisaka impl->elems = (MppCfgIoImpl **)((char *)(impl + 1) + name_buf_len);
323*437bfbebSnyanmisaka impl->array_size = count;
324*437bfbebSnyanmisaka }
325*437bfbebSnyanmisaka
326*437bfbebSnyanmisaka *obj = impl;
327*437bfbebSnyanmisaka
328*437bfbebSnyanmisaka return rk_ok;
329*437bfbebSnyanmisaka }
330*437bfbebSnyanmisaka
mpp_cfg_put(MppCfgObj obj)331*437bfbebSnyanmisaka rk_s32 mpp_cfg_put(MppCfgObj obj)
332*437bfbebSnyanmisaka {
333*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
334*437bfbebSnyanmisaka
335*437bfbebSnyanmisaka if (!obj) {
336*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p\n", obj);
337*437bfbebSnyanmisaka return rk_nok;
338*437bfbebSnyanmisaka }
339*437bfbebSnyanmisaka
340*437bfbebSnyanmisaka list_del_init(&impl->list);
341*437bfbebSnyanmisaka
342*437bfbebSnyanmisaka {
343*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
344*437bfbebSnyanmisaka
345*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
346*437bfbebSnyanmisaka list_del_init(&pos->list);
347*437bfbebSnyanmisaka }
348*437bfbebSnyanmisaka }
349*437bfbebSnyanmisaka
350*437bfbebSnyanmisaka impl->parent = NULL;
351*437bfbebSnyanmisaka
352*437bfbebSnyanmisaka mpp_free(impl);
353*437bfbebSnyanmisaka
354*437bfbebSnyanmisaka return rk_ok;
355*437bfbebSnyanmisaka }
356*437bfbebSnyanmisaka
mpp_cfg_put_all_child(MppCfgIoImpl * impl)357*437bfbebSnyanmisaka static void mpp_cfg_put_all_child(MppCfgIoImpl *impl)
358*437bfbebSnyanmisaka {
359*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
360*437bfbebSnyanmisaka
361*437bfbebSnyanmisaka cfg_io_dbg_free("depth %d - %p free start type %d name %s\n",
362*437bfbebSnyanmisaka impl->depth, impl, impl->type, impl->name);
363*437bfbebSnyanmisaka
364*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
365*437bfbebSnyanmisaka list_del_init(&pos->list);
366*437bfbebSnyanmisaka
367*437bfbebSnyanmisaka cfg_io_dbg_free("depth %d - %p free child %p type %d name %s\n",
368*437bfbebSnyanmisaka impl->depth, impl, pos, pos->type, pos->name);
369*437bfbebSnyanmisaka
370*437bfbebSnyanmisaka mpp_cfg_put_all_child(pos);
371*437bfbebSnyanmisaka }
372*437bfbebSnyanmisaka
373*437bfbebSnyanmisaka cfg_io_dbg_free("depth %d - %p free done type %d name %s\n",
374*437bfbebSnyanmisaka impl->depth, impl, impl->type, impl->name);
375*437bfbebSnyanmisaka
376*437bfbebSnyanmisaka mpp_free(impl);
377*437bfbebSnyanmisaka }
378*437bfbebSnyanmisaka
mpp_cfg_put_all(MppCfgObj obj)379*437bfbebSnyanmisaka rk_s32 mpp_cfg_put_all(MppCfgObj obj)
380*437bfbebSnyanmisaka {
381*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
382*437bfbebSnyanmisaka MppCfgIoImpl *root;
383*437bfbebSnyanmisaka
384*437bfbebSnyanmisaka if (!obj) {
385*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p\n", obj);
386*437bfbebSnyanmisaka return rk_nok;
387*437bfbebSnyanmisaka }
388*437bfbebSnyanmisaka
389*437bfbebSnyanmisaka if (impl->trie) {
390*437bfbebSnyanmisaka mpp_trie_deinit(impl->trie);
391*437bfbebSnyanmisaka impl->trie = NULL;
392*437bfbebSnyanmisaka }
393*437bfbebSnyanmisaka
394*437bfbebSnyanmisaka root = impl->parent;
395*437bfbebSnyanmisaka do {
396*437bfbebSnyanmisaka mpp_cfg_put_all_child(impl);
397*437bfbebSnyanmisaka
398*437bfbebSnyanmisaka if (!root)
399*437bfbebSnyanmisaka break;
400*437bfbebSnyanmisaka
401*437bfbebSnyanmisaka impl = root;
402*437bfbebSnyanmisaka root = impl->parent;
403*437bfbebSnyanmisaka } while (impl);
404*437bfbebSnyanmisaka
405*437bfbebSnyanmisaka return rk_ok;
406*437bfbebSnyanmisaka }
407*437bfbebSnyanmisaka
update_depth(MppCfgIoImpl * impl,void * data)408*437bfbebSnyanmisaka static void update_depth(MppCfgIoImpl *impl, void *data)
409*437bfbebSnyanmisaka {
410*437bfbebSnyanmisaka (void)data;
411*437bfbebSnyanmisaka
412*437bfbebSnyanmisaka if (impl->parent)
413*437bfbebSnyanmisaka impl->depth = impl->parent->depth + 1;
414*437bfbebSnyanmisaka }
415*437bfbebSnyanmisaka
mpp_cfg_add(MppCfgObj root,MppCfgObj leaf)416*437bfbebSnyanmisaka rk_s32 mpp_cfg_add(MppCfgObj root, MppCfgObj leaf)
417*437bfbebSnyanmisaka {
418*437bfbebSnyanmisaka MppCfgIoImpl *root_impl = (MppCfgIoImpl *)root;
419*437bfbebSnyanmisaka MppCfgIoImpl *leaf_impl = (MppCfgIoImpl *)leaf;
420*437bfbebSnyanmisaka
421*437bfbebSnyanmisaka if (!root || !leaf) {
422*437bfbebSnyanmisaka mpp_loge_f("invalid param root %p leaf %p\n", root, leaf);
423*437bfbebSnyanmisaka return rk_nok;
424*437bfbebSnyanmisaka }
425*437bfbebSnyanmisaka
426*437bfbebSnyanmisaka if (root_impl->type <= MPP_CFG_TYPE_INVALID || root_impl->type >= MPP_CFG_TYPE_BUTT) {
427*437bfbebSnyanmisaka mpp_loge_f("invalid root type %d\n", root_impl->type);
428*437bfbebSnyanmisaka return rk_nok;
429*437bfbebSnyanmisaka }
430*437bfbebSnyanmisaka
431*437bfbebSnyanmisaka list_add_tail(&leaf_impl->list, &root_impl->child);
432*437bfbebSnyanmisaka leaf_impl->parent = root_impl;
433*437bfbebSnyanmisaka
434*437bfbebSnyanmisaka loop_all_children(root, update_depth, NULL);
435*437bfbebSnyanmisaka
436*437bfbebSnyanmisaka if (root_impl->type == MPP_CFG_TYPE_ARRAY && root_impl->elems) {
437*437bfbebSnyanmisaka rk_s32 i;
438*437bfbebSnyanmisaka
439*437bfbebSnyanmisaka for (i = 0; i < root_impl->array_size; i++) {
440*437bfbebSnyanmisaka if (!root_impl->elems[i]) {
441*437bfbebSnyanmisaka root_impl->elems[i] = leaf_impl;
442*437bfbebSnyanmisaka break;
443*437bfbebSnyanmisaka }
444*437bfbebSnyanmisaka }
445*437bfbebSnyanmisaka }
446*437bfbebSnyanmisaka
447*437bfbebSnyanmisaka return rk_ok;
448*437bfbebSnyanmisaka }
449*437bfbebSnyanmisaka
mpp_cfg_del(MppCfgObj obj)450*437bfbebSnyanmisaka rk_s32 mpp_cfg_del(MppCfgObj obj)
451*437bfbebSnyanmisaka {
452*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
453*437bfbebSnyanmisaka MppCfgIoImpl *parent;
454*437bfbebSnyanmisaka
455*437bfbebSnyanmisaka if (!obj) {
456*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p\n", obj);
457*437bfbebSnyanmisaka return rk_nok;
458*437bfbebSnyanmisaka }
459*437bfbebSnyanmisaka
460*437bfbebSnyanmisaka parent = impl->parent;
461*437bfbebSnyanmisaka if (parent) {
462*437bfbebSnyanmisaka list_del_init(&impl->list);
463*437bfbebSnyanmisaka
464*437bfbebSnyanmisaka if (parent->type == MPP_CFG_TYPE_ARRAY && parent->elems) {
465*437bfbebSnyanmisaka rk_s32 i;
466*437bfbebSnyanmisaka
467*437bfbebSnyanmisaka for (i = 0; i < parent->array_size; i++) {
468*437bfbebSnyanmisaka if (parent->elems[i] == impl) {
469*437bfbebSnyanmisaka parent->elems[i] = NULL;
470*437bfbebSnyanmisaka break;
471*437bfbebSnyanmisaka }
472*437bfbebSnyanmisaka }
473*437bfbebSnyanmisaka }
474*437bfbebSnyanmisaka
475*437bfbebSnyanmisaka impl->parent = NULL;
476*437bfbebSnyanmisaka impl->depth = 0;
477*437bfbebSnyanmisaka loop_all_children(impl, update_depth, NULL);
478*437bfbebSnyanmisaka }
479*437bfbebSnyanmisaka
480*437bfbebSnyanmisaka return rk_ok;
481*437bfbebSnyanmisaka }
482*437bfbebSnyanmisaka
mpp_cfg_find(MppCfgObj * obj,MppCfgObj root,char * name,rk_s32 type)483*437bfbebSnyanmisaka rk_s32 mpp_cfg_find(MppCfgObj *obj, MppCfgObj root, char *name, rk_s32 type)
484*437bfbebSnyanmisaka {
485*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)root;
486*437bfbebSnyanmisaka rk_s32 str_start = 0;
487*437bfbebSnyanmisaka rk_s32 str_len = 0;
488*437bfbebSnyanmisaka rk_s32 i;
489*437bfbebSnyanmisaka char delimiter;
490*437bfbebSnyanmisaka
491*437bfbebSnyanmisaka if (!obj || !root || !name) {
492*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p root %p name %s\n", obj, root, name);
493*437bfbebSnyanmisaka return rk_nok;
494*437bfbebSnyanmisaka }
495*437bfbebSnyanmisaka
496*437bfbebSnyanmisaka delimiter = (type == MPP_CFG_STR_FMT_TOML) ? '.' : ':';
497*437bfbebSnyanmisaka str_len = strlen(name);
498*437bfbebSnyanmisaka
499*437bfbebSnyanmisaka for (i = 0; i <= str_len; i++) {
500*437bfbebSnyanmisaka if (name[i] == delimiter || name[i] == '\0') {
501*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
502*437bfbebSnyanmisaka MppCfgIoImpl *last_array = NULL;
503*437bfbebSnyanmisaka char bak = name[i];
504*437bfbebSnyanmisaka rk_s32 found = 0;
505*437bfbebSnyanmisaka
506*437bfbebSnyanmisaka name[i] = '\0';
507*437bfbebSnyanmisaka mpp_logi("try match %s\n", name + str_start);
508*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
509*437bfbebSnyanmisaka if (pos->name && !strcmp(pos->name, name + str_start)) {
510*437bfbebSnyanmisaka impl = pos;
511*437bfbebSnyanmisaka found = 1;
512*437bfbebSnyanmisaka break;
513*437bfbebSnyanmisaka }
514*437bfbebSnyanmisaka
515*437bfbebSnyanmisaka /* if impl is array, find impl->chil is object and has no name, to match its child */
516*437bfbebSnyanmisaka if (impl->type == MPP_CFG_TYPE_ARRAY && pos->type == MPP_CFG_TYPE_OBJECT && !pos->name)
517*437bfbebSnyanmisaka last_array = pos;
518*437bfbebSnyanmisaka }
519*437bfbebSnyanmisaka
520*437bfbebSnyanmisaka if (last_array) {
521*437bfbebSnyanmisaka MppCfgIoImpl *array_pos, *array_n;
522*437bfbebSnyanmisaka
523*437bfbebSnyanmisaka list_for_each_entry_safe(array_pos, array_n, &last_array->child, MppCfgIoImpl, list) {
524*437bfbebSnyanmisaka if (array_pos->name && !strcmp(array_pos->name, name + str_start)) {
525*437bfbebSnyanmisaka impl = array_pos;
526*437bfbebSnyanmisaka found = 1;
527*437bfbebSnyanmisaka break;
528*437bfbebSnyanmisaka }
529*437bfbebSnyanmisaka }
530*437bfbebSnyanmisaka }
531*437bfbebSnyanmisaka
532*437bfbebSnyanmisaka name[i] = bak;
533*437bfbebSnyanmisaka
534*437bfbebSnyanmisaka if (!found) {
535*437bfbebSnyanmisaka *obj = NULL;
536*437bfbebSnyanmisaka return rk_nok;
537*437bfbebSnyanmisaka }
538*437bfbebSnyanmisaka
539*437bfbebSnyanmisaka str_start = i + 1;
540*437bfbebSnyanmisaka }
541*437bfbebSnyanmisaka }
542*437bfbebSnyanmisaka
543*437bfbebSnyanmisaka *obj = impl;
544*437bfbebSnyanmisaka return rk_ok;
545*437bfbebSnyanmisaka }
546*437bfbebSnyanmisaka
mpp_cfg_set_info(MppCfgObj obj,MppCfgInfo * info)547*437bfbebSnyanmisaka rk_s32 mpp_cfg_set_info(MppCfgObj obj, MppCfgInfo *info)
548*437bfbebSnyanmisaka {
549*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
550*437bfbebSnyanmisaka
551*437bfbebSnyanmisaka if (impl && info) {
552*437bfbebSnyanmisaka cfg_io_dbg_info("obj %-16s set info type %s offset %d size %d\n",
553*437bfbebSnyanmisaka impl->name, strof_cfg_type(info->data_type),
554*437bfbebSnyanmisaka info->data_offset, info->data_size);
555*437bfbebSnyanmisaka
556*437bfbebSnyanmisaka if (info->data_type < CFG_FUNC_TYPE_BUTT) {
557*437bfbebSnyanmisaka memcpy(&impl->info, info, sizeof(impl->info));
558*437bfbebSnyanmisaka
559*437bfbebSnyanmisaka switch (info->data_type) {
560*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s32 : {
561*437bfbebSnyanmisaka impl->type = MPP_CFG_TYPE_s32;
562*437bfbebSnyanmisaka } break;
563*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u32 : {
564*437bfbebSnyanmisaka impl->type = MPP_CFG_TYPE_u32;
565*437bfbebSnyanmisaka } break;
566*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s64 : {
567*437bfbebSnyanmisaka impl->type = MPP_CFG_TYPE_s64;
568*437bfbebSnyanmisaka } break;
569*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u64 : {
570*437bfbebSnyanmisaka impl->type = MPP_CFG_TYPE_u64;
571*437bfbebSnyanmisaka } break;
572*437bfbebSnyanmisaka default : {
573*437bfbebSnyanmisaka } break;
574*437bfbebSnyanmisaka }
575*437bfbebSnyanmisaka } else {
576*437bfbebSnyanmisaka impl->info.data_type = CFG_FUNC_TYPE_BUTT;
577*437bfbebSnyanmisaka }
578*437bfbebSnyanmisaka
579*437bfbebSnyanmisaka return rk_ok;
580*437bfbebSnyanmisaka }
581*437bfbebSnyanmisaka
582*437bfbebSnyanmisaka return rk_nok;
583*437bfbebSnyanmisaka }
584*437bfbebSnyanmisaka
mpp_cfg_set_cond(MppCfgObj obj,MppCfgObjCond cond)585*437bfbebSnyanmisaka rk_s32 mpp_cfg_set_cond(MppCfgObj obj, MppCfgObjCond cond)
586*437bfbebSnyanmisaka {
587*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
588*437bfbebSnyanmisaka
589*437bfbebSnyanmisaka if (impl)
590*437bfbebSnyanmisaka impl->cond = cond;
591*437bfbebSnyanmisaka
592*437bfbebSnyanmisaka return rk_ok;
593*437bfbebSnyanmisaka }
594*437bfbebSnyanmisaka typedef struct MppCfgFullNameCtx_t {
595*437bfbebSnyanmisaka MppTrie trie;
596*437bfbebSnyanmisaka char *buf;
597*437bfbebSnyanmisaka rk_s32 buf_size;
598*437bfbebSnyanmisaka } MppCfgFullNameCtx;
599*437bfbebSnyanmisaka
add_obj_info(MppCfgIoImpl * impl,void * data)600*437bfbebSnyanmisaka static void add_obj_info(MppCfgIoImpl *impl, void *data)
601*437bfbebSnyanmisaka {
602*437bfbebSnyanmisaka /* NOTE: skip the root object and the invalid object */
603*437bfbebSnyanmisaka if (impl->info.data_type < CFG_FUNC_TYPE_BUTT && impl->parent) {
604*437bfbebSnyanmisaka MppCfgFullNameCtx *ctx = (MppCfgFullNameCtx *)data;
605*437bfbebSnyanmisaka
606*437bfbebSnyanmisaka get_full_name(impl, ctx->buf, ctx->buf_size);
607*437bfbebSnyanmisaka mpp_trie_add_info(ctx->trie, ctx->buf, &impl->info, sizeof(impl->info));
608*437bfbebSnyanmisaka }
609*437bfbebSnyanmisaka }
610*437bfbebSnyanmisaka
mpp_cfg_to_trie(MppCfgObj obj)611*437bfbebSnyanmisaka MppTrie mpp_cfg_to_trie(MppCfgObj obj)
612*437bfbebSnyanmisaka {
613*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
614*437bfbebSnyanmisaka MppTrie p = NULL;
615*437bfbebSnyanmisaka
616*437bfbebSnyanmisaka do {
617*437bfbebSnyanmisaka MppCfgFullNameCtx ctx;
618*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
619*437bfbebSnyanmisaka char name[256];
620*437bfbebSnyanmisaka
621*437bfbebSnyanmisaka if (!impl) {
622*437bfbebSnyanmisaka mpp_loge_f("invalid param obj\n", impl);
623*437bfbebSnyanmisaka break;
624*437bfbebSnyanmisaka }
625*437bfbebSnyanmisaka
626*437bfbebSnyanmisaka if (impl->parent) {
627*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p not root\n", impl);
628*437bfbebSnyanmisaka break;
629*437bfbebSnyanmisaka }
630*437bfbebSnyanmisaka
631*437bfbebSnyanmisaka if (impl->trie) {
632*437bfbebSnyanmisaka p = impl->trie;
633*437bfbebSnyanmisaka break;
634*437bfbebSnyanmisaka }
635*437bfbebSnyanmisaka
636*437bfbebSnyanmisaka ret = mpp_trie_init(&p, impl->name ? impl->name : "cfg_io");
637*437bfbebSnyanmisaka if (ret || !p) {
638*437bfbebSnyanmisaka mpp_loge_f("failed to init obj %s trie\n", impl->name ? impl->name : "cfg_io");
639*437bfbebSnyanmisaka break;
640*437bfbebSnyanmisaka }
641*437bfbebSnyanmisaka
642*437bfbebSnyanmisaka ctx.trie = p;
643*437bfbebSnyanmisaka ctx.buf = name;
644*437bfbebSnyanmisaka ctx.buf_size = sizeof(name) - 1;
645*437bfbebSnyanmisaka
646*437bfbebSnyanmisaka loop_all_children(impl, add_obj_info, &ctx);
647*437bfbebSnyanmisaka mpp_trie_add_info(p, NULL, NULL, 0);
648*437bfbebSnyanmisaka impl->trie = p;
649*437bfbebSnyanmisaka } while (0);
650*437bfbebSnyanmisaka
651*437bfbebSnyanmisaka return p;
652*437bfbebSnyanmisaka }
653*437bfbebSnyanmisaka
654*437bfbebSnyanmisaka /* read byte functions */
655*437bfbebSnyanmisaka /* check valid len, get offset position */
656*437bfbebSnyanmisaka #define test_byte_f(str, len) test_byte(str, len, __FUNCTION__)
657*437bfbebSnyanmisaka /* check valid pos, get offset + pos position */
658*437bfbebSnyanmisaka #define show_byte_f(str, pos) show_byte(str, pos, __FUNCTION__)
659*437bfbebSnyanmisaka /* check valid len, get offset + len position and increase offset by len */
660*437bfbebSnyanmisaka #define skip_byte_f(str, len) skip_byte(str, len, __FUNCTION__)
661*437bfbebSnyanmisaka #define skip_ws_f(str) skip_ws(str, __FUNCTION__)
662*437bfbebSnyanmisaka
663*437bfbebSnyanmisaka /* write byte functions */
664*437bfbebSnyanmisaka #define write_byte_f(str, buf, size) write_byte(str, (void *)buf, size, __FUNCTION__)
665*437bfbebSnyanmisaka #define write_indent_f(str) write_indent(str, __FUNCTION__)
666*437bfbebSnyanmisaka /* revert comma for json */
667*437bfbebSnyanmisaka #define revert_comma_f(str) revert_comma(str, __FUNCTION__)
668*437bfbebSnyanmisaka
test_byte(MppCfgStrBuf * str,rk_s32 len,const char * caller)669*437bfbebSnyanmisaka static char *test_byte(MppCfgStrBuf *str, rk_s32 len, const char *caller)
670*437bfbebSnyanmisaka {
671*437bfbebSnyanmisaka char *ret = NULL;
672*437bfbebSnyanmisaka
673*437bfbebSnyanmisaka if (str->offset + len >= str->buf_size) {
674*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d test %d get the end at %s\n",
675*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, len, caller);
676*437bfbebSnyanmisaka return ret;
677*437bfbebSnyanmisaka }
678*437bfbebSnyanmisaka
679*437bfbebSnyanmisaka ret = str->buf + str->offset;
680*437bfbebSnyanmisaka
681*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d test %d ret %p at %s\n",
682*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, len, ret, caller);
683*437bfbebSnyanmisaka
684*437bfbebSnyanmisaka return ret;
685*437bfbebSnyanmisaka }
686*437bfbebSnyanmisaka
show_byte(MppCfgStrBuf * str,rk_s32 pos,const char * caller)687*437bfbebSnyanmisaka static char *show_byte(MppCfgStrBuf *str, rk_s32 pos, const char *caller)
688*437bfbebSnyanmisaka {
689*437bfbebSnyanmisaka char *ret = NULL;
690*437bfbebSnyanmisaka
691*437bfbebSnyanmisaka if (str->offset + pos >= str->buf_size) {
692*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d show pos %d get the end at %s\n",
693*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, pos, caller);
694*437bfbebSnyanmisaka return ret;
695*437bfbebSnyanmisaka }
696*437bfbebSnyanmisaka
697*437bfbebSnyanmisaka ret = str->buf + str->offset + pos;
698*437bfbebSnyanmisaka
699*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d show %d ret %p at %s\n",
700*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, pos, ret, caller);
701*437bfbebSnyanmisaka
702*437bfbebSnyanmisaka return ret;
703*437bfbebSnyanmisaka }
704*437bfbebSnyanmisaka
skip_byte(MppCfgStrBuf * str,rk_s32 len,const char * caller)705*437bfbebSnyanmisaka static char *skip_byte(MppCfgStrBuf *str, rk_s32 len, const char *caller)
706*437bfbebSnyanmisaka {
707*437bfbebSnyanmisaka char *ret = NULL;
708*437bfbebSnyanmisaka
709*437bfbebSnyanmisaka if (str->offset + len >= str->buf_size) {
710*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d skip %d get the end at %s\n",
711*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, len, caller);
712*437bfbebSnyanmisaka return NULL;
713*437bfbebSnyanmisaka }
714*437bfbebSnyanmisaka
715*437bfbebSnyanmisaka ret = str->buf + str->offset + len;
716*437bfbebSnyanmisaka
717*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d skip %d ret %p at %s\n",
718*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, len, ret, caller);
719*437bfbebSnyanmisaka
720*437bfbebSnyanmisaka str->offset += len;
721*437bfbebSnyanmisaka return ret;
722*437bfbebSnyanmisaka }
723*437bfbebSnyanmisaka
skip_ws(MppCfgStrBuf * str,const char * caller)724*437bfbebSnyanmisaka static char *skip_ws(MppCfgStrBuf *str, const char *caller)
725*437bfbebSnyanmisaka {
726*437bfbebSnyanmisaka rk_s32 old = str->offset;
727*437bfbebSnyanmisaka char *p;
728*437bfbebSnyanmisaka
729*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d skip ws start at %s\n",
730*437bfbebSnyanmisaka str, str->buf, str->buf_size, old, caller);
731*437bfbebSnyanmisaka
732*437bfbebSnyanmisaka while ((p = show_byte(str, 0, caller)) && p[0] <= 32)
733*437bfbebSnyanmisaka str->offset++;
734*437bfbebSnyanmisaka
735*437bfbebSnyanmisaka if (str->offset >= str->buf_size) {
736*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d skip ws to the end at %s\n",
737*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, caller);
738*437bfbebSnyanmisaka str->offset--;
739*437bfbebSnyanmisaka return NULL;
740*437bfbebSnyanmisaka }
741*437bfbebSnyanmisaka
742*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] offset %d skip ws to %d at %s\n",
743*437bfbebSnyanmisaka str, str->buf, str->buf_size, old, str->offset, caller);
744*437bfbebSnyanmisaka
745*437bfbebSnyanmisaka return str->buf + str->offset;
746*437bfbebSnyanmisaka }
747*437bfbebSnyanmisaka
write_byte(MppCfgStrBuf * str,void * buf,rk_s32 * size,const char * caller)748*437bfbebSnyanmisaka static rk_s32 write_byte(MppCfgStrBuf *str, void *buf, rk_s32 *size, const char *caller)
749*437bfbebSnyanmisaka {
750*437bfbebSnyanmisaka rk_s32 len = size[0];
751*437bfbebSnyanmisaka
752*437bfbebSnyanmisaka if (!len)
753*437bfbebSnyanmisaka return rk_ok;
754*437bfbebSnyanmisaka
755*437bfbebSnyanmisaka if (str->offset + len >= str->buf_size) {
756*437bfbebSnyanmisaka void *ptr = mpp_realloc_size(str->buf, void, str->buf_size * 2);
757*437bfbebSnyanmisaka
758*437bfbebSnyanmisaka if (!ptr) {
759*437bfbebSnyanmisaka mpp_loge("failed to realloc buf size %d -> %d at %s\n",
760*437bfbebSnyanmisaka str->buf_size, str->buf_size * 2, caller);
761*437bfbebSnyanmisaka return rk_nok;
762*437bfbebSnyanmisaka }
763*437bfbebSnyanmisaka
764*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] enlarger buffer to [%p:%d] at %s\n",
765*437bfbebSnyanmisaka str, str->buf, str->buf_size, ptr, str->buf_size * 2, caller);
766*437bfbebSnyanmisaka
767*437bfbebSnyanmisaka str->buf = ptr;
768*437bfbebSnyanmisaka str->buf_size *= 2;
769*437bfbebSnyanmisaka }
770*437bfbebSnyanmisaka
771*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] write offset %d from [%p:%d] at %s\n",
772*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->offset, buf, len, caller);
773*437bfbebSnyanmisaka
774*437bfbebSnyanmisaka memcpy(str->buf + str->offset, buf, len);
775*437bfbebSnyanmisaka str->offset += len;
776*437bfbebSnyanmisaka str->buf[str->offset] = '\0';
777*437bfbebSnyanmisaka size[0] = 0;
778*437bfbebSnyanmisaka
779*437bfbebSnyanmisaka return rk_ok;
780*437bfbebSnyanmisaka }
781*437bfbebSnyanmisaka
write_indent(MppCfgStrBuf * str,const char * caller)782*437bfbebSnyanmisaka static rk_s32 write_indent(MppCfgStrBuf *str, const char *caller)
783*437bfbebSnyanmisaka {
784*437bfbebSnyanmisaka rk_s32 depth;
785*437bfbebSnyanmisaka
786*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] write indent %d at %s\n",
787*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->depth, caller);
788*437bfbebSnyanmisaka
789*437bfbebSnyanmisaka depth = str->depth;
790*437bfbebSnyanmisaka if (str->type == MPP_CFG_STR_FMT_TOML) {
791*437bfbebSnyanmisaka depth = depth - 1;
792*437bfbebSnyanmisaka depth = depth >= 0 ? depth : 0;
793*437bfbebSnyanmisaka }
794*437bfbebSnyanmisaka
795*437bfbebSnyanmisaka if (depth) {
796*437bfbebSnyanmisaka char space[17] = " ";
797*437bfbebSnyanmisaka rk_s32 i;
798*437bfbebSnyanmisaka
799*437bfbebSnyanmisaka for (i = 0; i < depth; i++) {
800*437bfbebSnyanmisaka rk_s32 indent_width = 4;
801*437bfbebSnyanmisaka
802*437bfbebSnyanmisaka if (write_byte_f(str, space, &indent_width))
803*437bfbebSnyanmisaka return rk_nok;
804*437bfbebSnyanmisaka }
805*437bfbebSnyanmisaka }
806*437bfbebSnyanmisaka
807*437bfbebSnyanmisaka return rk_ok;
808*437bfbebSnyanmisaka }
809*437bfbebSnyanmisaka
revert_comma(MppCfgStrBuf * str,const char * caller)810*437bfbebSnyanmisaka static rk_s32 revert_comma(MppCfgStrBuf *str, const char *caller)
811*437bfbebSnyanmisaka {
812*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p-[%p:%d] revert_comma %d at %s\n",
813*437bfbebSnyanmisaka str, str->buf, str->buf_size, str->depth, caller);
814*437bfbebSnyanmisaka
815*437bfbebSnyanmisaka if (str->offset <= 1) {
816*437bfbebSnyanmisaka cfg_io_dbg_byte("str %p offset %d skip revert_comma at %s\n",
817*437bfbebSnyanmisaka str, str->offset, caller);
818*437bfbebSnyanmisaka return rk_ok;
819*437bfbebSnyanmisaka }
820*437bfbebSnyanmisaka
821*437bfbebSnyanmisaka if (str->buf[str->offset - 2] == ',') {
822*437bfbebSnyanmisaka str->buf[str->offset - 2] = str->buf[str->offset - 1];
823*437bfbebSnyanmisaka str->buf[str->offset - 1] = str->buf[str->offset];
824*437bfbebSnyanmisaka str->offset--;
825*437bfbebSnyanmisaka }
826*437bfbebSnyanmisaka
827*437bfbebSnyanmisaka return rk_ok;
828*437bfbebSnyanmisaka }
829*437bfbebSnyanmisaka
mpp_cfg_to_log(MppCfgIoImpl * impl,MppCfgStrBuf * str)830*437bfbebSnyanmisaka static rk_s32 mpp_cfg_to_log(MppCfgIoImpl *impl, MppCfgStrBuf *str)
831*437bfbebSnyanmisaka {
832*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
833*437bfbebSnyanmisaka char buf[256];
834*437bfbebSnyanmisaka rk_s32 len = 0;
835*437bfbebSnyanmisaka rk_s32 total = sizeof(buf) - 1;
836*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
837*437bfbebSnyanmisaka
838*437bfbebSnyanmisaka write_indent_f(str);
839*437bfbebSnyanmisaka
840*437bfbebSnyanmisaka /* leaf node write once and finish */
841*437bfbebSnyanmisaka if (impl->type < MPP_CFG_TYPE_OBJECT) {
842*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d leaf write name %s type %d\n", str->depth, impl->name, impl->type);
843*437bfbebSnyanmisaka
844*437bfbebSnyanmisaka if (impl->name)
845*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s : ", impl->name);
846*437bfbebSnyanmisaka
847*437bfbebSnyanmisaka switch (impl->type) {
848*437bfbebSnyanmisaka case MPP_CFG_TYPE_NULL : {
849*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "null\n");
850*437bfbebSnyanmisaka } break;
851*437bfbebSnyanmisaka case MPP_CFG_TYPE_BOOL : {
852*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s\n", impl->val.b1 ? "true" : "false");
853*437bfbebSnyanmisaka } break;
854*437bfbebSnyanmisaka case MPP_CFG_TYPE_s32 : {
855*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%d\n", impl->val.s32);
856*437bfbebSnyanmisaka } break;
857*437bfbebSnyanmisaka case MPP_CFG_TYPE_u32 : {
858*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%u\n", impl->val.u32);
859*437bfbebSnyanmisaka } break;
860*437bfbebSnyanmisaka case MPP_CFG_TYPE_s64 : {
861*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%lld\n", impl->val.s64);
862*437bfbebSnyanmisaka } break;
863*437bfbebSnyanmisaka case MPP_CFG_TYPE_u64 : {
864*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%llu\n", impl->val.u64);
865*437bfbebSnyanmisaka } break;
866*437bfbebSnyanmisaka case MPP_CFG_TYPE_f32 : {
867*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%f\n", impl->val.f32);
868*437bfbebSnyanmisaka } break;
869*437bfbebSnyanmisaka case MPP_CFG_TYPE_f64 : {
870*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%lf\n", impl->val.f64);
871*437bfbebSnyanmisaka } break;
872*437bfbebSnyanmisaka case MPP_CFG_TYPE_STRING :
873*437bfbebSnyanmisaka case MPP_CFG_TYPE_RAW : {
874*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\"%s\"\n", (char *)impl->val.str);
875*437bfbebSnyanmisaka } break;
876*437bfbebSnyanmisaka default : {
877*437bfbebSnyanmisaka mpp_loge("invalid type %d\n", impl->type);
878*437bfbebSnyanmisaka } break;
879*437bfbebSnyanmisaka }
880*437bfbebSnyanmisaka
881*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
882*437bfbebSnyanmisaka }
883*437bfbebSnyanmisaka
884*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d branch write name %s type %d\n", str->depth, impl->name, impl->type);
885*437bfbebSnyanmisaka
886*437bfbebSnyanmisaka if (impl->name)
887*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s : ", impl->name);
888*437bfbebSnyanmisaka
889*437bfbebSnyanmisaka if (list_empty(&impl->child)) {
890*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s\n",
891*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? "{}" : "[]");
892*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
893*437bfbebSnyanmisaka }
894*437bfbebSnyanmisaka
895*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c\n",
896*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '{' : '[');
897*437bfbebSnyanmisaka
898*437bfbebSnyanmisaka ret = write_byte_f(str, buf, &len);
899*437bfbebSnyanmisaka if (ret)
900*437bfbebSnyanmisaka return ret;
901*437bfbebSnyanmisaka
902*437bfbebSnyanmisaka str->depth++;
903*437bfbebSnyanmisaka
904*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
905*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d child write name %s type %d\n", str->depth, pos->name, pos->type);
906*437bfbebSnyanmisaka ret = mpp_cfg_to_log(pos, str);
907*437bfbebSnyanmisaka if (ret)
908*437bfbebSnyanmisaka break;
909*437bfbebSnyanmisaka }
910*437bfbebSnyanmisaka
911*437bfbebSnyanmisaka str->depth--;
912*437bfbebSnyanmisaka
913*437bfbebSnyanmisaka write_indent_f(str);
914*437bfbebSnyanmisaka
915*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c\n",
916*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '}' : ']');
917*437bfbebSnyanmisaka
918*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
919*437bfbebSnyanmisaka }
920*437bfbebSnyanmisaka
mpp_cfg_to_json(MppCfgIoImpl * impl,MppCfgStrBuf * str)921*437bfbebSnyanmisaka static rk_s32 mpp_cfg_to_json(MppCfgIoImpl *impl, MppCfgStrBuf *str)
922*437bfbebSnyanmisaka {
923*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
924*437bfbebSnyanmisaka char buf[256];
925*437bfbebSnyanmisaka rk_s32 len = 0;
926*437bfbebSnyanmisaka rk_s32 total = sizeof(buf) - 1;
927*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
928*437bfbebSnyanmisaka
929*437bfbebSnyanmisaka write_indent_f(str);
930*437bfbebSnyanmisaka
931*437bfbebSnyanmisaka /* leaf node write once and finish */
932*437bfbebSnyanmisaka if (impl->type < MPP_CFG_TYPE_OBJECT) {
933*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d leaf write name %s type %d\n", str->depth, impl->name, impl->type);
934*437bfbebSnyanmisaka
935*437bfbebSnyanmisaka if (impl->name)
936*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\"%s\" : ", impl->name);
937*437bfbebSnyanmisaka
938*437bfbebSnyanmisaka switch (impl->type) {
939*437bfbebSnyanmisaka case MPP_CFG_TYPE_NULL : {
940*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "null,\n");
941*437bfbebSnyanmisaka } break;
942*437bfbebSnyanmisaka case MPP_CFG_TYPE_BOOL : {
943*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s,\n", impl->val.b1 ? "true" : "false");
944*437bfbebSnyanmisaka } break;
945*437bfbebSnyanmisaka case MPP_CFG_TYPE_s32 : {
946*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%d,\n", impl->val.s32);
947*437bfbebSnyanmisaka } break;
948*437bfbebSnyanmisaka case MPP_CFG_TYPE_u32 : {
949*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%u,\n", impl->val.u32);
950*437bfbebSnyanmisaka } break;
951*437bfbebSnyanmisaka case MPP_CFG_TYPE_s64 : {
952*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%lld,\n", impl->val.s64);
953*437bfbebSnyanmisaka } break;
954*437bfbebSnyanmisaka case MPP_CFG_TYPE_u64 : {
955*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%llu,\n", impl->val.u64);
956*437bfbebSnyanmisaka } break;
957*437bfbebSnyanmisaka case MPP_CFG_TYPE_f32 : {
958*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%f,\n", impl->val.f32);
959*437bfbebSnyanmisaka } break;
960*437bfbebSnyanmisaka case MPP_CFG_TYPE_f64 : {
961*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%lf,\n", impl->val.f64);
962*437bfbebSnyanmisaka } break;
963*437bfbebSnyanmisaka case MPP_CFG_TYPE_STRING :
964*437bfbebSnyanmisaka case MPP_CFG_TYPE_RAW : {
965*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\"%s\",\n", (char *)impl->val.str);
966*437bfbebSnyanmisaka } break;
967*437bfbebSnyanmisaka default : {
968*437bfbebSnyanmisaka mpp_loge("invalid type %d\n", impl->type);
969*437bfbebSnyanmisaka } break;
970*437bfbebSnyanmisaka }
971*437bfbebSnyanmisaka
972*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
973*437bfbebSnyanmisaka }
974*437bfbebSnyanmisaka
975*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d branch write name %s type %d\n", str->depth, impl->name, impl->type);
976*437bfbebSnyanmisaka
977*437bfbebSnyanmisaka if (impl->name)
978*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\"%s\" : ", impl->name);
979*437bfbebSnyanmisaka
980*437bfbebSnyanmisaka if (list_empty(&impl->child)) {
981*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s,\n",
982*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? "{}" : "[]");
983*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
984*437bfbebSnyanmisaka }
985*437bfbebSnyanmisaka
986*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c\n",
987*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '{' : '[');
988*437bfbebSnyanmisaka
989*437bfbebSnyanmisaka ret = write_byte_f(str, buf, &len);
990*437bfbebSnyanmisaka if (ret)
991*437bfbebSnyanmisaka return ret;
992*437bfbebSnyanmisaka
993*437bfbebSnyanmisaka str->depth++;
994*437bfbebSnyanmisaka
995*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
996*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d child write name %s type %d\n", str->depth, pos->name, pos->type);
997*437bfbebSnyanmisaka ret = mpp_cfg_to_json(pos, str);
998*437bfbebSnyanmisaka if (ret)
999*437bfbebSnyanmisaka break;
1000*437bfbebSnyanmisaka }
1001*437bfbebSnyanmisaka
1002*437bfbebSnyanmisaka revert_comma_f(str);
1003*437bfbebSnyanmisaka
1004*437bfbebSnyanmisaka str->depth--;
1005*437bfbebSnyanmisaka
1006*437bfbebSnyanmisaka write_indent_f(str);
1007*437bfbebSnyanmisaka
1008*437bfbebSnyanmisaka if (str->depth)
1009*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c,\n",
1010*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '}' : ']');
1011*437bfbebSnyanmisaka else
1012*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c\n",
1013*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '}' : ']');
1014*437bfbebSnyanmisaka
1015*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
1016*437bfbebSnyanmisaka }
1017*437bfbebSnyanmisaka
mpp_toml_parent_is_array_table(MppCfgIoImpl * impl,MppCfgStrBuf * str)1018*437bfbebSnyanmisaka static rk_s32 mpp_toml_parent_is_array_table(MppCfgIoImpl *impl, MppCfgStrBuf *str)
1019*437bfbebSnyanmisaka {
1020*437bfbebSnyanmisaka return str->depth == 1 && impl->type == MPP_CFG_TYPE_OBJECT &&
1021*437bfbebSnyanmisaka !impl->name && impl->parent->type == MPP_CFG_TYPE_ARRAY;
1022*437bfbebSnyanmisaka }
1023*437bfbebSnyanmisaka
mpp_toml_top(MppCfgIoImpl * impl,MppCfgStrBuf * str)1024*437bfbebSnyanmisaka static rk_s32 mpp_toml_top(MppCfgIoImpl *impl, MppCfgStrBuf *str)
1025*437bfbebSnyanmisaka {
1026*437bfbebSnyanmisaka char buf[256];
1027*437bfbebSnyanmisaka rk_s32 len = 0;
1028*437bfbebSnyanmisaka rk_s32 total = sizeof(buf) - 1;
1029*437bfbebSnyanmisaka
1030*437bfbebSnyanmisaka if (impl->name && impl->type == MPP_CFG_TYPE_OBJECT)
1031*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\n[%s]\n", impl->name);
1032*437bfbebSnyanmisaka
1033*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
1034*437bfbebSnyanmisaka }
1035*437bfbebSnyanmisaka
mpp_toml_non_top(MppCfgIoImpl * impl,MppCfgStrBuf * str)1036*437bfbebSnyanmisaka static rk_s32 mpp_toml_non_top(MppCfgIoImpl *impl, MppCfgStrBuf *str)
1037*437bfbebSnyanmisaka {
1038*437bfbebSnyanmisaka char buf[256];
1039*437bfbebSnyanmisaka rk_s32 len = 0;
1040*437bfbebSnyanmisaka rk_s32 total = sizeof(buf) - 1;
1041*437bfbebSnyanmisaka
1042*437bfbebSnyanmisaka if (impl->name)
1043*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s = ", impl->name);
1044*437bfbebSnyanmisaka
1045*437bfbebSnyanmisaka if (list_empty(&impl->child)) {
1046*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s\n",
1047*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? "{}" : "[]");
1048*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
1049*437bfbebSnyanmisaka }
1050*437bfbebSnyanmisaka
1051*437bfbebSnyanmisaka if (mpp_toml_parent_is_array_table(impl, str))
1052*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\n[[%s]]\n", impl->parent->name);
1053*437bfbebSnyanmisaka else
1054*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c\n",
1055*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '{' : '[');
1056*437bfbebSnyanmisaka
1057*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
1058*437bfbebSnyanmisaka }
1059*437bfbebSnyanmisaka
mpp_cfg_to_toml(MppCfgIoImpl * impl,MppCfgStrBuf * str,rk_s32 first_time)1060*437bfbebSnyanmisaka static rk_s32 mpp_cfg_to_toml(MppCfgIoImpl *impl, MppCfgStrBuf *str, rk_s32 first_time)
1061*437bfbebSnyanmisaka {
1062*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
1063*437bfbebSnyanmisaka char buf[256];
1064*437bfbebSnyanmisaka rk_s32 len = 0;
1065*437bfbebSnyanmisaka rk_s32 total = sizeof(buf) - 1;
1066*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
1067*437bfbebSnyanmisaka
1068*437bfbebSnyanmisaka write_indent_f(str);
1069*437bfbebSnyanmisaka
1070*437bfbebSnyanmisaka /* leaf node write once and finish */
1071*437bfbebSnyanmisaka if (impl->type < MPP_CFG_TYPE_OBJECT) {
1072*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d leaf write name %s type %d\n", str->depth, impl->name, impl->type);
1073*437bfbebSnyanmisaka
1074*437bfbebSnyanmisaka if (impl->name)
1075*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s = ", impl->name);
1076*437bfbebSnyanmisaka
1077*437bfbebSnyanmisaka switch (impl->type) {
1078*437bfbebSnyanmisaka case MPP_CFG_TYPE_NULL : {
1079*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "null");
1080*437bfbebSnyanmisaka } break;
1081*437bfbebSnyanmisaka case MPP_CFG_TYPE_BOOL : {
1082*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%s", impl->val.b1 ? "true" : "false");
1083*437bfbebSnyanmisaka } break;
1084*437bfbebSnyanmisaka case MPP_CFG_TYPE_s32 : {
1085*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%d", impl->val.s32);
1086*437bfbebSnyanmisaka } break;
1087*437bfbebSnyanmisaka case MPP_CFG_TYPE_u32 : {
1088*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%u", impl->val.u32);
1089*437bfbebSnyanmisaka } break;
1090*437bfbebSnyanmisaka case MPP_CFG_TYPE_s64 : {
1091*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%lld", impl->val.s64);
1092*437bfbebSnyanmisaka } break;
1093*437bfbebSnyanmisaka case MPP_CFG_TYPE_u64 : {
1094*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%llu", impl->val.u64);
1095*437bfbebSnyanmisaka } break;
1096*437bfbebSnyanmisaka case MPP_CFG_TYPE_f32 : {
1097*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%f", impl->val.f32);
1098*437bfbebSnyanmisaka } break;
1099*437bfbebSnyanmisaka case MPP_CFG_TYPE_f64 : {
1100*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%lf", impl->val.f64);
1101*437bfbebSnyanmisaka } break;
1102*437bfbebSnyanmisaka case MPP_CFG_TYPE_STRING :
1103*437bfbebSnyanmisaka case MPP_CFG_TYPE_RAW : {
1104*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\"%s\"", (char *)impl->val.str);
1105*437bfbebSnyanmisaka } break;
1106*437bfbebSnyanmisaka default : {
1107*437bfbebSnyanmisaka mpp_loge("invalid type %d\n", impl->type);
1108*437bfbebSnyanmisaka } break;
1109*437bfbebSnyanmisaka }
1110*437bfbebSnyanmisaka
1111*437bfbebSnyanmisaka if (str->depth > 1)
1112*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, ",\n");
1113*437bfbebSnyanmisaka else
1114*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "\n");
1115*437bfbebSnyanmisaka
1116*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
1117*437bfbebSnyanmisaka }
1118*437bfbebSnyanmisaka
1119*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d branch write name %s type %d\n", str->depth, impl->name, impl->type);
1120*437bfbebSnyanmisaka
1121*437bfbebSnyanmisaka if (str->depth == 0) {
1122*437bfbebSnyanmisaka ret = mpp_toml_top(impl, str);
1123*437bfbebSnyanmisaka } else {
1124*437bfbebSnyanmisaka ret = mpp_toml_non_top(impl, str);
1125*437bfbebSnyanmisaka }
1126*437bfbebSnyanmisaka if (ret)
1127*437bfbebSnyanmisaka return ret;
1128*437bfbebSnyanmisaka
1129*437bfbebSnyanmisaka if (list_empty(&impl->child))
1130*437bfbebSnyanmisaka return rk_ok;
1131*437bfbebSnyanmisaka
1132*437bfbebSnyanmisaka if (!mpp_toml_parent_is_array_table(impl, str) && !first_time)
1133*437bfbebSnyanmisaka str->depth++;
1134*437bfbebSnyanmisaka
1135*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
1136*437bfbebSnyanmisaka cfg_io_dbg_to("depth %d child write name %s type %d\n", str->depth, pos->name, pos->type);
1137*437bfbebSnyanmisaka ret = mpp_cfg_to_toml(pos, str, 0);
1138*437bfbebSnyanmisaka if (ret)
1139*437bfbebSnyanmisaka break;
1140*437bfbebSnyanmisaka }
1141*437bfbebSnyanmisaka
1142*437bfbebSnyanmisaka if (str->depth > 1)
1143*437bfbebSnyanmisaka revert_comma_f(str);
1144*437bfbebSnyanmisaka
1145*437bfbebSnyanmisaka if (!mpp_toml_parent_is_array_table(impl, str) && !first_time)
1146*437bfbebSnyanmisaka str->depth--;
1147*437bfbebSnyanmisaka
1148*437bfbebSnyanmisaka write_indent_f(str);
1149*437bfbebSnyanmisaka
1150*437bfbebSnyanmisaka if (str->depth > 0 && !mpp_toml_parent_is_array_table(impl, str)) {
1151*437bfbebSnyanmisaka if (str->depth == 1)
1152*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c\n",
1153*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '}' : ']');
1154*437bfbebSnyanmisaka else
1155*437bfbebSnyanmisaka len += snprintf(buf + len, total - len, "%c,\n",
1156*437bfbebSnyanmisaka impl->type == MPP_CFG_TYPE_OBJECT ? '}' : ']');
1157*437bfbebSnyanmisaka }
1158*437bfbebSnyanmisaka
1159*437bfbebSnyanmisaka return write_byte_f(str, buf, &len);
1160*437bfbebSnyanmisaka }
1161*437bfbebSnyanmisaka
parse_number(MppCfgStrBuf * str,MppCfgType * type,MppCfgVal * val)1162*437bfbebSnyanmisaka static rk_s32 parse_number(MppCfgStrBuf *str, MppCfgType *type, MppCfgVal *val)
1163*437bfbebSnyanmisaka {
1164*437bfbebSnyanmisaka char *buf = NULL;
1165*437bfbebSnyanmisaka char tmp[64];
1166*437bfbebSnyanmisaka long double value;
1167*437bfbebSnyanmisaka rk_u32 i;
1168*437bfbebSnyanmisaka
1169*437bfbebSnyanmisaka for (i = 0; i < sizeof(tmp) - 1; i++) {
1170*437bfbebSnyanmisaka buf = show_byte_f(str, 0);
1171*437bfbebSnyanmisaka if (!buf)
1172*437bfbebSnyanmisaka break;
1173*437bfbebSnyanmisaka
1174*437bfbebSnyanmisaka switch (buf[0]) {
1175*437bfbebSnyanmisaka case '0' ... '9' :
1176*437bfbebSnyanmisaka case '.' :
1177*437bfbebSnyanmisaka case 'e' :
1178*437bfbebSnyanmisaka case 'E' :
1179*437bfbebSnyanmisaka case '+' :
1180*437bfbebSnyanmisaka case '-' : {
1181*437bfbebSnyanmisaka tmp[i] = buf[0];
1182*437bfbebSnyanmisaka } break;
1183*437bfbebSnyanmisaka default : {
1184*437bfbebSnyanmisaka tmp[i] = '\0';
1185*437bfbebSnyanmisaka goto done;
1186*437bfbebSnyanmisaka } break;
1187*437bfbebSnyanmisaka }
1188*437bfbebSnyanmisaka skip_byte_f(str, 1);
1189*437bfbebSnyanmisaka }
1190*437bfbebSnyanmisaka
1191*437bfbebSnyanmisaka done:
1192*437bfbebSnyanmisaka if (!i)
1193*437bfbebSnyanmisaka return rk_nok;
1194*437bfbebSnyanmisaka
1195*437bfbebSnyanmisaka errno = 0;
1196*437bfbebSnyanmisaka value = strtold(tmp, NULL);
1197*437bfbebSnyanmisaka if (errno) {
1198*437bfbebSnyanmisaka mpp_loge_f("failed to parse number %s errno %s\n", tmp, strerror(errno));
1199*437bfbebSnyanmisaka return rk_nok;
1200*437bfbebSnyanmisaka }
1201*437bfbebSnyanmisaka
1202*437bfbebSnyanmisaka if (strstr(tmp, ".")) {
1203*437bfbebSnyanmisaka if (value >= FLT_MIN && value <= FLT_MAX) {
1204*437bfbebSnyanmisaka *type = MPP_CFG_TYPE_f32;
1205*437bfbebSnyanmisaka val->f32 = (float)value;
1206*437bfbebSnyanmisaka } else {
1207*437bfbebSnyanmisaka *type = MPP_CFG_TYPE_f64;
1208*437bfbebSnyanmisaka val->f64 = (double)value;
1209*437bfbebSnyanmisaka }
1210*437bfbebSnyanmisaka } else {
1211*437bfbebSnyanmisaka if (value >= INT_MIN && value <= INT_MAX) {
1212*437bfbebSnyanmisaka *type = MPP_CFG_TYPE_s32;
1213*437bfbebSnyanmisaka val->s32 = (int)value;
1214*437bfbebSnyanmisaka } else if (value >= 0 && value <= UINT_MAX) {
1215*437bfbebSnyanmisaka *type = MPP_CFG_TYPE_u32;
1216*437bfbebSnyanmisaka val->u32 = (unsigned int)value;
1217*437bfbebSnyanmisaka } else if (value >= (long double)LLONG_MIN && value <= (long double)LLONG_MAX) {
1218*437bfbebSnyanmisaka *type = MPP_CFG_TYPE_u64;
1219*437bfbebSnyanmisaka val->u64 = (unsigned long long)value;
1220*437bfbebSnyanmisaka } else if (value >= 0 && value <= (long double)ULLONG_MAX) {
1221*437bfbebSnyanmisaka *type = MPP_CFG_TYPE_s64;
1222*437bfbebSnyanmisaka val->s64 = (long long)value;
1223*437bfbebSnyanmisaka } else {
1224*437bfbebSnyanmisaka mpp_loge_f("invalid number %s\n", tmp);
1225*437bfbebSnyanmisaka return rk_nok;
1226*437bfbebSnyanmisaka }
1227*437bfbebSnyanmisaka }
1228*437bfbebSnyanmisaka
1229*437bfbebSnyanmisaka return rk_ok;
1230*437bfbebSnyanmisaka }
1231*437bfbebSnyanmisaka
parse_log_string(MppCfgStrBuf * str,char ** name,rk_s32 * len,rk_u32 type)1232*437bfbebSnyanmisaka static rk_s32 parse_log_string(MppCfgStrBuf *str, char **name, rk_s32 *len, rk_u32 type)
1233*437bfbebSnyanmisaka {
1234*437bfbebSnyanmisaka char *buf = NULL;
1235*437bfbebSnyanmisaka char *start = NULL;
1236*437bfbebSnyanmisaka rk_s32 name_len = 0;
1237*437bfbebSnyanmisaka char terminator = type ? '\"' : ' ';
1238*437bfbebSnyanmisaka
1239*437bfbebSnyanmisaka *name = NULL;
1240*437bfbebSnyanmisaka *len = 0;
1241*437bfbebSnyanmisaka
1242*437bfbebSnyanmisaka /* skip whitespace and find first double quotes */
1243*437bfbebSnyanmisaka buf = skip_ws_f(str);
1244*437bfbebSnyanmisaka if (!buf)
1245*437bfbebSnyanmisaka return -101;
1246*437bfbebSnyanmisaka
1247*437bfbebSnyanmisaka if (type) {
1248*437bfbebSnyanmisaka if (buf[0] != '\"')
1249*437bfbebSnyanmisaka return -101;
1250*437bfbebSnyanmisaka
1251*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1252*437bfbebSnyanmisaka if (!buf)
1253*437bfbebSnyanmisaka return -102;
1254*437bfbebSnyanmisaka }
1255*437bfbebSnyanmisaka
1256*437bfbebSnyanmisaka start = buf;
1257*437bfbebSnyanmisaka
1258*437bfbebSnyanmisaka /* find the terminator */
1259*437bfbebSnyanmisaka while ((buf = show_byte_f(str, name_len)) && buf[0] != terminator) {
1260*437bfbebSnyanmisaka name_len++;
1261*437bfbebSnyanmisaka }
1262*437bfbebSnyanmisaka
1263*437bfbebSnyanmisaka if (!buf || buf[0] != terminator)
1264*437bfbebSnyanmisaka return -103;
1265*437bfbebSnyanmisaka
1266*437bfbebSnyanmisaka /* find complete string skip the string and terminator */
1267*437bfbebSnyanmisaka buf = skip_byte_f(str, name_len + 1);
1268*437bfbebSnyanmisaka if (!buf)
1269*437bfbebSnyanmisaka return -104;
1270*437bfbebSnyanmisaka
1271*437bfbebSnyanmisaka *name = start;
1272*437bfbebSnyanmisaka *len = name_len;
1273*437bfbebSnyanmisaka
1274*437bfbebSnyanmisaka return rk_ok;
1275*437bfbebSnyanmisaka }
1276*437bfbebSnyanmisaka
1277*437bfbebSnyanmisaka static rk_s32 parse_log_value(MppCfgIoImpl *parent, const char *name, MppCfgStrBuf *str);
1278*437bfbebSnyanmisaka
parse_log_array(MppCfgIoImpl * obj,MppCfgStrBuf * str)1279*437bfbebSnyanmisaka static rk_s32 parse_log_array(MppCfgIoImpl *obj, MppCfgStrBuf *str)
1280*437bfbebSnyanmisaka {
1281*437bfbebSnyanmisaka MppCfgIoImpl *parent = obj;
1282*437bfbebSnyanmisaka char *buf = NULL;
1283*437bfbebSnyanmisaka rk_s32 old = str->offset;
1284*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
1285*437bfbebSnyanmisaka
1286*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
1287*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
1288*437bfbebSnyanmisaka return rk_nok;
1289*437bfbebSnyanmisaka }
1290*437bfbebSnyanmisaka
1291*437bfbebSnyanmisaka str->depth++;
1292*437bfbebSnyanmisaka
1293*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d array parse start\n", str->depth, str->offset);
1294*437bfbebSnyanmisaka
1295*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
1296*437bfbebSnyanmisaka if (!buf || buf[0] != '[') {
1297*437bfbebSnyanmisaka ret = -2;
1298*437bfbebSnyanmisaka goto failed;
1299*437bfbebSnyanmisaka }
1300*437bfbebSnyanmisaka
1301*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1302*437bfbebSnyanmisaka if (!buf) {
1303*437bfbebSnyanmisaka ret = -3;
1304*437bfbebSnyanmisaka goto failed;
1305*437bfbebSnyanmisaka }
1306*437bfbebSnyanmisaka
1307*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
1308*437bfbebSnyanmisaka buf = skip_ws_f(str);
1309*437bfbebSnyanmisaka if (!buf) {
1310*437bfbebSnyanmisaka ret = -4;
1311*437bfbebSnyanmisaka goto failed;
1312*437bfbebSnyanmisaka }
1313*437bfbebSnyanmisaka
1314*437bfbebSnyanmisaka /* check empty object */
1315*437bfbebSnyanmisaka if (buf[0] == ']') {
1316*437bfbebSnyanmisaka skip_byte_f(str, 1);
1317*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d found empty array\n", str->depth);
1318*437bfbebSnyanmisaka str->depth--;
1319*437bfbebSnyanmisaka return rk_ok;
1320*437bfbebSnyanmisaka }
1321*437bfbebSnyanmisaka
1322*437bfbebSnyanmisaka do {
1323*437bfbebSnyanmisaka /* find colon for separater */
1324*437bfbebSnyanmisaka buf = skip_ws_f(str);
1325*437bfbebSnyanmisaka if (!buf) {
1326*437bfbebSnyanmisaka ret = -5;
1327*437bfbebSnyanmisaka goto failed;
1328*437bfbebSnyanmisaka }
1329*437bfbebSnyanmisaka
1330*437bfbebSnyanmisaka /* parse value */
1331*437bfbebSnyanmisaka ret = parse_log_value(parent, NULL, str);
1332*437bfbebSnyanmisaka if (ret) {
1333*437bfbebSnyanmisaka ret = -6;
1334*437bfbebSnyanmisaka goto failed;
1335*437bfbebSnyanmisaka }
1336*437bfbebSnyanmisaka
1337*437bfbebSnyanmisaka buf = skip_ws_f(str);
1338*437bfbebSnyanmisaka if (!buf) {
1339*437bfbebSnyanmisaka ret = -7;
1340*437bfbebSnyanmisaka goto failed;
1341*437bfbebSnyanmisaka }
1342*437bfbebSnyanmisaka
1343*437bfbebSnyanmisaka if (buf[0] == ']')
1344*437bfbebSnyanmisaka break;
1345*437bfbebSnyanmisaka } while (1);
1346*437bfbebSnyanmisaka
1347*437bfbebSnyanmisaka if (!buf || buf[0] != ']') {
1348*437bfbebSnyanmisaka ret = -9;
1349*437bfbebSnyanmisaka goto failed;
1350*437bfbebSnyanmisaka }
1351*437bfbebSnyanmisaka
1352*437bfbebSnyanmisaka skip_byte_f(str, 1);
1353*437bfbebSnyanmisaka
1354*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d array parse success\n",
1355*437bfbebSnyanmisaka str->depth, old, str->offset);
1356*437bfbebSnyanmisaka
1357*437bfbebSnyanmisaka str->depth--;
1358*437bfbebSnyanmisaka ret = rk_ok;
1359*437bfbebSnyanmisaka
1360*437bfbebSnyanmisaka failed:
1361*437bfbebSnyanmisaka if (ret)
1362*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d array parse failed ret %d\n",
1363*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
1364*437bfbebSnyanmisaka
1365*437bfbebSnyanmisaka return ret;
1366*437bfbebSnyanmisaka }
1367*437bfbebSnyanmisaka
1368*437bfbebSnyanmisaka static rk_s32 parse_log_object(MppCfgIoImpl *obj, MppCfgStrBuf *str);
1369*437bfbebSnyanmisaka
parse_log_value(MppCfgIoImpl * parent,const char * name,MppCfgStrBuf * str)1370*437bfbebSnyanmisaka static rk_s32 parse_log_value(MppCfgIoImpl *parent, const char *name, MppCfgStrBuf *str)
1371*437bfbebSnyanmisaka {
1372*437bfbebSnyanmisaka MppCfgObj obj = NULL;
1373*437bfbebSnyanmisaka char *buf = NULL;
1374*437bfbebSnyanmisaka
1375*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: parse value\n", str->depth, str->offset);
1376*437bfbebSnyanmisaka
1377*437bfbebSnyanmisaka buf = test_byte_f(str, 4);
1378*437bfbebSnyanmisaka if (buf && !strncmp(buf, "null", 4)) {
1379*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_NULL, NULL);
1380*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1381*437bfbebSnyanmisaka
1382*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value null\n", str->depth, str->offset);
1383*437bfbebSnyanmisaka skip_byte_f(str, 4);
1384*437bfbebSnyanmisaka return rk_ok;
1385*437bfbebSnyanmisaka }
1386*437bfbebSnyanmisaka
1387*437bfbebSnyanmisaka if (buf && !strncmp(buf, "true", 4)) {
1388*437bfbebSnyanmisaka MppCfgVal val;
1389*437bfbebSnyanmisaka
1390*437bfbebSnyanmisaka val.b1 = 1;
1391*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_BOOL, &val);
1392*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1393*437bfbebSnyanmisaka
1394*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value true\n", str->depth, str->offset);
1395*437bfbebSnyanmisaka skip_byte_f(str, 4);
1396*437bfbebSnyanmisaka return rk_ok;
1397*437bfbebSnyanmisaka }
1398*437bfbebSnyanmisaka
1399*437bfbebSnyanmisaka buf = test_byte_f(str, 5);
1400*437bfbebSnyanmisaka if (buf && !strncmp(buf, "false", 5)) {
1401*437bfbebSnyanmisaka MppCfgVal val;
1402*437bfbebSnyanmisaka
1403*437bfbebSnyanmisaka val.b1 = 0;
1404*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_BOOL, &val);
1405*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1406*437bfbebSnyanmisaka
1407*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value false\n", str->depth, str->offset);
1408*437bfbebSnyanmisaka skip_byte_f(str, 5);
1409*437bfbebSnyanmisaka return rk_ok;
1410*437bfbebSnyanmisaka }
1411*437bfbebSnyanmisaka
1412*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
1413*437bfbebSnyanmisaka if (buf && buf[0] == '\"') {
1414*437bfbebSnyanmisaka MppCfgVal val;
1415*437bfbebSnyanmisaka char *string = NULL;
1416*437bfbebSnyanmisaka rk_s32 len = 0;
1417*437bfbebSnyanmisaka
1418*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value string start\n", str->depth, str->offset);
1419*437bfbebSnyanmisaka
1420*437bfbebSnyanmisaka parse_log_string(str, &string, &len, MPP_CFG_PARSER_TYPE_VALUE);
1421*437bfbebSnyanmisaka if (!string)
1422*437bfbebSnyanmisaka return rk_nok;
1423*437bfbebSnyanmisaka
1424*437bfbebSnyanmisaka val.str = dup_str(string, len);
1425*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_STRING, &val);
1426*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1427*437bfbebSnyanmisaka MPP_FREE(val.str);
1428*437bfbebSnyanmisaka
1429*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value string success\n", str->depth, str->offset);
1430*437bfbebSnyanmisaka return rk_ok;
1431*437bfbebSnyanmisaka }
1432*437bfbebSnyanmisaka
1433*437bfbebSnyanmisaka if (buf && (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9'))) {
1434*437bfbebSnyanmisaka MppCfgType type;
1435*437bfbebSnyanmisaka MppCfgVal val;
1436*437bfbebSnyanmisaka rk_s32 ret;
1437*437bfbebSnyanmisaka
1438*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value number start\n",
1439*437bfbebSnyanmisaka str->depth, str->offset);
1440*437bfbebSnyanmisaka
1441*437bfbebSnyanmisaka ret = parse_number(str, &type, &val);
1442*437bfbebSnyanmisaka if (ret)
1443*437bfbebSnyanmisaka return ret;
1444*437bfbebSnyanmisaka
1445*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, type, &val);
1446*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1447*437bfbebSnyanmisaka
1448*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value number success\n",
1449*437bfbebSnyanmisaka str->depth, str->offset);
1450*437bfbebSnyanmisaka return ret;
1451*437bfbebSnyanmisaka }
1452*437bfbebSnyanmisaka
1453*437bfbebSnyanmisaka if (buf && buf[0] == '{') {
1454*437bfbebSnyanmisaka rk_s32 ret;
1455*437bfbebSnyanmisaka
1456*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value object start\n",
1457*437bfbebSnyanmisaka str->depth, str->offset);
1458*437bfbebSnyanmisaka
1459*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_OBJECT, NULL);
1460*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1461*437bfbebSnyanmisaka
1462*437bfbebSnyanmisaka ret = parse_log_object(obj, str);
1463*437bfbebSnyanmisaka
1464*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value object ret %d\n",
1465*437bfbebSnyanmisaka str->depth, str->offset, ret);
1466*437bfbebSnyanmisaka return ret;
1467*437bfbebSnyanmisaka }
1468*437bfbebSnyanmisaka
1469*437bfbebSnyanmisaka if (buf && buf[0] == '[') {
1470*437bfbebSnyanmisaka rk_s32 ret;
1471*437bfbebSnyanmisaka
1472*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array start\n",
1473*437bfbebSnyanmisaka str->depth, str->offset);
1474*437bfbebSnyanmisaka
1475*437bfbebSnyanmisaka mpp_cfg_get_array(&obj, name, 0);
1476*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1477*437bfbebSnyanmisaka
1478*437bfbebSnyanmisaka ret = parse_log_array(obj, str);
1479*437bfbebSnyanmisaka
1480*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array ret %d\n",
1481*437bfbebSnyanmisaka str->depth, str->offset, ret);
1482*437bfbebSnyanmisaka return ret;
1483*437bfbebSnyanmisaka }
1484*437bfbebSnyanmisaka
1485*437bfbebSnyanmisaka return rk_nok;
1486*437bfbebSnyanmisaka }
1487*437bfbebSnyanmisaka
parse_log_object(MppCfgIoImpl * obj,MppCfgStrBuf * str)1488*437bfbebSnyanmisaka static rk_s32 parse_log_object(MppCfgIoImpl *obj, MppCfgStrBuf *str)
1489*437bfbebSnyanmisaka {
1490*437bfbebSnyanmisaka MppCfgIoImpl *parent = obj;
1491*437bfbebSnyanmisaka char *buf = NULL;
1492*437bfbebSnyanmisaka rk_s32 old = str->offset;
1493*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
1494*437bfbebSnyanmisaka
1495*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
1496*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
1497*437bfbebSnyanmisaka return rk_nok;
1498*437bfbebSnyanmisaka }
1499*437bfbebSnyanmisaka
1500*437bfbebSnyanmisaka str->depth++;
1501*437bfbebSnyanmisaka
1502*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d object parse start\n", str->depth, str->offset);
1503*437bfbebSnyanmisaka
1504*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
1505*437bfbebSnyanmisaka if (!buf || buf[0] != '{') {
1506*437bfbebSnyanmisaka ret = -2;
1507*437bfbebSnyanmisaka goto failed;
1508*437bfbebSnyanmisaka }
1509*437bfbebSnyanmisaka
1510*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1511*437bfbebSnyanmisaka if (!buf) {
1512*437bfbebSnyanmisaka ret = -3;
1513*437bfbebSnyanmisaka goto failed;
1514*437bfbebSnyanmisaka }
1515*437bfbebSnyanmisaka
1516*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
1517*437bfbebSnyanmisaka buf = skip_ws_f(str);
1518*437bfbebSnyanmisaka if (!buf) {
1519*437bfbebSnyanmisaka ret = -4;
1520*437bfbebSnyanmisaka goto failed;
1521*437bfbebSnyanmisaka }
1522*437bfbebSnyanmisaka
1523*437bfbebSnyanmisaka /* check empty object */
1524*437bfbebSnyanmisaka if (buf[0] == '}') {
1525*437bfbebSnyanmisaka skip_byte_f(str, 1);
1526*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d found empty object\n", str->depth);
1527*437bfbebSnyanmisaka str->depth--;
1528*437bfbebSnyanmisaka return rk_ok;
1529*437bfbebSnyanmisaka }
1530*437bfbebSnyanmisaka
1531*437bfbebSnyanmisaka do {
1532*437bfbebSnyanmisaka rk_s32 name_len = 0;
1533*437bfbebSnyanmisaka char *name = NULL;
1534*437bfbebSnyanmisaka char *tmp = NULL;
1535*437bfbebSnyanmisaka
1536*437bfbebSnyanmisaka /* support array without name */
1537*437bfbebSnyanmisaka if (buf[0] == '[') {
1538*437bfbebSnyanmisaka MppCfgObj object = NULL;
1539*437bfbebSnyanmisaka
1540*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array start\n",
1541*437bfbebSnyanmisaka str->depth, str->offset);
1542*437bfbebSnyanmisaka
1543*437bfbebSnyanmisaka mpp_cfg_get_array(&object, NULL, 0);
1544*437bfbebSnyanmisaka mpp_cfg_add(parent, object);
1545*437bfbebSnyanmisaka
1546*437bfbebSnyanmisaka ret = parse_log_array(object, str);
1547*437bfbebSnyanmisaka
1548*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array ret %d\n",
1549*437bfbebSnyanmisaka str->depth, str->offset, ret);
1550*437bfbebSnyanmisaka
1551*437bfbebSnyanmisaka if (ret) {
1552*437bfbebSnyanmisaka mpp_cfg_put_all_child(object);
1553*437bfbebSnyanmisaka goto failed;
1554*437bfbebSnyanmisaka }
1555*437bfbebSnyanmisaka
1556*437bfbebSnyanmisaka goto __next;
1557*437bfbebSnyanmisaka }
1558*437bfbebSnyanmisaka
1559*437bfbebSnyanmisaka ret = parse_log_string(str, &name, &name_len, MPP_CFG_PARSER_TYPE_KEY);
1560*437bfbebSnyanmisaka if (ret) {
1561*437bfbebSnyanmisaka goto failed;
1562*437bfbebSnyanmisaka }
1563*437bfbebSnyanmisaka
1564*437bfbebSnyanmisaka tmp = dup_str(name, name_len);
1565*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d found object key %s len %d\n",
1566*437bfbebSnyanmisaka str->depth, str->offset, tmp, name_len);
1567*437bfbebSnyanmisaka MPP_FREE(tmp);
1568*437bfbebSnyanmisaka
1569*437bfbebSnyanmisaka /* find colon for separater */
1570*437bfbebSnyanmisaka buf = skip_ws_f(str);
1571*437bfbebSnyanmisaka if (!buf || buf[0] != ':') {
1572*437bfbebSnyanmisaka ret = -5;
1573*437bfbebSnyanmisaka goto failed;
1574*437bfbebSnyanmisaka }
1575*437bfbebSnyanmisaka
1576*437bfbebSnyanmisaka /* skip colon */
1577*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1578*437bfbebSnyanmisaka if (!buf) {
1579*437bfbebSnyanmisaka ret = -6;
1580*437bfbebSnyanmisaka goto failed;
1581*437bfbebSnyanmisaka }
1582*437bfbebSnyanmisaka
1583*437bfbebSnyanmisaka buf = skip_ws_f(str);
1584*437bfbebSnyanmisaka if (!buf) {
1585*437bfbebSnyanmisaka ret = -7;
1586*437bfbebSnyanmisaka goto failed;
1587*437bfbebSnyanmisaka }
1588*437bfbebSnyanmisaka
1589*437bfbebSnyanmisaka tmp = dup_str(name, name_len);
1590*437bfbebSnyanmisaka if (!tmp) {
1591*437bfbebSnyanmisaka mpp_loge_f("failed to dup name\n");
1592*437bfbebSnyanmisaka ret = -8;
1593*437bfbebSnyanmisaka goto failed;
1594*437bfbebSnyanmisaka }
1595*437bfbebSnyanmisaka
1596*437bfbebSnyanmisaka /* parse value */
1597*437bfbebSnyanmisaka ret = parse_log_value(parent, tmp, str);
1598*437bfbebSnyanmisaka MPP_FREE(tmp);
1599*437bfbebSnyanmisaka if (ret) {
1600*437bfbebSnyanmisaka ret = -9;
1601*437bfbebSnyanmisaka goto failed;
1602*437bfbebSnyanmisaka }
1603*437bfbebSnyanmisaka __next:
1604*437bfbebSnyanmisaka buf = skip_ws_f(str);
1605*437bfbebSnyanmisaka if (!buf) {
1606*437bfbebSnyanmisaka ret = -10;
1607*437bfbebSnyanmisaka goto failed;
1608*437bfbebSnyanmisaka }
1609*437bfbebSnyanmisaka
1610*437bfbebSnyanmisaka if (buf[0] == '}')
1611*437bfbebSnyanmisaka break;
1612*437bfbebSnyanmisaka
1613*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get next object\n", str->depth, str->offset);
1614*437bfbebSnyanmisaka } while (1);
1615*437bfbebSnyanmisaka
1616*437bfbebSnyanmisaka skip_byte_f(str, 1);
1617*437bfbebSnyanmisaka
1618*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d object parse success\n",
1619*437bfbebSnyanmisaka str->depth, old, str->offset);
1620*437bfbebSnyanmisaka
1621*437bfbebSnyanmisaka str->depth--;
1622*437bfbebSnyanmisaka ret = rk_ok;
1623*437bfbebSnyanmisaka
1624*437bfbebSnyanmisaka failed:
1625*437bfbebSnyanmisaka if (ret)
1626*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d object parse failed ret %d\n",
1627*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
1628*437bfbebSnyanmisaka
1629*437bfbebSnyanmisaka return ret;
1630*437bfbebSnyanmisaka }
1631*437bfbebSnyanmisaka
mpp_cfg_from_log(MppCfgObj * obj,MppCfgStrBuf * str)1632*437bfbebSnyanmisaka static rk_s32 mpp_cfg_from_log(MppCfgObj *obj, MppCfgStrBuf *str)
1633*437bfbebSnyanmisaka {
1634*437bfbebSnyanmisaka MppCfgObj object = NULL;
1635*437bfbebSnyanmisaka char *buf = NULL;
1636*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
1637*437bfbebSnyanmisaka
1638*437bfbebSnyanmisaka /* skip white space and check the end of buffer */
1639*437bfbebSnyanmisaka buf = skip_ws_f(str);
1640*437bfbebSnyanmisaka if (!buf)
1641*437bfbebSnyanmisaka return rk_nok;
1642*437bfbebSnyanmisaka
1643*437bfbebSnyanmisaka if (buf[0] == '{') {
1644*437bfbebSnyanmisaka ret = mpp_cfg_get_object(&object, NULL, MPP_CFG_TYPE_OBJECT, NULL);
1645*437bfbebSnyanmisaka if (ret || !object) {
1646*437bfbebSnyanmisaka mpp_loge_f("failed to create top object\n");
1647*437bfbebSnyanmisaka return rk_nok;
1648*437bfbebSnyanmisaka }
1649*437bfbebSnyanmisaka
1650*437bfbebSnyanmisaka ret = parse_log_object(object, str);
1651*437bfbebSnyanmisaka } else if (buf[0] == '[') {
1652*437bfbebSnyanmisaka ret = mpp_cfg_get_array(&object, NULL, 0);
1653*437bfbebSnyanmisaka if (ret || !object) {
1654*437bfbebSnyanmisaka mpp_loge_f("failed to create top object\n");
1655*437bfbebSnyanmisaka return rk_nok;
1656*437bfbebSnyanmisaka }
1657*437bfbebSnyanmisaka
1658*437bfbebSnyanmisaka ret = parse_log_array(object, str);
1659*437bfbebSnyanmisaka } else {
1660*437bfbebSnyanmisaka mpp_loge_f("invalid top element '%c' on offset %d\n", buf[0], str->offset);
1661*437bfbebSnyanmisaka }
1662*437bfbebSnyanmisaka
1663*437bfbebSnyanmisaka *obj = object;
1664*437bfbebSnyanmisaka
1665*437bfbebSnyanmisaka return ret;
1666*437bfbebSnyanmisaka }
1667*437bfbebSnyanmisaka
parse_json_string(MppCfgStrBuf * str,char ** name,rk_s32 * len)1668*437bfbebSnyanmisaka static rk_s32 parse_json_string(MppCfgStrBuf *str, char **name, rk_s32 *len)
1669*437bfbebSnyanmisaka {
1670*437bfbebSnyanmisaka char *buf = NULL;
1671*437bfbebSnyanmisaka char *start = NULL;
1672*437bfbebSnyanmisaka rk_s32 name_len = 0;
1673*437bfbebSnyanmisaka
1674*437bfbebSnyanmisaka *name = NULL;
1675*437bfbebSnyanmisaka *len = 0;
1676*437bfbebSnyanmisaka
1677*437bfbebSnyanmisaka /* skip whitespace and find first double quotes */
1678*437bfbebSnyanmisaka buf = skip_ws_f(str);
1679*437bfbebSnyanmisaka if (!buf || buf[0] != '\"')
1680*437bfbebSnyanmisaka return -101;
1681*437bfbebSnyanmisaka
1682*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1683*437bfbebSnyanmisaka if (!buf)
1684*437bfbebSnyanmisaka return -102;
1685*437bfbebSnyanmisaka
1686*437bfbebSnyanmisaka start = buf;
1687*437bfbebSnyanmisaka
1688*437bfbebSnyanmisaka /* find the last double quotes */
1689*437bfbebSnyanmisaka while ((buf = show_byte_f(str, name_len)) && buf[0] != '\"') {
1690*437bfbebSnyanmisaka name_len++;
1691*437bfbebSnyanmisaka }
1692*437bfbebSnyanmisaka
1693*437bfbebSnyanmisaka if (!buf || buf[0] != '\"')
1694*437bfbebSnyanmisaka return -103;
1695*437bfbebSnyanmisaka
1696*437bfbebSnyanmisaka /* find complete string skip the string and double quotes */
1697*437bfbebSnyanmisaka buf = skip_byte_f(str, name_len + 1);
1698*437bfbebSnyanmisaka if (!buf)
1699*437bfbebSnyanmisaka return -104;
1700*437bfbebSnyanmisaka
1701*437bfbebSnyanmisaka *name = start;
1702*437bfbebSnyanmisaka *len = name_len;
1703*437bfbebSnyanmisaka
1704*437bfbebSnyanmisaka return rk_ok;
1705*437bfbebSnyanmisaka }
1706*437bfbebSnyanmisaka
1707*437bfbebSnyanmisaka static rk_s32 parse_json_value(MppCfgIoImpl *parent, const char *name, MppCfgStrBuf *str);
1708*437bfbebSnyanmisaka static rk_s32 parse_json_array(MppCfgIoImpl *obj, MppCfgStrBuf *str);
1709*437bfbebSnyanmisaka
parse_json_object(MppCfgIoImpl * obj,MppCfgStrBuf * str)1710*437bfbebSnyanmisaka static rk_s32 parse_json_object(MppCfgIoImpl *obj, MppCfgStrBuf *str)
1711*437bfbebSnyanmisaka {
1712*437bfbebSnyanmisaka MppCfgIoImpl *parent = obj;
1713*437bfbebSnyanmisaka char *buf = NULL;
1714*437bfbebSnyanmisaka rk_s32 old = str->offset;
1715*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
1716*437bfbebSnyanmisaka
1717*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
1718*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
1719*437bfbebSnyanmisaka return rk_nok;
1720*437bfbebSnyanmisaka }
1721*437bfbebSnyanmisaka
1722*437bfbebSnyanmisaka str->depth++;
1723*437bfbebSnyanmisaka
1724*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d object parse start\n", str->depth, str->offset);
1725*437bfbebSnyanmisaka
1726*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
1727*437bfbebSnyanmisaka if (!buf || buf[0] != '{') {
1728*437bfbebSnyanmisaka ret = -2;
1729*437bfbebSnyanmisaka goto failed;
1730*437bfbebSnyanmisaka }
1731*437bfbebSnyanmisaka
1732*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1733*437bfbebSnyanmisaka if (!buf) {
1734*437bfbebSnyanmisaka ret = -3;
1735*437bfbebSnyanmisaka goto failed;
1736*437bfbebSnyanmisaka }
1737*437bfbebSnyanmisaka
1738*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
1739*437bfbebSnyanmisaka buf = skip_ws_f(str);
1740*437bfbebSnyanmisaka if (!buf) {
1741*437bfbebSnyanmisaka ret = -4;
1742*437bfbebSnyanmisaka goto failed;
1743*437bfbebSnyanmisaka }
1744*437bfbebSnyanmisaka
1745*437bfbebSnyanmisaka /* check empty object */
1746*437bfbebSnyanmisaka if (buf[0] == '}') {
1747*437bfbebSnyanmisaka skip_byte_f(str, 1);
1748*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d found empty object\n", str->depth);
1749*437bfbebSnyanmisaka str->depth--;
1750*437bfbebSnyanmisaka return rk_ok;
1751*437bfbebSnyanmisaka }
1752*437bfbebSnyanmisaka
1753*437bfbebSnyanmisaka do {
1754*437bfbebSnyanmisaka rk_s32 name_len = 0;
1755*437bfbebSnyanmisaka char *name = NULL;
1756*437bfbebSnyanmisaka char *tmp = NULL;
1757*437bfbebSnyanmisaka
1758*437bfbebSnyanmisaka if (buf[0] == '[') {
1759*437bfbebSnyanmisaka MppCfgObj object = NULL;
1760*437bfbebSnyanmisaka
1761*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array start\n",
1762*437bfbebSnyanmisaka str->depth, str->offset);
1763*437bfbebSnyanmisaka
1764*437bfbebSnyanmisaka mpp_cfg_get_array(&object, NULL, 0);
1765*437bfbebSnyanmisaka mpp_cfg_add(parent, object);
1766*437bfbebSnyanmisaka
1767*437bfbebSnyanmisaka ret = parse_json_array(object, str);
1768*437bfbebSnyanmisaka
1769*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array ret %d\n",
1770*437bfbebSnyanmisaka str->depth, str->offset, ret);
1771*437bfbebSnyanmisaka
1772*437bfbebSnyanmisaka if (ret) {
1773*437bfbebSnyanmisaka mpp_cfg_put_all_child(object);
1774*437bfbebSnyanmisaka goto failed;
1775*437bfbebSnyanmisaka }
1776*437bfbebSnyanmisaka
1777*437bfbebSnyanmisaka goto __next;
1778*437bfbebSnyanmisaka }
1779*437bfbebSnyanmisaka
1780*437bfbebSnyanmisaka ret = parse_json_string(str, &name, &name_len);
1781*437bfbebSnyanmisaka if (ret) {
1782*437bfbebSnyanmisaka goto failed;
1783*437bfbebSnyanmisaka }
1784*437bfbebSnyanmisaka
1785*437bfbebSnyanmisaka /* find colon for separater */
1786*437bfbebSnyanmisaka buf = skip_ws_f(str);
1787*437bfbebSnyanmisaka if (!buf || buf[0] != ':') {
1788*437bfbebSnyanmisaka ret = -5;
1789*437bfbebSnyanmisaka goto failed;
1790*437bfbebSnyanmisaka }
1791*437bfbebSnyanmisaka
1792*437bfbebSnyanmisaka /* skip colon */
1793*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1794*437bfbebSnyanmisaka if (!buf) {
1795*437bfbebSnyanmisaka ret = -6;
1796*437bfbebSnyanmisaka goto failed;
1797*437bfbebSnyanmisaka }
1798*437bfbebSnyanmisaka
1799*437bfbebSnyanmisaka buf = skip_ws_f(str);
1800*437bfbebSnyanmisaka if (!buf) {
1801*437bfbebSnyanmisaka ret = -7;
1802*437bfbebSnyanmisaka goto failed;
1803*437bfbebSnyanmisaka }
1804*437bfbebSnyanmisaka
1805*437bfbebSnyanmisaka tmp = dup_str(name, name_len);
1806*437bfbebSnyanmisaka if (!tmp) {
1807*437bfbebSnyanmisaka mpp_loge_f("failed to dup name\n");
1808*437bfbebSnyanmisaka ret = -8;
1809*437bfbebSnyanmisaka goto failed;
1810*437bfbebSnyanmisaka }
1811*437bfbebSnyanmisaka
1812*437bfbebSnyanmisaka /* parse value */
1813*437bfbebSnyanmisaka ret = parse_json_value(parent, tmp, str);
1814*437bfbebSnyanmisaka MPP_FREE(tmp);
1815*437bfbebSnyanmisaka if (ret) {
1816*437bfbebSnyanmisaka ret = -9;
1817*437bfbebSnyanmisaka goto failed;
1818*437bfbebSnyanmisaka }
1819*437bfbebSnyanmisaka __next:
1820*437bfbebSnyanmisaka buf = skip_ws_f(str);
1821*437bfbebSnyanmisaka if (!buf) {
1822*437bfbebSnyanmisaka ret = -10;
1823*437bfbebSnyanmisaka goto failed;
1824*437bfbebSnyanmisaka }
1825*437bfbebSnyanmisaka
1826*437bfbebSnyanmisaka if (buf[0] == ',') {
1827*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1828*437bfbebSnyanmisaka if (!buf) {
1829*437bfbebSnyanmisaka ret = -11;
1830*437bfbebSnyanmisaka goto failed;
1831*437bfbebSnyanmisaka }
1832*437bfbebSnyanmisaka
1833*437bfbebSnyanmisaka buf = skip_ws_f(str);
1834*437bfbebSnyanmisaka if (buf[0] == '}')
1835*437bfbebSnyanmisaka break;
1836*437bfbebSnyanmisaka
1837*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get next object\n", str->depth, str->offset);
1838*437bfbebSnyanmisaka continue;
1839*437bfbebSnyanmisaka }
1840*437bfbebSnyanmisaka
1841*437bfbebSnyanmisaka break;
1842*437bfbebSnyanmisaka } while (1);
1843*437bfbebSnyanmisaka
1844*437bfbebSnyanmisaka buf = skip_ws_f(str);
1845*437bfbebSnyanmisaka if (!buf || buf[0] != '}') {
1846*437bfbebSnyanmisaka ret = -12;
1847*437bfbebSnyanmisaka goto failed;
1848*437bfbebSnyanmisaka }
1849*437bfbebSnyanmisaka
1850*437bfbebSnyanmisaka skip_byte_f(str, 1);
1851*437bfbebSnyanmisaka
1852*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d object parse success\n",
1853*437bfbebSnyanmisaka str->depth, old, str->offset);
1854*437bfbebSnyanmisaka
1855*437bfbebSnyanmisaka str->depth--;
1856*437bfbebSnyanmisaka ret = rk_ok;
1857*437bfbebSnyanmisaka
1858*437bfbebSnyanmisaka failed:
1859*437bfbebSnyanmisaka if (ret)
1860*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d object parse failed ret %d\n",
1861*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
1862*437bfbebSnyanmisaka
1863*437bfbebSnyanmisaka return ret;
1864*437bfbebSnyanmisaka }
1865*437bfbebSnyanmisaka
parse_json_array(MppCfgIoImpl * obj,MppCfgStrBuf * str)1866*437bfbebSnyanmisaka static rk_s32 parse_json_array(MppCfgIoImpl *obj, MppCfgStrBuf *str)
1867*437bfbebSnyanmisaka {
1868*437bfbebSnyanmisaka MppCfgIoImpl *parent = obj;
1869*437bfbebSnyanmisaka char *buf = NULL;
1870*437bfbebSnyanmisaka rk_s32 old = str->offset;
1871*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
1872*437bfbebSnyanmisaka
1873*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
1874*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
1875*437bfbebSnyanmisaka return rk_nok;
1876*437bfbebSnyanmisaka }
1877*437bfbebSnyanmisaka
1878*437bfbebSnyanmisaka str->depth++;
1879*437bfbebSnyanmisaka
1880*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d array parse start\n", str->depth, str->offset);
1881*437bfbebSnyanmisaka
1882*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
1883*437bfbebSnyanmisaka if (!buf || buf[0] != '[') {
1884*437bfbebSnyanmisaka ret = -2;
1885*437bfbebSnyanmisaka goto failed;
1886*437bfbebSnyanmisaka }
1887*437bfbebSnyanmisaka
1888*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1889*437bfbebSnyanmisaka if (!buf) {
1890*437bfbebSnyanmisaka ret = -3;
1891*437bfbebSnyanmisaka goto failed;
1892*437bfbebSnyanmisaka }
1893*437bfbebSnyanmisaka
1894*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
1895*437bfbebSnyanmisaka buf = skip_ws_f(str);
1896*437bfbebSnyanmisaka if (!buf) {
1897*437bfbebSnyanmisaka ret = -4;
1898*437bfbebSnyanmisaka goto failed;
1899*437bfbebSnyanmisaka }
1900*437bfbebSnyanmisaka
1901*437bfbebSnyanmisaka /* check empty object */
1902*437bfbebSnyanmisaka if (buf[0] == ']') {
1903*437bfbebSnyanmisaka skip_byte_f(str, 1);
1904*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d found empty array\n", str->depth);
1905*437bfbebSnyanmisaka str->depth--;
1906*437bfbebSnyanmisaka return rk_ok;
1907*437bfbebSnyanmisaka }
1908*437bfbebSnyanmisaka
1909*437bfbebSnyanmisaka do {
1910*437bfbebSnyanmisaka /* find colon for separater */
1911*437bfbebSnyanmisaka buf = skip_ws_f(str);
1912*437bfbebSnyanmisaka if (!buf) {
1913*437bfbebSnyanmisaka ret = -5;
1914*437bfbebSnyanmisaka goto failed;
1915*437bfbebSnyanmisaka }
1916*437bfbebSnyanmisaka
1917*437bfbebSnyanmisaka /* parse value */
1918*437bfbebSnyanmisaka ret = parse_json_value(parent, NULL, str);
1919*437bfbebSnyanmisaka if (ret) {
1920*437bfbebSnyanmisaka ret = -6;
1921*437bfbebSnyanmisaka goto failed;
1922*437bfbebSnyanmisaka }
1923*437bfbebSnyanmisaka
1924*437bfbebSnyanmisaka buf = skip_ws_f(str);
1925*437bfbebSnyanmisaka if (!buf) {
1926*437bfbebSnyanmisaka ret = -7;
1927*437bfbebSnyanmisaka goto failed;
1928*437bfbebSnyanmisaka }
1929*437bfbebSnyanmisaka
1930*437bfbebSnyanmisaka if (buf[0] == ',') {
1931*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
1932*437bfbebSnyanmisaka if (!buf) {
1933*437bfbebSnyanmisaka ret = -8;
1934*437bfbebSnyanmisaka goto failed;
1935*437bfbebSnyanmisaka }
1936*437bfbebSnyanmisaka
1937*437bfbebSnyanmisaka buf = skip_ws_f(str);
1938*437bfbebSnyanmisaka if (buf[0] == '}')
1939*437bfbebSnyanmisaka break;
1940*437bfbebSnyanmisaka
1941*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get next array\n", str->depth, str->offset);
1942*437bfbebSnyanmisaka continue;
1943*437bfbebSnyanmisaka }
1944*437bfbebSnyanmisaka break;
1945*437bfbebSnyanmisaka } while (1);
1946*437bfbebSnyanmisaka
1947*437bfbebSnyanmisaka buf = skip_ws_f(str);
1948*437bfbebSnyanmisaka if (!buf || buf[0] != ']') {
1949*437bfbebSnyanmisaka ret = -9;
1950*437bfbebSnyanmisaka goto failed;
1951*437bfbebSnyanmisaka }
1952*437bfbebSnyanmisaka
1953*437bfbebSnyanmisaka skip_byte_f(str, 1);
1954*437bfbebSnyanmisaka
1955*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d array parse success\n",
1956*437bfbebSnyanmisaka str->depth, old, str->offset);
1957*437bfbebSnyanmisaka
1958*437bfbebSnyanmisaka str->depth--;
1959*437bfbebSnyanmisaka ret = rk_ok;
1960*437bfbebSnyanmisaka
1961*437bfbebSnyanmisaka failed:
1962*437bfbebSnyanmisaka if (ret)
1963*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d array parse failed ret %d\n",
1964*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
1965*437bfbebSnyanmisaka
1966*437bfbebSnyanmisaka return ret;
1967*437bfbebSnyanmisaka }
1968*437bfbebSnyanmisaka
parse_json_value(MppCfgIoImpl * parent,const char * name,MppCfgStrBuf * str)1969*437bfbebSnyanmisaka static rk_s32 parse_json_value(MppCfgIoImpl *parent, const char *name, MppCfgStrBuf *str)
1970*437bfbebSnyanmisaka {
1971*437bfbebSnyanmisaka MppCfgObj obj = NULL;
1972*437bfbebSnyanmisaka char *buf = NULL;
1973*437bfbebSnyanmisaka
1974*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: parse value\n", str->depth, str->offset);
1975*437bfbebSnyanmisaka
1976*437bfbebSnyanmisaka buf = test_byte_f(str, 4);
1977*437bfbebSnyanmisaka if (buf && !strncmp(buf, "null", 4)) {
1978*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_NULL, NULL);
1979*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1980*437bfbebSnyanmisaka
1981*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value null\n", str->depth, str->offset);
1982*437bfbebSnyanmisaka skip_byte_f(str, 4);
1983*437bfbebSnyanmisaka return rk_ok;
1984*437bfbebSnyanmisaka }
1985*437bfbebSnyanmisaka
1986*437bfbebSnyanmisaka if (buf && !strncmp(buf, "true", 4)) {
1987*437bfbebSnyanmisaka MppCfgVal val;
1988*437bfbebSnyanmisaka
1989*437bfbebSnyanmisaka val.b1 = 1;
1990*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_BOOL, &val);
1991*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
1992*437bfbebSnyanmisaka
1993*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value true\n", str->depth, str->offset);
1994*437bfbebSnyanmisaka skip_byte_f(str, 4);
1995*437bfbebSnyanmisaka return rk_ok;
1996*437bfbebSnyanmisaka }
1997*437bfbebSnyanmisaka
1998*437bfbebSnyanmisaka buf = test_byte_f(str, 5);
1999*437bfbebSnyanmisaka if (buf && !strncmp(buf, "false", 5)) {
2000*437bfbebSnyanmisaka MppCfgVal val;
2001*437bfbebSnyanmisaka
2002*437bfbebSnyanmisaka val.b1 = 0;
2003*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_BOOL, &val);
2004*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2005*437bfbebSnyanmisaka
2006*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value false\n", str->depth, str->offset);
2007*437bfbebSnyanmisaka skip_byte_f(str, 5);
2008*437bfbebSnyanmisaka return rk_ok;
2009*437bfbebSnyanmisaka }
2010*437bfbebSnyanmisaka
2011*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
2012*437bfbebSnyanmisaka if (buf && buf[0] == '\"') {
2013*437bfbebSnyanmisaka MppCfgVal val;
2014*437bfbebSnyanmisaka char *string = NULL;
2015*437bfbebSnyanmisaka rk_s32 len = 0;
2016*437bfbebSnyanmisaka
2017*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value string start\n", str->depth, str->offset);
2018*437bfbebSnyanmisaka
2019*437bfbebSnyanmisaka parse_json_string(str, &string, &len);
2020*437bfbebSnyanmisaka if (!string)
2021*437bfbebSnyanmisaka return rk_nok;
2022*437bfbebSnyanmisaka
2023*437bfbebSnyanmisaka val.str = dup_str(string, len);
2024*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_STRING, &val);
2025*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2026*437bfbebSnyanmisaka MPP_FREE(val.str);
2027*437bfbebSnyanmisaka
2028*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value string success\n", str->depth, str->offset);
2029*437bfbebSnyanmisaka return rk_ok;
2030*437bfbebSnyanmisaka }
2031*437bfbebSnyanmisaka
2032*437bfbebSnyanmisaka if (buf && (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9'))) {
2033*437bfbebSnyanmisaka MppCfgType type;
2034*437bfbebSnyanmisaka MppCfgVal val;
2035*437bfbebSnyanmisaka rk_s32 ret;
2036*437bfbebSnyanmisaka
2037*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value number start\n",
2038*437bfbebSnyanmisaka str->depth, str->offset);
2039*437bfbebSnyanmisaka
2040*437bfbebSnyanmisaka ret = parse_number(str, &type, &val);
2041*437bfbebSnyanmisaka if (ret)
2042*437bfbebSnyanmisaka return ret;
2043*437bfbebSnyanmisaka
2044*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, type, &val);
2045*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2046*437bfbebSnyanmisaka
2047*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value number success\n",
2048*437bfbebSnyanmisaka str->depth, str->offset);
2049*437bfbebSnyanmisaka return ret;
2050*437bfbebSnyanmisaka }
2051*437bfbebSnyanmisaka
2052*437bfbebSnyanmisaka if (buf && buf[0] == '{') {
2053*437bfbebSnyanmisaka rk_s32 ret;
2054*437bfbebSnyanmisaka
2055*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value object start\n",
2056*437bfbebSnyanmisaka str->depth, str->offset);
2057*437bfbebSnyanmisaka
2058*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_OBJECT, NULL);
2059*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2060*437bfbebSnyanmisaka
2061*437bfbebSnyanmisaka ret = parse_json_object(obj, str);
2062*437bfbebSnyanmisaka
2063*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value object ret %d\n",
2064*437bfbebSnyanmisaka str->depth, str->offset, ret);
2065*437bfbebSnyanmisaka return ret;
2066*437bfbebSnyanmisaka }
2067*437bfbebSnyanmisaka
2068*437bfbebSnyanmisaka if (buf && buf[0] == '[') {
2069*437bfbebSnyanmisaka rk_s32 ret;
2070*437bfbebSnyanmisaka
2071*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array start\n",
2072*437bfbebSnyanmisaka str->depth, str->offset);
2073*437bfbebSnyanmisaka
2074*437bfbebSnyanmisaka mpp_cfg_get_array(&obj, name, 0);
2075*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2076*437bfbebSnyanmisaka
2077*437bfbebSnyanmisaka ret = parse_json_array(obj, str);
2078*437bfbebSnyanmisaka
2079*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array ret %d\n",
2080*437bfbebSnyanmisaka str->depth, str->offset, ret);
2081*437bfbebSnyanmisaka return ret;
2082*437bfbebSnyanmisaka }
2083*437bfbebSnyanmisaka
2084*437bfbebSnyanmisaka return rk_nok;
2085*437bfbebSnyanmisaka }
2086*437bfbebSnyanmisaka
mpp_cfg_from_json(MppCfgObj * obj,MppCfgStrBuf * str)2087*437bfbebSnyanmisaka static rk_s32 mpp_cfg_from_json(MppCfgObj *obj, MppCfgStrBuf *str)
2088*437bfbebSnyanmisaka {
2089*437bfbebSnyanmisaka MppCfgObj object = NULL;
2090*437bfbebSnyanmisaka char *buf = NULL;
2091*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
2092*437bfbebSnyanmisaka
2093*437bfbebSnyanmisaka /* skip UTF-8 */
2094*437bfbebSnyanmisaka buf = test_byte_f(str, 4);
2095*437bfbebSnyanmisaka if (buf && !strncmp(buf, "\xEF\xBB\xBF", 3))
2096*437bfbebSnyanmisaka skip_byte_f(str, 3);
2097*437bfbebSnyanmisaka
2098*437bfbebSnyanmisaka /* skip white space and check the end of buffer */
2099*437bfbebSnyanmisaka buf = skip_ws_f(str);
2100*437bfbebSnyanmisaka if (!buf)
2101*437bfbebSnyanmisaka return rk_nok;
2102*437bfbebSnyanmisaka
2103*437bfbebSnyanmisaka if (buf[0] == '{') {
2104*437bfbebSnyanmisaka ret = mpp_cfg_get_object(&object, NULL, MPP_CFG_TYPE_OBJECT, NULL);
2105*437bfbebSnyanmisaka if (ret || !object) {
2106*437bfbebSnyanmisaka mpp_loge_f("failed to create top object\n");
2107*437bfbebSnyanmisaka return rk_nok;
2108*437bfbebSnyanmisaka }
2109*437bfbebSnyanmisaka
2110*437bfbebSnyanmisaka ret = parse_json_object(object, str);
2111*437bfbebSnyanmisaka } else if (buf[0] == '[') {
2112*437bfbebSnyanmisaka ret = mpp_cfg_get_array(&object, NULL, 0);
2113*437bfbebSnyanmisaka if (ret || !object) {
2114*437bfbebSnyanmisaka mpp_loge_f("failed to create top object\n");
2115*437bfbebSnyanmisaka return rk_nok;
2116*437bfbebSnyanmisaka }
2117*437bfbebSnyanmisaka
2118*437bfbebSnyanmisaka ret = parse_json_array(object, str);
2119*437bfbebSnyanmisaka } else {
2120*437bfbebSnyanmisaka mpp_loge_f("invalid top element '%c' on offset %d\n", buf[0], str->offset);
2121*437bfbebSnyanmisaka }
2122*437bfbebSnyanmisaka
2123*437bfbebSnyanmisaka *obj = object;
2124*437bfbebSnyanmisaka
2125*437bfbebSnyanmisaka return ret;
2126*437bfbebSnyanmisaka }
2127*437bfbebSnyanmisaka
parse_toml_nested_table(MppCfgIoImpl * root,MppCfgObj * object,char * name,rk_s32 name_len)2128*437bfbebSnyanmisaka static rk_s32 parse_toml_nested_table(MppCfgIoImpl *root, MppCfgObj *object, char *name,
2129*437bfbebSnyanmisaka rk_s32 name_len)
2130*437bfbebSnyanmisaka {
2131*437bfbebSnyanmisaka MppCfgObj obj = NULL;
2132*437bfbebSnyanmisaka MppCfgIoImpl *parent = root;
2133*437bfbebSnyanmisaka rk_s32 i = 0;
2134*437bfbebSnyanmisaka char sub_name_offset = 0;
2135*437bfbebSnyanmisaka char sub_name_len = 0;
2136*437bfbebSnyanmisaka char sub_name[256] = {0};
2137*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
2138*437bfbebSnyanmisaka
2139*437bfbebSnyanmisaka for (i = 0; i <= name_len; i++) {
2140*437bfbebSnyanmisaka if (name[i] == '.' || name[i] == '\0') {
2141*437bfbebSnyanmisaka sub_name_len = i;
2142*437bfbebSnyanmisaka memcpy(sub_name, name, sub_name_len);
2143*437bfbebSnyanmisaka sub_name[i] = '\0';
2144*437bfbebSnyanmisaka obj = NULL;
2145*437bfbebSnyanmisaka mpp_cfg_find(&obj, root, sub_name, MPP_CFG_STR_FMT_TOML);
2146*437bfbebSnyanmisaka if (!obj) {
2147*437bfbebSnyanmisaka memcpy(sub_name, name + sub_name_offset, sub_name_len - sub_name_offset);
2148*437bfbebSnyanmisaka sub_name[sub_name_len - sub_name_offset] = '\0';
2149*437bfbebSnyanmisaka ret = mpp_cfg_get_object(&obj, sub_name, MPP_CFG_TYPE_OBJECT, NULL);
2150*437bfbebSnyanmisaka if (ret || !obj) {
2151*437bfbebSnyanmisaka mpp_loge_f("failed to create object %s\n", name);
2152*437bfbebSnyanmisaka ret = -101;
2153*437bfbebSnyanmisaka return ret;
2154*437bfbebSnyanmisaka }
2155*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2156*437bfbebSnyanmisaka }
2157*437bfbebSnyanmisaka
2158*437bfbebSnyanmisaka parent = obj;
2159*437bfbebSnyanmisaka sub_name_offset = i + 1;
2160*437bfbebSnyanmisaka }
2161*437bfbebSnyanmisaka }
2162*437bfbebSnyanmisaka
2163*437bfbebSnyanmisaka *object = obj;
2164*437bfbebSnyanmisaka
2165*437bfbebSnyanmisaka return ret;
2166*437bfbebSnyanmisaka }
2167*437bfbebSnyanmisaka
parse_toml_nested_array_table(MppCfgIoImpl * root,MppCfgObj * object,char * name,rk_s32 name_len)2168*437bfbebSnyanmisaka static rk_s32 parse_toml_nested_array_table(MppCfgIoImpl *root, MppCfgObj *object, char *name,
2169*437bfbebSnyanmisaka rk_s32 name_len)
2170*437bfbebSnyanmisaka {
2171*437bfbebSnyanmisaka MppCfgObj obj = NULL;
2172*437bfbebSnyanmisaka MppCfgIoImpl *parent = root;
2173*437bfbebSnyanmisaka rk_s32 i = 0;
2174*437bfbebSnyanmisaka char sub_name_offset = 0;
2175*437bfbebSnyanmisaka char sub_name_len = 0;
2176*437bfbebSnyanmisaka char sub_name[256] = {0};
2177*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
2178*437bfbebSnyanmisaka
2179*437bfbebSnyanmisaka for (i = 0; i <= name_len; i++) {
2180*437bfbebSnyanmisaka if (name[i] == '.' || name[i] == '\0') {
2181*437bfbebSnyanmisaka sub_name_len = i;
2182*437bfbebSnyanmisaka memcpy(sub_name, name, sub_name_len);
2183*437bfbebSnyanmisaka sub_name[i] = '\0';
2184*437bfbebSnyanmisaka obj = NULL;
2185*437bfbebSnyanmisaka mpp_cfg_find(&obj, root, sub_name, MPP_CFG_STR_FMT_TOML);
2186*437bfbebSnyanmisaka if (!obj) {
2187*437bfbebSnyanmisaka memcpy(sub_name, name + sub_name_offset, sub_name_len - sub_name_offset);
2188*437bfbebSnyanmisaka sub_name[sub_name_len - sub_name_offset] = '\0';
2189*437bfbebSnyanmisaka
2190*437bfbebSnyanmisaka /* if parent type is array, need get its last child as new parent */
2191*437bfbebSnyanmisaka if (parent->type == MPP_CFG_TYPE_ARRAY) {
2192*437bfbebSnyanmisaka MppCfgIoImpl *child_pos, *child_n;
2193*437bfbebSnyanmisaka MppCfgIoImpl *last_child = NULL;
2194*437bfbebSnyanmisaka list_for_each_entry_safe(child_pos, child_n, &parent->child, MppCfgIoImpl, list) {
2195*437bfbebSnyanmisaka if (!child_pos->name && child_pos->type == MPP_CFG_TYPE_OBJECT) {
2196*437bfbebSnyanmisaka last_child = child_pos;
2197*437bfbebSnyanmisaka }
2198*437bfbebSnyanmisaka }
2199*437bfbebSnyanmisaka if (!last_child) {
2200*437bfbebSnyanmisaka mpp_loge_f("failed to find last child\n");
2201*437bfbebSnyanmisaka ret = -111;
2202*437bfbebSnyanmisaka return ret;
2203*437bfbebSnyanmisaka }
2204*437bfbebSnyanmisaka parent = last_child;
2205*437bfbebSnyanmisaka }
2206*437bfbebSnyanmisaka if (name[i] == '\0') {
2207*437bfbebSnyanmisaka ret = mpp_cfg_get_array(&obj, sub_name, 0);
2208*437bfbebSnyanmisaka if (ret || !obj) {
2209*437bfbebSnyanmisaka mpp_loge_f("failed to create object %s\n", name);
2210*437bfbebSnyanmisaka ret = -112;
2211*437bfbebSnyanmisaka return ret;
2212*437bfbebSnyanmisaka }
2213*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2214*437bfbebSnyanmisaka } else {
2215*437bfbebSnyanmisaka ret = mpp_cfg_get_object(&obj, sub_name, MPP_CFG_TYPE_OBJECT, NULL);
2216*437bfbebSnyanmisaka if (ret || !obj) {
2217*437bfbebSnyanmisaka mpp_loge_f("failed to create nested object %s\n", name);
2218*437bfbebSnyanmisaka ret = -113;
2219*437bfbebSnyanmisaka return ret;
2220*437bfbebSnyanmisaka }
2221*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2222*437bfbebSnyanmisaka }
2223*437bfbebSnyanmisaka }
2224*437bfbebSnyanmisaka
2225*437bfbebSnyanmisaka parent = obj;
2226*437bfbebSnyanmisaka sub_name_offset = i + 1;
2227*437bfbebSnyanmisaka }
2228*437bfbebSnyanmisaka }
2229*437bfbebSnyanmisaka
2230*437bfbebSnyanmisaka *object = obj;
2231*437bfbebSnyanmisaka
2232*437bfbebSnyanmisaka return ret;
2233*437bfbebSnyanmisaka }
2234*437bfbebSnyanmisaka
parse_toml_string(MppCfgStrBuf * str,char ** name,rk_s32 * len,rk_u32 type)2235*437bfbebSnyanmisaka static rk_s32 parse_toml_string(MppCfgStrBuf *str, char **name, rk_s32 *len, rk_u32 type)
2236*437bfbebSnyanmisaka {
2237*437bfbebSnyanmisaka char *buf = NULL;
2238*437bfbebSnyanmisaka char *start = NULL;
2239*437bfbebSnyanmisaka rk_s32 name_len = 0;
2240*437bfbebSnyanmisaka char terminator;
2241*437bfbebSnyanmisaka
2242*437bfbebSnyanmisaka *name = NULL;
2243*437bfbebSnyanmisaka *len = 0;
2244*437bfbebSnyanmisaka
2245*437bfbebSnyanmisaka /* skip whitespace and find first double quotes */
2246*437bfbebSnyanmisaka buf = skip_ws_f(str);
2247*437bfbebSnyanmisaka if (!buf)
2248*437bfbebSnyanmisaka return -201;
2249*437bfbebSnyanmisaka
2250*437bfbebSnyanmisaka if (type == MPP_CFG_PARSER_TYPE_VALUE) {
2251*437bfbebSnyanmisaka terminator = '\"';
2252*437bfbebSnyanmisaka if (buf[0] != '\"')
2253*437bfbebSnyanmisaka return -202;
2254*437bfbebSnyanmisaka
2255*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2256*437bfbebSnyanmisaka if (!buf)
2257*437bfbebSnyanmisaka return -203;
2258*437bfbebSnyanmisaka } else if (type == MPP_CFG_PARSER_TYPE_KEY) {
2259*437bfbebSnyanmisaka terminator = ' ';
2260*437bfbebSnyanmisaka } else if (type == MPP_CFG_PARSER_TYPE_TABLE || type == MPP_CFG_PARSER_TYPE_ARRAY_TABLE) {
2261*437bfbebSnyanmisaka terminator = ']';
2262*437bfbebSnyanmisaka } else {
2263*437bfbebSnyanmisaka return -204;
2264*437bfbebSnyanmisaka }
2265*437bfbebSnyanmisaka
2266*437bfbebSnyanmisaka start = buf;
2267*437bfbebSnyanmisaka
2268*437bfbebSnyanmisaka /* find the terminator */
2269*437bfbebSnyanmisaka while ((buf = show_byte_f(str, name_len)) && buf[0] != terminator) {
2270*437bfbebSnyanmisaka name_len++;
2271*437bfbebSnyanmisaka }
2272*437bfbebSnyanmisaka
2273*437bfbebSnyanmisaka if (!buf || buf[0] != terminator)
2274*437bfbebSnyanmisaka return -205;
2275*437bfbebSnyanmisaka
2276*437bfbebSnyanmisaka /* find complete string skip the string */
2277*437bfbebSnyanmisaka if (type == MPP_CFG_PARSER_TYPE_VALUE)
2278*437bfbebSnyanmisaka buf = skip_byte_f(str, name_len + 1);
2279*437bfbebSnyanmisaka else
2280*437bfbebSnyanmisaka buf = skip_byte_f(str, name_len);
2281*437bfbebSnyanmisaka if (!buf)
2282*437bfbebSnyanmisaka return -206;
2283*437bfbebSnyanmisaka
2284*437bfbebSnyanmisaka *name = start;
2285*437bfbebSnyanmisaka *len = name_len;
2286*437bfbebSnyanmisaka
2287*437bfbebSnyanmisaka return rk_ok;
2288*437bfbebSnyanmisaka }
2289*437bfbebSnyanmisaka
2290*437bfbebSnyanmisaka static rk_s32 parse_toml_value(MppCfgIoImpl *parent, const char *name, MppCfgStrBuf *str);
2291*437bfbebSnyanmisaka static rk_s32 parse_toml_object(MppCfgIoImpl *parent, MppCfgStrBuf *str, rk_s32 is_brace);
2292*437bfbebSnyanmisaka
parse_toml_array(MppCfgIoImpl * obj,MppCfgStrBuf * str)2293*437bfbebSnyanmisaka static rk_s32 parse_toml_array(MppCfgIoImpl *obj, MppCfgStrBuf *str)
2294*437bfbebSnyanmisaka {
2295*437bfbebSnyanmisaka MppCfgIoImpl *parent = obj;
2296*437bfbebSnyanmisaka char *buf = NULL;
2297*437bfbebSnyanmisaka rk_s32 old = str->offset;
2298*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
2299*437bfbebSnyanmisaka
2300*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
2301*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
2302*437bfbebSnyanmisaka return rk_nok;
2303*437bfbebSnyanmisaka }
2304*437bfbebSnyanmisaka
2305*437bfbebSnyanmisaka str->depth++;
2306*437bfbebSnyanmisaka
2307*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d array parse start\n", str->depth, str->offset);
2308*437bfbebSnyanmisaka
2309*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
2310*437bfbebSnyanmisaka if (!buf || buf[0] != '[') {
2311*437bfbebSnyanmisaka ret = -61;
2312*437bfbebSnyanmisaka goto failed;
2313*437bfbebSnyanmisaka }
2314*437bfbebSnyanmisaka
2315*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2316*437bfbebSnyanmisaka if (!buf) {
2317*437bfbebSnyanmisaka ret = -62;
2318*437bfbebSnyanmisaka goto failed;
2319*437bfbebSnyanmisaka }
2320*437bfbebSnyanmisaka
2321*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
2322*437bfbebSnyanmisaka buf = skip_ws_f(str);
2323*437bfbebSnyanmisaka if (!buf) {
2324*437bfbebSnyanmisaka ret = -63;
2325*437bfbebSnyanmisaka goto failed;
2326*437bfbebSnyanmisaka }
2327*437bfbebSnyanmisaka
2328*437bfbebSnyanmisaka /* check empty object */
2329*437bfbebSnyanmisaka if (buf[0] == ']') {
2330*437bfbebSnyanmisaka skip_byte_f(str, 1);
2331*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d found empty array\n", str->depth);
2332*437bfbebSnyanmisaka str->depth--;
2333*437bfbebSnyanmisaka return rk_ok;
2334*437bfbebSnyanmisaka }
2335*437bfbebSnyanmisaka
2336*437bfbebSnyanmisaka do {
2337*437bfbebSnyanmisaka buf = skip_ws_f(str);
2338*437bfbebSnyanmisaka if (!buf) {
2339*437bfbebSnyanmisaka ret = -64;
2340*437bfbebSnyanmisaka goto failed;
2341*437bfbebSnyanmisaka }
2342*437bfbebSnyanmisaka
2343*437bfbebSnyanmisaka /* parse value */
2344*437bfbebSnyanmisaka ret = parse_toml_value(parent, NULL, str);
2345*437bfbebSnyanmisaka if (ret) {
2346*437bfbebSnyanmisaka ret = -65;
2347*437bfbebSnyanmisaka goto failed;
2348*437bfbebSnyanmisaka }
2349*437bfbebSnyanmisaka
2350*437bfbebSnyanmisaka buf = skip_ws_f(str);
2351*437bfbebSnyanmisaka if (!buf) {
2352*437bfbebSnyanmisaka ret = -66;
2353*437bfbebSnyanmisaka goto failed;
2354*437bfbebSnyanmisaka }
2355*437bfbebSnyanmisaka
2356*437bfbebSnyanmisaka if (buf[0] == ',') {
2357*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2358*437bfbebSnyanmisaka if (!buf) {
2359*437bfbebSnyanmisaka ret = -67;
2360*437bfbebSnyanmisaka goto failed;
2361*437bfbebSnyanmisaka }
2362*437bfbebSnyanmisaka
2363*437bfbebSnyanmisaka buf = skip_ws_f(str);
2364*437bfbebSnyanmisaka if (buf[0] == '}')
2365*437bfbebSnyanmisaka break;
2366*437bfbebSnyanmisaka
2367*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get next array\n", str->depth, str->offset);
2368*437bfbebSnyanmisaka continue;
2369*437bfbebSnyanmisaka }
2370*437bfbebSnyanmisaka break;
2371*437bfbebSnyanmisaka } while (1);
2372*437bfbebSnyanmisaka
2373*437bfbebSnyanmisaka if (!buf || buf[0] != ']') {
2374*437bfbebSnyanmisaka ret = -68;
2375*437bfbebSnyanmisaka goto failed;
2376*437bfbebSnyanmisaka }
2377*437bfbebSnyanmisaka
2378*437bfbebSnyanmisaka skip_byte_f(str, 1);
2379*437bfbebSnyanmisaka
2380*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d array parse success\n",
2381*437bfbebSnyanmisaka str->depth, old, str->offset);
2382*437bfbebSnyanmisaka
2383*437bfbebSnyanmisaka str->depth--;
2384*437bfbebSnyanmisaka ret = rk_ok;
2385*437bfbebSnyanmisaka
2386*437bfbebSnyanmisaka failed:
2387*437bfbebSnyanmisaka if (ret)
2388*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d array parse failed ret %d\n",
2389*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
2390*437bfbebSnyanmisaka
2391*437bfbebSnyanmisaka return ret;
2392*437bfbebSnyanmisaka }
2393*437bfbebSnyanmisaka
parse_toml_value(MppCfgIoImpl * parent,const char * name,MppCfgStrBuf * str)2394*437bfbebSnyanmisaka static rk_s32 parse_toml_value(MppCfgIoImpl *parent, const char *name, MppCfgStrBuf *str)
2395*437bfbebSnyanmisaka {
2396*437bfbebSnyanmisaka MppCfgObj obj = NULL;
2397*437bfbebSnyanmisaka char *buf = NULL;
2398*437bfbebSnyanmisaka
2399*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: parse value\n", str->depth, str->offset);
2400*437bfbebSnyanmisaka
2401*437bfbebSnyanmisaka buf = test_byte_f(str, 4);
2402*437bfbebSnyanmisaka if (buf && !strncmp(buf, "null", 4)) {
2403*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_NULL, NULL);
2404*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2405*437bfbebSnyanmisaka
2406*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value null\n", str->depth, str->offset);
2407*437bfbebSnyanmisaka skip_byte_f(str, 4);
2408*437bfbebSnyanmisaka return rk_ok;
2409*437bfbebSnyanmisaka }
2410*437bfbebSnyanmisaka
2411*437bfbebSnyanmisaka if (buf && !strncmp(buf, "true", 4)) {
2412*437bfbebSnyanmisaka MppCfgVal val;
2413*437bfbebSnyanmisaka
2414*437bfbebSnyanmisaka val.b1 = 1;
2415*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_BOOL, &val);
2416*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2417*437bfbebSnyanmisaka
2418*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value true\n", str->depth, str->offset);
2419*437bfbebSnyanmisaka skip_byte_f(str, 4);
2420*437bfbebSnyanmisaka return rk_ok;
2421*437bfbebSnyanmisaka }
2422*437bfbebSnyanmisaka
2423*437bfbebSnyanmisaka buf = test_byte_f(str, 5);
2424*437bfbebSnyanmisaka if (buf && !strncmp(buf, "false", 5)) {
2425*437bfbebSnyanmisaka MppCfgVal val;
2426*437bfbebSnyanmisaka
2427*437bfbebSnyanmisaka val.b1 = 0;
2428*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_BOOL, &val);
2429*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2430*437bfbebSnyanmisaka
2431*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value false\n", str->depth, str->offset);
2432*437bfbebSnyanmisaka skip_byte_f(str, 5);
2433*437bfbebSnyanmisaka return rk_ok;
2434*437bfbebSnyanmisaka }
2435*437bfbebSnyanmisaka
2436*437bfbebSnyanmisaka buf = test_byte_f(str, 3);
2437*437bfbebSnyanmisaka if (buf && !strncmp(buf, "\"\"\"", 3)) {
2438*437bfbebSnyanmisaka MppCfgVal val;
2439*437bfbebSnyanmisaka char *string = NULL;
2440*437bfbebSnyanmisaka rk_s32 len = 0;
2441*437bfbebSnyanmisaka
2442*437bfbebSnyanmisaka skip_byte_f(str, 2);
2443*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value multi line string start\n", str->depth, str->offset);
2444*437bfbebSnyanmisaka
2445*437bfbebSnyanmisaka parse_toml_string(str, &string, &len, MPP_CFG_PARSER_TYPE_VALUE);
2446*437bfbebSnyanmisaka if (!string)
2447*437bfbebSnyanmisaka return rk_nok;
2448*437bfbebSnyanmisaka buf = test_byte_f(str, 1);
2449*437bfbebSnyanmisaka if (!buf || strncmp(buf, "\"\"", 2)) {
2450*437bfbebSnyanmisaka return rk_nok;
2451*437bfbebSnyanmisaka }
2452*437bfbebSnyanmisaka skip_byte_f(str, 2);
2453*437bfbebSnyanmisaka
2454*437bfbebSnyanmisaka val.str = dup_str(string, len);
2455*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_STRING, &val);
2456*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2457*437bfbebSnyanmisaka MPP_FREE(val.str);
2458*437bfbebSnyanmisaka
2459*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value multi line string success\n", str->depth, str->offset);
2460*437bfbebSnyanmisaka return rk_ok;
2461*437bfbebSnyanmisaka }
2462*437bfbebSnyanmisaka
2463*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
2464*437bfbebSnyanmisaka if (buf && buf[0] == '\"') {
2465*437bfbebSnyanmisaka MppCfgVal val;
2466*437bfbebSnyanmisaka char *string = NULL;
2467*437bfbebSnyanmisaka rk_s32 len = 0;
2468*437bfbebSnyanmisaka
2469*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value string start\n", str->depth, str->offset);
2470*437bfbebSnyanmisaka
2471*437bfbebSnyanmisaka parse_toml_string(str, &string, &len, MPP_CFG_PARSER_TYPE_VALUE);
2472*437bfbebSnyanmisaka if (!string)
2473*437bfbebSnyanmisaka return rk_nok;
2474*437bfbebSnyanmisaka
2475*437bfbebSnyanmisaka val.str = dup_str(string, len);
2476*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_STRING, &val);
2477*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2478*437bfbebSnyanmisaka MPP_FREE(val.str);
2479*437bfbebSnyanmisaka
2480*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value string success\n", str->depth, str->offset);
2481*437bfbebSnyanmisaka return rk_ok;
2482*437bfbebSnyanmisaka }
2483*437bfbebSnyanmisaka
2484*437bfbebSnyanmisaka if (buf && (buf[0] == '-' || (buf[0] >= '0' && buf[0] <= '9'))) {
2485*437bfbebSnyanmisaka MppCfgType type;
2486*437bfbebSnyanmisaka MppCfgVal val;
2487*437bfbebSnyanmisaka rk_s32 ret;
2488*437bfbebSnyanmisaka
2489*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value number start\n",
2490*437bfbebSnyanmisaka str->depth, str->offset);
2491*437bfbebSnyanmisaka
2492*437bfbebSnyanmisaka ret = parse_number(str, &type, &val);
2493*437bfbebSnyanmisaka if (ret)
2494*437bfbebSnyanmisaka return ret;
2495*437bfbebSnyanmisaka
2496*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, type, &val);
2497*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2498*437bfbebSnyanmisaka
2499*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value number success\n",
2500*437bfbebSnyanmisaka str->depth, str->offset);
2501*437bfbebSnyanmisaka return ret;
2502*437bfbebSnyanmisaka }
2503*437bfbebSnyanmisaka
2504*437bfbebSnyanmisaka if (buf && buf[0] == '{') {
2505*437bfbebSnyanmisaka rk_s32 ret;
2506*437bfbebSnyanmisaka
2507*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value object start\n",
2508*437bfbebSnyanmisaka str->depth, str->offset);
2509*437bfbebSnyanmisaka
2510*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, name, MPP_CFG_TYPE_OBJECT, NULL);
2511*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2512*437bfbebSnyanmisaka
2513*437bfbebSnyanmisaka ret = parse_toml_object(obj, str, 1);
2514*437bfbebSnyanmisaka
2515*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value object ret %d\n",
2516*437bfbebSnyanmisaka str->depth, str->offset, ret);
2517*437bfbebSnyanmisaka return ret;
2518*437bfbebSnyanmisaka }
2519*437bfbebSnyanmisaka
2520*437bfbebSnyanmisaka if (buf && buf[0] == '[') {
2521*437bfbebSnyanmisaka rk_s32 ret;
2522*437bfbebSnyanmisaka
2523*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array start\n",
2524*437bfbebSnyanmisaka str->depth, str->offset);
2525*437bfbebSnyanmisaka
2526*437bfbebSnyanmisaka mpp_cfg_get_array(&obj, name, 0);
2527*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2528*437bfbebSnyanmisaka
2529*437bfbebSnyanmisaka ret = parse_toml_array(obj, str);
2530*437bfbebSnyanmisaka
2531*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array ret %d\n",
2532*437bfbebSnyanmisaka str->depth, str->offset, ret);
2533*437bfbebSnyanmisaka return ret;
2534*437bfbebSnyanmisaka }
2535*437bfbebSnyanmisaka
2536*437bfbebSnyanmisaka return rk_nok;
2537*437bfbebSnyanmisaka }
2538*437bfbebSnyanmisaka
parse_toml_object(MppCfgIoImpl * parent,MppCfgStrBuf * str,rk_s32 is_brace)2539*437bfbebSnyanmisaka static rk_s32 parse_toml_object(MppCfgIoImpl *parent, MppCfgStrBuf *str, rk_s32 is_brace)
2540*437bfbebSnyanmisaka {
2541*437bfbebSnyanmisaka char *buf = NULL;
2542*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
2543*437bfbebSnyanmisaka rk_s32 old = str->offset;
2544*437bfbebSnyanmisaka
2545*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
2546*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
2547*437bfbebSnyanmisaka return rk_nok;
2548*437bfbebSnyanmisaka }
2549*437bfbebSnyanmisaka
2550*437bfbebSnyanmisaka str->depth++;
2551*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
2552*437bfbebSnyanmisaka if (is_brace) {
2553*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
2554*437bfbebSnyanmisaka if (!buf || buf[0] != '{') {
2555*437bfbebSnyanmisaka ret = -31;
2556*437bfbebSnyanmisaka goto failed;
2557*437bfbebSnyanmisaka }
2558*437bfbebSnyanmisaka
2559*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2560*437bfbebSnyanmisaka if (!buf) {
2561*437bfbebSnyanmisaka ret = -32;
2562*437bfbebSnyanmisaka goto failed;
2563*437bfbebSnyanmisaka }
2564*437bfbebSnyanmisaka
2565*437bfbebSnyanmisaka /* skip whitespace and check the end of buffer */
2566*437bfbebSnyanmisaka buf = skip_ws_f(str);
2567*437bfbebSnyanmisaka if (!buf) {
2568*437bfbebSnyanmisaka ret = -33;
2569*437bfbebSnyanmisaka goto failed;
2570*437bfbebSnyanmisaka }
2571*437bfbebSnyanmisaka
2572*437bfbebSnyanmisaka /* check empty object */
2573*437bfbebSnyanmisaka if (buf[0] == '}') {
2574*437bfbebSnyanmisaka skip_byte_f(str, 1);
2575*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d found empty object\n", str->depth);
2576*437bfbebSnyanmisaka str->depth--;
2577*437bfbebSnyanmisaka return rk_ok;
2578*437bfbebSnyanmisaka }
2579*437bfbebSnyanmisaka } else {
2580*437bfbebSnyanmisaka buf = skip_ws_f(str);
2581*437bfbebSnyanmisaka if (!buf) {
2582*437bfbebSnyanmisaka ret = -34;
2583*437bfbebSnyanmisaka goto failed;
2584*437bfbebSnyanmisaka }
2585*437bfbebSnyanmisaka }
2586*437bfbebSnyanmisaka
2587*437bfbebSnyanmisaka do {
2588*437bfbebSnyanmisaka rk_s32 name_len = 0;
2589*437bfbebSnyanmisaka char *name = NULL;
2590*437bfbebSnyanmisaka char *tmp = NULL;
2591*437bfbebSnyanmisaka
2592*437bfbebSnyanmisaka if (buf[0] == '[') {
2593*437bfbebSnyanmisaka MppCfgObj object = NULL;
2594*437bfbebSnyanmisaka
2595*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array start\n",
2596*437bfbebSnyanmisaka str->depth, str->offset);
2597*437bfbebSnyanmisaka
2598*437bfbebSnyanmisaka mpp_cfg_get_array(&object, NULL, 0);
2599*437bfbebSnyanmisaka mpp_cfg_add(parent, object);
2600*437bfbebSnyanmisaka
2601*437bfbebSnyanmisaka ret = parse_toml_array(object, str);
2602*437bfbebSnyanmisaka
2603*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get value array ret %d\n",
2604*437bfbebSnyanmisaka str->depth, str->offset, ret);
2605*437bfbebSnyanmisaka
2606*437bfbebSnyanmisaka if (ret) {
2607*437bfbebSnyanmisaka mpp_cfg_put_all_child(object);
2608*437bfbebSnyanmisaka goto failed;
2609*437bfbebSnyanmisaka }
2610*437bfbebSnyanmisaka
2611*437bfbebSnyanmisaka goto __next;
2612*437bfbebSnyanmisaka }
2613*437bfbebSnyanmisaka
2614*437bfbebSnyanmisaka ret = parse_toml_string(str, &name, &name_len, MPP_CFG_PARSER_TYPE_KEY);
2615*437bfbebSnyanmisaka if (ret) {
2616*437bfbebSnyanmisaka ret = -35;
2617*437bfbebSnyanmisaka goto failed;
2618*437bfbebSnyanmisaka }
2619*437bfbebSnyanmisaka
2620*437bfbebSnyanmisaka /* find equal for separater */
2621*437bfbebSnyanmisaka buf = skip_ws_f(str);
2622*437bfbebSnyanmisaka if (!buf || buf[0] != '=') {
2623*437bfbebSnyanmisaka ret = -36;
2624*437bfbebSnyanmisaka goto failed;
2625*437bfbebSnyanmisaka }
2626*437bfbebSnyanmisaka
2627*437bfbebSnyanmisaka /* skip equal */
2628*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2629*437bfbebSnyanmisaka if (!buf) {
2630*437bfbebSnyanmisaka ret = -37;
2631*437bfbebSnyanmisaka goto failed;
2632*437bfbebSnyanmisaka }
2633*437bfbebSnyanmisaka
2634*437bfbebSnyanmisaka buf = skip_ws_f(str);
2635*437bfbebSnyanmisaka if (!buf) {
2636*437bfbebSnyanmisaka ret = -38;
2637*437bfbebSnyanmisaka goto failed;
2638*437bfbebSnyanmisaka }
2639*437bfbebSnyanmisaka
2640*437bfbebSnyanmisaka tmp = dup_str(name, name_len);
2641*437bfbebSnyanmisaka if (!tmp) {
2642*437bfbebSnyanmisaka mpp_loge_f("failed to dup name\n");
2643*437bfbebSnyanmisaka ret = -39;
2644*437bfbebSnyanmisaka goto failed;
2645*437bfbebSnyanmisaka }
2646*437bfbebSnyanmisaka
2647*437bfbebSnyanmisaka /* parse value */
2648*437bfbebSnyanmisaka ret = parse_toml_value(parent, tmp, str);
2649*437bfbebSnyanmisaka MPP_FREE(tmp);
2650*437bfbebSnyanmisaka if (ret) {
2651*437bfbebSnyanmisaka ret = -40;
2652*437bfbebSnyanmisaka goto failed;
2653*437bfbebSnyanmisaka }
2654*437bfbebSnyanmisaka __next:
2655*437bfbebSnyanmisaka buf = skip_ws_f(str);
2656*437bfbebSnyanmisaka if (!buf || buf[0] == '[' || buf[0] == '}')
2657*437bfbebSnyanmisaka break;
2658*437bfbebSnyanmisaka
2659*437bfbebSnyanmisaka if (buf[0] == ',') {
2660*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2661*437bfbebSnyanmisaka if (!buf) {
2662*437bfbebSnyanmisaka ret = -41;
2663*437bfbebSnyanmisaka goto failed;
2664*437bfbebSnyanmisaka }
2665*437bfbebSnyanmisaka
2666*437bfbebSnyanmisaka buf = skip_ws_f(str);
2667*437bfbebSnyanmisaka if (buf[0] == '[' || buf[0] == '}')
2668*437bfbebSnyanmisaka break;
2669*437bfbebSnyanmisaka
2670*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d: get next object\n", str->depth, str->offset);
2671*437bfbebSnyanmisaka }
2672*437bfbebSnyanmisaka } while (1);
2673*437bfbebSnyanmisaka
2674*437bfbebSnyanmisaka if (is_brace) {
2675*437bfbebSnyanmisaka if (buf && buf[0] == '}')
2676*437bfbebSnyanmisaka skip_byte_f(str, 1);
2677*437bfbebSnyanmisaka else {
2678*437bfbebSnyanmisaka ret = -42;
2679*437bfbebSnyanmisaka goto failed;
2680*437bfbebSnyanmisaka }
2681*437bfbebSnyanmisaka }
2682*437bfbebSnyanmisaka
2683*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d object parse success\n",
2684*437bfbebSnyanmisaka str->depth, old, str->offset);
2685*437bfbebSnyanmisaka
2686*437bfbebSnyanmisaka str->depth--;
2687*437bfbebSnyanmisaka ret = rk_ok;
2688*437bfbebSnyanmisaka
2689*437bfbebSnyanmisaka failed:
2690*437bfbebSnyanmisaka if (ret)
2691*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d object parse failed ret %d\n",
2692*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
2693*437bfbebSnyanmisaka
2694*437bfbebSnyanmisaka return ret;
2695*437bfbebSnyanmisaka }
2696*437bfbebSnyanmisaka
parse_toml_table(MppCfgIoImpl * parent,MppCfgStrBuf * str)2697*437bfbebSnyanmisaka static rk_s32 parse_toml_table(MppCfgIoImpl *parent, MppCfgStrBuf *str)
2698*437bfbebSnyanmisaka {
2699*437bfbebSnyanmisaka MppCfgObj obj = NULL;
2700*437bfbebSnyanmisaka char *buf = NULL;
2701*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
2702*437bfbebSnyanmisaka rk_s32 name_len = 0;
2703*437bfbebSnyanmisaka char *name = NULL;
2704*437bfbebSnyanmisaka char *tmp = NULL;
2705*437bfbebSnyanmisaka
2706*437bfbebSnyanmisaka ret = parse_toml_string(str, &name, &name_len, MPP_CFG_PARSER_TYPE_TABLE);
2707*437bfbebSnyanmisaka if (ret) {
2708*437bfbebSnyanmisaka ret = -11;
2709*437bfbebSnyanmisaka goto failed;
2710*437bfbebSnyanmisaka }
2711*437bfbebSnyanmisaka
2712*437bfbebSnyanmisaka tmp = dup_str(name, name_len);
2713*437bfbebSnyanmisaka if (!tmp) {
2714*437bfbebSnyanmisaka mpp_loge_f("failed to dup tmp\n");
2715*437bfbebSnyanmisaka ret = -12;
2716*437bfbebSnyanmisaka goto failed;
2717*437bfbebSnyanmisaka }
2718*437bfbebSnyanmisaka
2719*437bfbebSnyanmisaka if (strchr(tmp, '.')) {
2720*437bfbebSnyanmisaka ret = parse_toml_nested_table(parent, &obj, tmp, name_len);
2721*437bfbebSnyanmisaka MPP_FREE(tmp);
2722*437bfbebSnyanmisaka if (ret || !obj) {
2723*437bfbebSnyanmisaka return ret;
2724*437bfbebSnyanmisaka }
2725*437bfbebSnyanmisaka } else {
2726*437bfbebSnyanmisaka ret = mpp_cfg_get_object(&obj, tmp, MPP_CFG_TYPE_OBJECT, NULL);
2727*437bfbebSnyanmisaka MPP_FREE(tmp);
2728*437bfbebSnyanmisaka if (ret || !obj) {
2729*437bfbebSnyanmisaka mpp_loge_f("failed to create object %s\n", tmp);
2730*437bfbebSnyanmisaka ret = -13;
2731*437bfbebSnyanmisaka goto failed;
2732*437bfbebSnyanmisaka }
2733*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2734*437bfbebSnyanmisaka }
2735*437bfbebSnyanmisaka
2736*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
2737*437bfbebSnyanmisaka if (!buf || buf[0] != ']') {
2738*437bfbebSnyanmisaka ret = -14;
2739*437bfbebSnyanmisaka goto failed;
2740*437bfbebSnyanmisaka }
2741*437bfbebSnyanmisaka
2742*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2743*437bfbebSnyanmisaka if (!buf) {
2744*437bfbebSnyanmisaka ret = -15;
2745*437bfbebSnyanmisaka goto failed;
2746*437bfbebSnyanmisaka }
2747*437bfbebSnyanmisaka
2748*437bfbebSnyanmisaka buf = skip_ws_f(str);
2749*437bfbebSnyanmisaka if (!buf)
2750*437bfbebSnyanmisaka return rk_nok;
2751*437bfbebSnyanmisaka
2752*437bfbebSnyanmisaka if (buf[0] == '[')
2753*437bfbebSnyanmisaka ret = rk_ok;
2754*437bfbebSnyanmisaka else
2755*437bfbebSnyanmisaka ret = parse_toml_object(obj, str, 0);
2756*437bfbebSnyanmisaka
2757*437bfbebSnyanmisaka failed:
2758*437bfbebSnyanmisaka if (ret)
2759*437bfbebSnyanmisaka cfg_io_dbg_from("table parse failed ret %d\n", ret);
2760*437bfbebSnyanmisaka
2761*437bfbebSnyanmisaka return ret;
2762*437bfbebSnyanmisaka }
2763*437bfbebSnyanmisaka
parse_toml_array_table(MppCfgIoImpl * parent,MppCfgStrBuf * str)2764*437bfbebSnyanmisaka static rk_s32 parse_toml_array_table(MppCfgIoImpl *parent, MppCfgStrBuf *str)
2765*437bfbebSnyanmisaka {
2766*437bfbebSnyanmisaka MppCfgObj obj = NULL;
2767*437bfbebSnyanmisaka char *buf = NULL;
2768*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
2769*437bfbebSnyanmisaka rk_s32 name_len = 0;
2770*437bfbebSnyanmisaka char *name = NULL;
2771*437bfbebSnyanmisaka char *tmp = NULL;
2772*437bfbebSnyanmisaka
2773*437bfbebSnyanmisaka ret = parse_toml_string(str, &name, &name_len, MPP_CFG_PARSER_TYPE_ARRAY_TABLE);
2774*437bfbebSnyanmisaka if (ret) {
2775*437bfbebSnyanmisaka ret = -22;
2776*437bfbebSnyanmisaka goto failed;
2777*437bfbebSnyanmisaka }
2778*437bfbebSnyanmisaka
2779*437bfbebSnyanmisaka tmp = dup_str(name, name_len);
2780*437bfbebSnyanmisaka if (!tmp) {
2781*437bfbebSnyanmisaka mpp_loge_f("failed to dup tmp\n");
2782*437bfbebSnyanmisaka ret = -23;
2783*437bfbebSnyanmisaka goto failed;
2784*437bfbebSnyanmisaka }
2785*437bfbebSnyanmisaka
2786*437bfbebSnyanmisaka if (strchr(tmp, '.')) {
2787*437bfbebSnyanmisaka ret = parse_toml_nested_array_table(parent, &obj, tmp, name_len);
2788*437bfbebSnyanmisaka MPP_FREE(tmp);
2789*437bfbebSnyanmisaka if (ret || !obj) {
2790*437bfbebSnyanmisaka return ret;
2791*437bfbebSnyanmisaka }
2792*437bfbebSnyanmisaka } else {
2793*437bfbebSnyanmisaka mpp_cfg_find(&obj, parent, tmp, MPP_CFG_STR_FMT_TOML);
2794*437bfbebSnyanmisaka if (!obj) {
2795*437bfbebSnyanmisaka ret = mpp_cfg_get_array(&obj, tmp, 0);
2796*437bfbebSnyanmisaka MPP_FREE(tmp);
2797*437bfbebSnyanmisaka if (ret || !obj) {
2798*437bfbebSnyanmisaka mpp_loge_f("failed to create object %s\n", tmp);
2799*437bfbebSnyanmisaka ret = -24;
2800*437bfbebSnyanmisaka goto failed;
2801*437bfbebSnyanmisaka }
2802*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2803*437bfbebSnyanmisaka } else {
2804*437bfbebSnyanmisaka MPP_FREE(tmp);
2805*437bfbebSnyanmisaka }
2806*437bfbebSnyanmisaka }
2807*437bfbebSnyanmisaka
2808*437bfbebSnyanmisaka /* array object need create object as child */
2809*437bfbebSnyanmisaka parent = obj;
2810*437bfbebSnyanmisaka obj = NULL;
2811*437bfbebSnyanmisaka mpp_cfg_get_object(&obj, NULL, MPP_CFG_TYPE_OBJECT, NULL);
2812*437bfbebSnyanmisaka mpp_cfg_add(parent, obj);
2813*437bfbebSnyanmisaka
2814*437bfbebSnyanmisaka buf = test_byte_f(str, 1);
2815*437bfbebSnyanmisaka if (!buf || strncmp(buf, "]]", 2)) {
2816*437bfbebSnyanmisaka ret = -25;
2817*437bfbebSnyanmisaka goto failed;
2818*437bfbebSnyanmisaka }
2819*437bfbebSnyanmisaka
2820*437bfbebSnyanmisaka buf = skip_byte_f(str, 2);
2821*437bfbebSnyanmisaka if (!buf) {
2822*437bfbebSnyanmisaka ret = -26;
2823*437bfbebSnyanmisaka goto failed;
2824*437bfbebSnyanmisaka }
2825*437bfbebSnyanmisaka
2826*437bfbebSnyanmisaka buf = skip_ws_f(str);
2827*437bfbebSnyanmisaka if (!buf)
2828*437bfbebSnyanmisaka return rk_nok;
2829*437bfbebSnyanmisaka
2830*437bfbebSnyanmisaka if (buf[0] == '[')
2831*437bfbebSnyanmisaka ret = rk_ok;
2832*437bfbebSnyanmisaka else
2833*437bfbebSnyanmisaka ret = parse_toml_object(obj, str, 0);
2834*437bfbebSnyanmisaka
2835*437bfbebSnyanmisaka failed:
2836*437bfbebSnyanmisaka if (ret)
2837*437bfbebSnyanmisaka cfg_io_dbg_from("array table parse failed ret %d\n", ret);
2838*437bfbebSnyanmisaka return ret;
2839*437bfbebSnyanmisaka }
2840*437bfbebSnyanmisaka
parse_toml_section(MppCfgIoImpl * parent,MppCfgStrBuf * str)2841*437bfbebSnyanmisaka static rk_s32 parse_toml_section(MppCfgIoImpl *parent, MppCfgStrBuf *str)
2842*437bfbebSnyanmisaka {
2843*437bfbebSnyanmisaka char *buf = NULL;
2844*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
2845*437bfbebSnyanmisaka rk_s32 old = str->offset;
2846*437bfbebSnyanmisaka
2847*437bfbebSnyanmisaka if (str->depth >= MAX_CFG_DEPTH) {
2848*437bfbebSnyanmisaka mpp_loge_f("depth %d reached max\n", MAX_CFG_DEPTH);
2849*437bfbebSnyanmisaka return rk_nok;
2850*437bfbebSnyanmisaka }
2851*437bfbebSnyanmisaka
2852*437bfbebSnyanmisaka buf = test_byte_f(str, 0);
2853*437bfbebSnyanmisaka if (!buf) {
2854*437bfbebSnyanmisaka ret = -2;
2855*437bfbebSnyanmisaka goto failed;
2856*437bfbebSnyanmisaka }
2857*437bfbebSnyanmisaka
2858*437bfbebSnyanmisaka if (buf[0] == '[') {
2859*437bfbebSnyanmisaka str->depth++;
2860*437bfbebSnyanmisaka
2861*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2862*437bfbebSnyanmisaka if (!buf) {
2863*437bfbebSnyanmisaka ret = -3;
2864*437bfbebSnyanmisaka goto failed;
2865*437bfbebSnyanmisaka }
2866*437bfbebSnyanmisaka if (buf[0] != '[') {
2867*437bfbebSnyanmisaka ret = parse_toml_table(parent, str);
2868*437bfbebSnyanmisaka if (ret)
2869*437bfbebSnyanmisaka goto failed;
2870*437bfbebSnyanmisaka } else {
2871*437bfbebSnyanmisaka buf = skip_byte_f(str, 1);
2872*437bfbebSnyanmisaka if (!buf) {
2873*437bfbebSnyanmisaka ret = -4;
2874*437bfbebSnyanmisaka goto failed;
2875*437bfbebSnyanmisaka }
2876*437bfbebSnyanmisaka
2877*437bfbebSnyanmisaka ret = parse_toml_array_table(parent, str);
2878*437bfbebSnyanmisaka if (ret)
2879*437bfbebSnyanmisaka goto failed;
2880*437bfbebSnyanmisaka }
2881*437bfbebSnyanmisaka str->depth--;
2882*437bfbebSnyanmisaka } else {
2883*437bfbebSnyanmisaka ret = parse_toml_object(parent, str, 0);
2884*437bfbebSnyanmisaka if (ret)
2885*437bfbebSnyanmisaka goto failed;
2886*437bfbebSnyanmisaka }
2887*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d section parse success\n",
2888*437bfbebSnyanmisaka str->depth, old, str->offset);
2889*437bfbebSnyanmisaka
2890*437bfbebSnyanmisaka ret = rk_ok;
2891*437bfbebSnyanmisaka
2892*437bfbebSnyanmisaka failed:
2893*437bfbebSnyanmisaka if (ret)
2894*437bfbebSnyanmisaka cfg_io_dbg_from("depth %d offset %d -> %d section parse failed ret %d\n",
2895*437bfbebSnyanmisaka str->depth, old, str->offset, ret);
2896*437bfbebSnyanmisaka
2897*437bfbebSnyanmisaka return ret;
2898*437bfbebSnyanmisaka }
2899*437bfbebSnyanmisaka
mpp_cfg_from_toml(MppCfgObj * obj,MppCfgStrBuf * str)2900*437bfbebSnyanmisaka static rk_s32 mpp_cfg_from_toml(MppCfgObj *obj, MppCfgStrBuf *str)
2901*437bfbebSnyanmisaka {
2902*437bfbebSnyanmisaka MppCfgObj object = NULL;
2903*437bfbebSnyanmisaka char *buf = NULL;
2904*437bfbebSnyanmisaka rk_s32 ret = rk_ok;
2905*437bfbebSnyanmisaka
2906*437bfbebSnyanmisaka /* skip white space and check the end of buffer */
2907*437bfbebSnyanmisaka buf = skip_ws_f(str);
2908*437bfbebSnyanmisaka if (!buf)
2909*437bfbebSnyanmisaka return rk_nok;
2910*437bfbebSnyanmisaka
2911*437bfbebSnyanmisaka ret = mpp_cfg_get_object(&object, NULL, MPP_CFG_TYPE_OBJECT, NULL);
2912*437bfbebSnyanmisaka if (ret || !object) {
2913*437bfbebSnyanmisaka mpp_loge_f("failed to create top object\n");
2914*437bfbebSnyanmisaka return rk_nok;
2915*437bfbebSnyanmisaka }
2916*437bfbebSnyanmisaka
2917*437bfbebSnyanmisaka do {
2918*437bfbebSnyanmisaka /* parse section */
2919*437bfbebSnyanmisaka ret = parse_toml_section(object, str);
2920*437bfbebSnyanmisaka if (ret) {
2921*437bfbebSnyanmisaka mpp_loge_f("failed to parse section, ret : %d.\n", ret);
2922*437bfbebSnyanmisaka return rk_nok;
2923*437bfbebSnyanmisaka }
2924*437bfbebSnyanmisaka
2925*437bfbebSnyanmisaka buf = skip_ws_f(str);
2926*437bfbebSnyanmisaka if (!buf)
2927*437bfbebSnyanmisaka break;
2928*437bfbebSnyanmisaka } while (1);
2929*437bfbebSnyanmisaka
2930*437bfbebSnyanmisaka *obj = object;
2931*437bfbebSnyanmisaka
2932*437bfbebSnyanmisaka return ret;
2933*437bfbebSnyanmisaka }
2934*437bfbebSnyanmisaka
mpp_cfg_dump(MppCfgObj obj,const char * func)2935*437bfbebSnyanmisaka void mpp_cfg_dump(MppCfgObj obj, const char *func)
2936*437bfbebSnyanmisaka {
2937*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
2938*437bfbebSnyanmisaka MppCfgStrBuf str;
2939*437bfbebSnyanmisaka rk_s32 ret;
2940*437bfbebSnyanmisaka
2941*437bfbebSnyanmisaka if (!obj) {
2942*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p at %s\n", obj, func);
2943*437bfbebSnyanmisaka return;
2944*437bfbebSnyanmisaka }
2945*437bfbebSnyanmisaka
2946*437bfbebSnyanmisaka mpp_logi_f("obj %s - %p at %s\n", impl->name ? impl->name : "n/a", impl, func);
2947*437bfbebSnyanmisaka
2948*437bfbebSnyanmisaka str.buf_size = 4096;
2949*437bfbebSnyanmisaka str.buf = mpp_malloc_size(void, str.buf_size);
2950*437bfbebSnyanmisaka str.offset = 0;
2951*437bfbebSnyanmisaka str.depth = 0;
2952*437bfbebSnyanmisaka str.type = MPP_CFG_STR_FMT_LOG;
2953*437bfbebSnyanmisaka
2954*437bfbebSnyanmisaka ret = mpp_cfg_to_log(impl, &str);
2955*437bfbebSnyanmisaka if (ret)
2956*437bfbebSnyanmisaka mpp_loge_f("failed to get log buffer\n");
2957*437bfbebSnyanmisaka else
2958*437bfbebSnyanmisaka mpp_cfg_print_string(str.buf);
2959*437bfbebSnyanmisaka
2960*437bfbebSnyanmisaka MPP_FREE(str.buf);
2961*437bfbebSnyanmisaka }
2962*437bfbebSnyanmisaka
mpp_cfg_to_string(MppCfgObj obj,MppCfgStrFmt fmt,char ** buf)2963*437bfbebSnyanmisaka rk_s32 mpp_cfg_to_string(MppCfgObj obj, MppCfgStrFmt fmt, char **buf)
2964*437bfbebSnyanmisaka {
2965*437bfbebSnyanmisaka MppCfgIoImpl *impl = (MppCfgIoImpl *)obj;
2966*437bfbebSnyanmisaka MppCfgStrBuf str;
2967*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
2968*437bfbebSnyanmisaka
2969*437bfbebSnyanmisaka if (!obj || !buf || fmt >= MPP_CFG_STR_FMT_BUTT) {
2970*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p fmt %d buf %p\n", obj, fmt, buf);
2971*437bfbebSnyanmisaka return ret;
2972*437bfbebSnyanmisaka }
2973*437bfbebSnyanmisaka
2974*437bfbebSnyanmisaka mpp_env_get_u32("mpp_cfg_io_debug", &mpp_cfg_io_debug, mpp_cfg_io_debug);
2975*437bfbebSnyanmisaka
2976*437bfbebSnyanmisaka str.buf_size = 4096;
2977*437bfbebSnyanmisaka str.buf = mpp_malloc_size(void, str.buf_size);
2978*437bfbebSnyanmisaka str.offset = 0;
2979*437bfbebSnyanmisaka str.depth = 0;
2980*437bfbebSnyanmisaka str.type = fmt;
2981*437bfbebSnyanmisaka
2982*437bfbebSnyanmisaka switch (fmt) {
2983*437bfbebSnyanmisaka case MPP_CFG_STR_FMT_LOG : {
2984*437bfbebSnyanmisaka ret = mpp_cfg_to_log(impl, &str);
2985*437bfbebSnyanmisaka } break;
2986*437bfbebSnyanmisaka case MPP_CFG_STR_FMT_JSON : {
2987*437bfbebSnyanmisaka ret = mpp_cfg_to_json(impl, &str);
2988*437bfbebSnyanmisaka } break;
2989*437bfbebSnyanmisaka case MPP_CFG_STR_FMT_TOML : {
2990*437bfbebSnyanmisaka ret = mpp_cfg_to_toml(impl, &str, 1);
2991*437bfbebSnyanmisaka } break;
2992*437bfbebSnyanmisaka default : {
2993*437bfbebSnyanmisaka mpp_loge_f("invalid formoffset %d\n", fmt);
2994*437bfbebSnyanmisaka } break;
2995*437bfbebSnyanmisaka }
2996*437bfbebSnyanmisaka
2997*437bfbebSnyanmisaka if (ret) {
2998*437bfbebSnyanmisaka mpp_loge_f("%p %s failed to get string buffer\n", impl, impl->name);
2999*437bfbebSnyanmisaka MPP_FREE(str.buf);
3000*437bfbebSnyanmisaka }
3001*437bfbebSnyanmisaka
3002*437bfbebSnyanmisaka *buf = str.buf;
3003*437bfbebSnyanmisaka return ret;
3004*437bfbebSnyanmisaka }
3005*437bfbebSnyanmisaka
mpp_cfg_from_string(MppCfgObj * obj,MppCfgStrFmt fmt,const char * buf)3006*437bfbebSnyanmisaka rk_s32 mpp_cfg_from_string(MppCfgObj *obj, MppCfgStrFmt fmt, const char *buf)
3007*437bfbebSnyanmisaka {
3008*437bfbebSnyanmisaka MppCfgObj object = NULL;
3009*437bfbebSnyanmisaka rk_s32 size;
3010*437bfbebSnyanmisaka rk_s32 ret = rk_nok;
3011*437bfbebSnyanmisaka
3012*437bfbebSnyanmisaka if (!obj || fmt >= MPP_CFG_STR_FMT_BUTT || !buf) {
3013*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p fmt %d buf %p\n", obj, fmt, buf);
3014*437bfbebSnyanmisaka return ret;
3015*437bfbebSnyanmisaka }
3016*437bfbebSnyanmisaka
3017*437bfbebSnyanmisaka mpp_env_get_u32("mpp_cfg_io_debug", &mpp_cfg_io_debug, mpp_cfg_io_debug);
3018*437bfbebSnyanmisaka
3019*437bfbebSnyanmisaka size = strlen(buf);
3020*437bfbebSnyanmisaka if (size) {
3021*437bfbebSnyanmisaka MppCfgStrBuf str;
3022*437bfbebSnyanmisaka
3023*437bfbebSnyanmisaka size++;
3024*437bfbebSnyanmisaka
3025*437bfbebSnyanmisaka str.buf = (char *)buf;
3026*437bfbebSnyanmisaka str.buf_size = size;
3027*437bfbebSnyanmisaka str.offset = 0;
3028*437bfbebSnyanmisaka str.depth = 0;
3029*437bfbebSnyanmisaka str.type = fmt;
3030*437bfbebSnyanmisaka
3031*437bfbebSnyanmisaka cfg_io_dbg_from("buf %p size %d\n", buf, size);
3032*437bfbebSnyanmisaka cfg_io_dbg_from("%s", buf);
3033*437bfbebSnyanmisaka
3034*437bfbebSnyanmisaka switch (fmt) {
3035*437bfbebSnyanmisaka case MPP_CFG_STR_FMT_LOG : {
3036*437bfbebSnyanmisaka ret = mpp_cfg_from_log(&object, &str);
3037*437bfbebSnyanmisaka } break;
3038*437bfbebSnyanmisaka case MPP_CFG_STR_FMT_JSON : {
3039*437bfbebSnyanmisaka ret = mpp_cfg_from_json(&object, &str);
3040*437bfbebSnyanmisaka } break;
3041*437bfbebSnyanmisaka case MPP_CFG_STR_FMT_TOML : {
3042*437bfbebSnyanmisaka ret = mpp_cfg_from_toml(&object, &str);
3043*437bfbebSnyanmisaka } break;
3044*437bfbebSnyanmisaka default : {
3045*437bfbebSnyanmisaka mpp_loge_f("invalid formoffset %d\n", fmt);
3046*437bfbebSnyanmisaka } break;
3047*437bfbebSnyanmisaka }
3048*437bfbebSnyanmisaka }
3049*437bfbebSnyanmisaka
3050*437bfbebSnyanmisaka if (ret)
3051*437bfbebSnyanmisaka mpp_loge_f("buf %p size %d failed to get object\n", buf, size);
3052*437bfbebSnyanmisaka
3053*437bfbebSnyanmisaka *obj = object;
3054*437bfbebSnyanmisaka return ret;
3055*437bfbebSnyanmisaka }
3056*437bfbebSnyanmisaka
write_struct(MppCfgIoImpl * obj,MppTrie trie,MppCfgStrBuf * str,void * st)3057*437bfbebSnyanmisaka static void write_struct(MppCfgIoImpl *obj, MppTrie trie, MppCfgStrBuf *str, void *st)
3058*437bfbebSnyanmisaka {
3059*437bfbebSnyanmisaka MppCfgInfo *tbl = NULL;
3060*437bfbebSnyanmisaka
3061*437bfbebSnyanmisaka if (obj->name) {
3062*437bfbebSnyanmisaka MppTrieInfo *info = NULL;
3063*437bfbebSnyanmisaka
3064*437bfbebSnyanmisaka /* use string to index the location table */
3065*437bfbebSnyanmisaka get_full_name(obj, str->buf, str->buf_size);
3066*437bfbebSnyanmisaka
3067*437bfbebSnyanmisaka info = mpp_trie_get_info(trie, str->buf);
3068*437bfbebSnyanmisaka if (info)
3069*437bfbebSnyanmisaka tbl = mpp_trie_info_ctx(info);
3070*437bfbebSnyanmisaka }
3071*437bfbebSnyanmisaka
3072*437bfbebSnyanmisaka if (!tbl)
3073*437bfbebSnyanmisaka tbl = &obj->info;
3074*437bfbebSnyanmisaka
3075*437bfbebSnyanmisaka cfg_io_dbg_show("depth %d obj type %s name %s -> info %s offset %d size %d\n",
3076*437bfbebSnyanmisaka obj->depth, strof_type(obj->type), obj->name ? str->buf : "null",
3077*437bfbebSnyanmisaka strof_cfg_type(tbl->data_type), tbl->data_offset, tbl->data_size);
3078*437bfbebSnyanmisaka
3079*437bfbebSnyanmisaka if (tbl->data_type < CFG_FUNC_TYPE_BUTT) {
3080*437bfbebSnyanmisaka switch (tbl->data_type) {
3081*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s32 : {
3082*437bfbebSnyanmisaka mpp_cfg_set_s32(tbl, st, obj->val.s32);
3083*437bfbebSnyanmisaka } break;
3084*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u32 : {
3085*437bfbebSnyanmisaka mpp_cfg_set_u32(tbl, st, obj->val.u32);
3086*437bfbebSnyanmisaka } break;
3087*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s64 : {
3088*437bfbebSnyanmisaka mpp_cfg_set_s64(tbl, st, obj->val.s64);
3089*437bfbebSnyanmisaka } break;
3090*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u64 : {
3091*437bfbebSnyanmisaka mpp_cfg_set_u64(tbl, st, obj->val.u64);
3092*437bfbebSnyanmisaka } break;
3093*437bfbebSnyanmisaka default : {
3094*437bfbebSnyanmisaka } break;
3095*437bfbebSnyanmisaka }
3096*437bfbebSnyanmisaka }
3097*437bfbebSnyanmisaka
3098*437bfbebSnyanmisaka {
3099*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
3100*437bfbebSnyanmisaka
3101*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &obj->child, MppCfgIoImpl, list) {
3102*437bfbebSnyanmisaka write_struct(pos, trie, str, st);
3103*437bfbebSnyanmisaka }
3104*437bfbebSnyanmisaka }
3105*437bfbebSnyanmisaka }
3106*437bfbebSnyanmisaka
mpp_cfg_to_struct(MppCfgObj obj,MppCfgObj type,void * st)3107*437bfbebSnyanmisaka rk_s32 mpp_cfg_to_struct(MppCfgObj obj, MppCfgObj type, void *st)
3108*437bfbebSnyanmisaka {
3109*437bfbebSnyanmisaka MppCfgIoImpl *orig;
3110*437bfbebSnyanmisaka MppCfgIoImpl *impl;
3111*437bfbebSnyanmisaka MppTrie trie;
3112*437bfbebSnyanmisaka MppCfgStrBuf str;
3113*437bfbebSnyanmisaka char name[256] = { 0 };
3114*437bfbebSnyanmisaka
3115*437bfbebSnyanmisaka if (!obj || !st) {
3116*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p st %p\n", obj, st);
3117*437bfbebSnyanmisaka return rk_nok;
3118*437bfbebSnyanmisaka }
3119*437bfbebSnyanmisaka
3120*437bfbebSnyanmisaka impl = (MppCfgIoImpl *)obj;
3121*437bfbebSnyanmisaka orig = (MppCfgIoImpl *)type;
3122*437bfbebSnyanmisaka trie = mpp_cfg_to_trie(orig);
3123*437bfbebSnyanmisaka
3124*437bfbebSnyanmisaka str.buf = name;
3125*437bfbebSnyanmisaka str.buf_size = sizeof(name) - 1;
3126*437bfbebSnyanmisaka str.offset = 0;
3127*437bfbebSnyanmisaka str.depth = 0;
3128*437bfbebSnyanmisaka
3129*437bfbebSnyanmisaka write_struct(impl, trie, &str, st + orig->info.data_offset);
3130*437bfbebSnyanmisaka
3131*437bfbebSnyanmisaka return rk_ok;
3132*437bfbebSnyanmisaka }
3133*437bfbebSnyanmisaka
read_struct(MppCfgIoImpl * impl,MppCfgObj parent,void * st)3134*437bfbebSnyanmisaka static MppCfgObj read_struct(MppCfgIoImpl *impl, MppCfgObj parent, void *st)
3135*437bfbebSnyanmisaka {
3136*437bfbebSnyanmisaka MppCfgInfo *info = &impl->info;
3137*437bfbebSnyanmisaka MppCfgIoImpl *ret = NULL;
3138*437bfbebSnyanmisaka
3139*437bfbebSnyanmisaka /* dup node first */
3140*437bfbebSnyanmisaka ret = mpp_calloc_size(MppCfgIoImpl, impl->buf_size);
3141*437bfbebSnyanmisaka if (!ret) {
3142*437bfbebSnyanmisaka mpp_loge_f("failed to alloc impl size %d\n", impl->buf_size);
3143*437bfbebSnyanmisaka return NULL;
3144*437bfbebSnyanmisaka }
3145*437bfbebSnyanmisaka
3146*437bfbebSnyanmisaka INIT_LIST_HEAD(&ret->list);
3147*437bfbebSnyanmisaka INIT_LIST_HEAD(&ret->child);
3148*437bfbebSnyanmisaka
3149*437bfbebSnyanmisaka ret->type = impl->type;
3150*437bfbebSnyanmisaka ret->buf_size = impl->buf_size;
3151*437bfbebSnyanmisaka
3152*437bfbebSnyanmisaka if (impl->name_buf_len) {
3153*437bfbebSnyanmisaka ret->name = (char *)(ret + 1);
3154*437bfbebSnyanmisaka memcpy(ret->name, impl->name, impl->name_buf_len);
3155*437bfbebSnyanmisaka ret->name_len = impl->name_len;
3156*437bfbebSnyanmisaka ret->name_buf_len = impl->name_buf_len;
3157*437bfbebSnyanmisaka }
3158*437bfbebSnyanmisaka
3159*437bfbebSnyanmisaka /* assign value by different type */
3160*437bfbebSnyanmisaka switch (info->data_type) {
3161*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s32 :
3162*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u32 :
3163*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s64 :
3164*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u64 : {
3165*437bfbebSnyanmisaka switch (info->data_type) {
3166*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s32 : {
3167*437bfbebSnyanmisaka mpp_assert(impl->type == MPP_CFG_TYPE_s32);
3168*437bfbebSnyanmisaka mpp_cfg_get_s32(info, st, &ret->val.s32);
3169*437bfbebSnyanmisaka } break;
3170*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u32 : {
3171*437bfbebSnyanmisaka mpp_assert(impl->type == MPP_CFG_TYPE_u32);
3172*437bfbebSnyanmisaka mpp_cfg_get_u32(info, st, &ret->val.u32);
3173*437bfbebSnyanmisaka } break;
3174*437bfbebSnyanmisaka case CFG_FUNC_TYPE_s64 : {
3175*437bfbebSnyanmisaka mpp_assert(impl->type == MPP_CFG_TYPE_s64);
3176*437bfbebSnyanmisaka mpp_cfg_get_s64(info, st, &ret->val.s64);
3177*437bfbebSnyanmisaka } break;
3178*437bfbebSnyanmisaka case CFG_FUNC_TYPE_u64 : {
3179*437bfbebSnyanmisaka mpp_assert(impl->type == MPP_CFG_TYPE_u64);
3180*437bfbebSnyanmisaka mpp_cfg_get_u64(info, st, &ret->val.u64);
3181*437bfbebSnyanmisaka } break;
3182*437bfbebSnyanmisaka default : {
3183*437bfbebSnyanmisaka } break;
3184*437bfbebSnyanmisaka }
3185*437bfbebSnyanmisaka } break;
3186*437bfbebSnyanmisaka case CFG_FUNC_TYPE_st :
3187*437bfbebSnyanmisaka case CFG_FUNC_TYPE_ptr : {
3188*437bfbebSnyanmisaka ret->val = impl->val;
3189*437bfbebSnyanmisaka } break;
3190*437bfbebSnyanmisaka default : {
3191*437bfbebSnyanmisaka } break;
3192*437bfbebSnyanmisaka }
3193*437bfbebSnyanmisaka
3194*437bfbebSnyanmisaka cfg_io_dbg_show("depth %d obj type %s name %s\n", ret->depth,
3195*437bfbebSnyanmisaka strof_type(ret->type), ret->name);
3196*437bfbebSnyanmisaka
3197*437bfbebSnyanmisaka if (parent)
3198*437bfbebSnyanmisaka mpp_cfg_add(parent, ret);
3199*437bfbebSnyanmisaka
3200*437bfbebSnyanmisaka {
3201*437bfbebSnyanmisaka MppCfgIoImpl *pos, *n;
3202*437bfbebSnyanmisaka
3203*437bfbebSnyanmisaka list_for_each_entry_safe(pos, n, &impl->child, MppCfgIoImpl, list) {
3204*437bfbebSnyanmisaka read_struct(pos, ret, st);
3205*437bfbebSnyanmisaka }
3206*437bfbebSnyanmisaka }
3207*437bfbebSnyanmisaka
3208*437bfbebSnyanmisaka return ret;
3209*437bfbebSnyanmisaka }
3210*437bfbebSnyanmisaka
mpp_cfg_from_struct(MppCfgObj * obj,MppCfgObj type,void * st)3211*437bfbebSnyanmisaka rk_s32 mpp_cfg_from_struct(MppCfgObj *obj, MppCfgObj type, void *st)
3212*437bfbebSnyanmisaka {
3213*437bfbebSnyanmisaka MppCfgIoImpl *orig = (MppCfgIoImpl *)type;
3214*437bfbebSnyanmisaka
3215*437bfbebSnyanmisaka if (!obj || !type || !st) {
3216*437bfbebSnyanmisaka mpp_loge_f("invalid param obj %p type %p st %p\n", obj, type, st);
3217*437bfbebSnyanmisaka return rk_nok;
3218*437bfbebSnyanmisaka }
3219*437bfbebSnyanmisaka
3220*437bfbebSnyanmisaka /* NOTE: update structure pointer by data_offset */
3221*437bfbebSnyanmisaka *obj = read_struct(orig, NULL, st + orig->info.data_offset);
3222*437bfbebSnyanmisaka
3223*437bfbebSnyanmisaka return *obj ? rk_ok : rk_nok;
3224*437bfbebSnyanmisaka }
3225*437bfbebSnyanmisaka
mpp_cfg_print_string(char * buf)3226*437bfbebSnyanmisaka rk_s32 mpp_cfg_print_string(char *buf)
3227*437bfbebSnyanmisaka {
3228*437bfbebSnyanmisaka rk_s32 start = 0;
3229*437bfbebSnyanmisaka rk_s32 pos = 0;
3230*437bfbebSnyanmisaka rk_s32 len = strlen(buf);
3231*437bfbebSnyanmisaka
3232*437bfbebSnyanmisaka /* it may be a very long string, split by \n to different line and print */
3233*437bfbebSnyanmisaka for (pos = 0; pos < len; pos++) {
3234*437bfbebSnyanmisaka if (buf[pos] == '\n') {
3235*437bfbebSnyanmisaka buf[pos] = '\0';
3236*437bfbebSnyanmisaka mpp_logi("%s\n", &buf[start]);
3237*437bfbebSnyanmisaka buf[pos] = '\n';
3238*437bfbebSnyanmisaka start = pos + 1;
3239*437bfbebSnyanmisaka }
3240*437bfbebSnyanmisaka }
3241*437bfbebSnyanmisaka
3242*437bfbebSnyanmisaka return rk_ok;
3243*437bfbebSnyanmisaka }
3244