xref: /rockchip-linux_mpp/mpp/base/mpp_cfg_io.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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