]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - LinuxGUI/Ventoy2Disk/Core/ventoy_json.c
1 /******************************************************************************
4 * Copyright (c) 2021, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 #include <ventoy_define.h>
29 #include <ventoy_util.h>
30 #include <ventoy_json.h>
32 static void vtoy_json_free(VTOY_JSON
*pstJsonHead
)
34 VTOY_JSON
*pstNext
= NULL
;
36 while (NULL
!= pstJsonHead
)
38 pstNext
= pstJsonHead
->pstNext
;
39 if ((pstJsonHead
->enDataType
< JSON_TYPE_BUTT
) && (NULL
!= pstJsonHead
->pstChild
))
41 vtoy_json_free(pstJsonHead
->pstChild
);
45 pstJsonHead
= pstNext
;
51 static char *vtoy_json_skip(const char *pcData
)
53 while ((NULL
!= pcData
) && ('\0' != *pcData
) && (*pcData
<= 32))
58 return (char *)pcData
;
61 VTOY_JSON
*vtoy_json_find_item
68 while (NULL
!= pstJson
)
70 if ((enDataType
== pstJson
->enDataType
) &&
71 (0 == strcmp(szKey
, pstJson
->pcName
)))
75 pstJson
= pstJson
->pstNext
;
81 static int vtoy_json_parse_number
90 Value
= strtoul(pcData
, (char **)ppcEnd
, 10);
91 if (*ppcEnd
== pcData
)
93 vdebug("Failed to parse json number %s.\n", pcData
);
97 pstJson
->enDataType
= JSON_TYPE_NUMBER
;
98 pstJson
->unData
.lValue
= Value
;
103 static int vtoy_json_parse_string
113 const char *pcPos
= NULL
;
114 const char *pcTmp
= pcData
+ 1;
123 pcPos
= strchr(pcTmp
, '\"');
124 if ((NULL
== pcPos
) || (pcPos
< pcTmp
))
126 vdebug("Invalid string %s.\n", pcData
);
131 uiLen
= (uint32_t)(unsigned long)(pcPos
- pcTmp
);
133 pstJson
->enDataType
= JSON_TYPE_STRING
;
134 pstJson
->unData
.pcStrVal
= pcNewStart
+ (pcTmp
- pcRawStart
);
135 pstJson
->unData
.pcStrVal
[uiLen
] = '\0';
140 static int vtoy_json_parse_array
149 int Ret
= JSON_SUCCESS
;
150 VTOY_JSON
*pstJsonChild
= NULL
;
151 VTOY_JSON
*pstJsonItem
= NULL
;
152 const char *pcTmp
= pcData
+ 1;
155 pstJson
->enDataType
= JSON_TYPE_ARRAY
;
162 pcTmp
= vtoy_json_skip(pcTmp
);
170 JSON_NEW_ITEM(pstJson
->pstChild
, JSON_FAILED
);
172 Ret
= vtoy_json_parse_value(pcNewStart
, pcRawStart
, pstJson
->pstChild
, pcTmp
, ppcEnd
);
173 if (JSON_SUCCESS
!= Ret
)
175 vdebug("Failed to parse array child.\n");
179 pstJsonChild
= pstJson
->pstChild
;
180 pcTmp
= vtoy_json_skip(*ppcEnd
);
181 while ((NULL
!= pcTmp
) && (',' == *pcTmp
))
183 JSON_NEW_ITEM(pstJsonItem
, JSON_FAILED
);
184 pstJsonChild
->pstNext
= pstJsonItem
;
185 pstJsonItem
->pstPrev
= pstJsonChild
;
186 pstJsonChild
= pstJsonItem
;
188 Ret
= vtoy_json_parse_value(pcNewStart
, pcRawStart
, pstJsonChild
, vtoy_json_skip(pcTmp
+ 1), ppcEnd
);
189 if (JSON_SUCCESS
!= Ret
)
191 vdebug("Failed to parse array child.\n");
194 pcTmp
= vtoy_json_skip(*ppcEnd
);
197 if ((NULL
!= pcTmp
) && (']' == *pcTmp
))
209 static int vtoy_json_parse_object
218 int Ret
= JSON_SUCCESS
;
219 VTOY_JSON
*pstJsonChild
= NULL
;
220 VTOY_JSON
*pstJsonItem
= NULL
;
221 const char *pcTmp
= pcData
+ 1;
224 pstJson
->enDataType
= JSON_TYPE_OBJECT
;
231 pcTmp
= vtoy_json_skip(pcTmp
);
238 JSON_NEW_ITEM(pstJson
->pstChild
, JSON_FAILED
);
240 Ret
= vtoy_json_parse_string(pcNewStart
, pcRawStart
, pstJson
->pstChild
, pcTmp
, ppcEnd
);
241 if (JSON_SUCCESS
!= Ret
)
243 vdebug("Failed to parse array child.\n");
247 pstJsonChild
= pstJson
->pstChild
;
248 pstJsonChild
->pcName
= pstJsonChild
->unData
.pcStrVal
;
249 pstJsonChild
->unData
.pcStrVal
= NULL
;
251 pcTmp
= vtoy_json_skip(*ppcEnd
);
252 if ((NULL
== pcTmp
) || (':' != *pcTmp
))
258 Ret
= vtoy_json_parse_value(pcNewStart
, pcRawStart
, pstJsonChild
, vtoy_json_skip(pcTmp
+ 1), ppcEnd
);
259 if (JSON_SUCCESS
!= Ret
)
261 vdebug("Failed to parse array child.\n");
265 pcTmp
= vtoy_json_skip(*ppcEnd
);
266 while ((NULL
!= pcTmp
) && (',' == *pcTmp
))
268 JSON_NEW_ITEM(pstJsonItem
, JSON_FAILED
);
269 pstJsonChild
->pstNext
= pstJsonItem
;
270 pstJsonItem
->pstPrev
= pstJsonChild
;
271 pstJsonChild
= pstJsonItem
;
273 Ret
= vtoy_json_parse_string(pcNewStart
, pcRawStart
, pstJsonChild
, vtoy_json_skip(pcTmp
+ 1), ppcEnd
);
274 if (JSON_SUCCESS
!= Ret
)
276 vdebug("Failed to parse array child.\n");
280 pcTmp
= vtoy_json_skip(*ppcEnd
);
281 pstJsonChild
->pcName
= pstJsonChild
->unData
.pcStrVal
;
282 pstJsonChild
->unData
.pcStrVal
= NULL
;
283 if ((NULL
== pcTmp
) || (':' != *pcTmp
))
289 Ret
= vtoy_json_parse_value(pcNewStart
, pcRawStart
, pstJsonChild
, vtoy_json_skip(pcTmp
+ 1), ppcEnd
);
290 if (JSON_SUCCESS
!= Ret
)
292 vdebug("Failed to parse array child.\n");
296 pcTmp
= vtoy_json_skip(*ppcEnd
);
299 if ((NULL
!= pcTmp
) && ('}' == *pcTmp
))
311 int vtoy_json_parse_value
320 pcData
= vtoy_json_skip(pcData
);
326 if (0 == strncmp(pcData
, "null", 4))
328 pstJson
->enDataType
= JSON_TYPE_NULL
;
329 *ppcEnd
= pcData
+ 4;
336 if (0 == strncmp(pcData
, "false", 5))
338 pstJson
->enDataType
= JSON_TYPE_BOOL
;
339 pstJson
->unData
.lValue
= 0;
340 *ppcEnd
= pcData
+ 5;
347 if (0 == strncmp(pcData
, "true", 4))
349 pstJson
->enDataType
= JSON_TYPE_BOOL
;
350 pstJson
->unData
.lValue
= 1;
351 *ppcEnd
= pcData
+ 4;
358 return vtoy_json_parse_string(pcNewStart
, pcRawStart
, pstJson
, pcData
, ppcEnd
);
362 return vtoy_json_parse_array(pcNewStart
, pcRawStart
, pstJson
, pcData
, ppcEnd
);
366 return vtoy_json_parse_object(pcNewStart
, pcRawStart
, pstJson
, pcData
, ppcEnd
);
370 return vtoy_json_parse_number(pstJson
, pcData
, ppcEnd
);
374 if (*pcData
>= '0' && *pcData
<= '9')
376 return vtoy_json_parse_number(pstJson
, pcData
, ppcEnd
);
382 vdebug("Invalid json data %u.\n", (uint8_t)(*pcData
));
386 VTOY_JSON
* vtoy_json_create(void)
388 VTOY_JSON
*pstJson
= NULL
;
390 pstJson
= (VTOY_JSON
*)zalloc(sizeof(VTOY_JSON
));
399 int vtoy_json_parse(VTOY_JSON
*pstJson
, const char *szJsonData
)
401 uint32_t uiMemSize
= 0;
402 int Ret
= JSON_SUCCESS
;
403 char *pcNewBuf
= NULL
;
404 const char *pcEnd
= NULL
;
406 uiMemSize
= strlen(szJsonData
) + 1;
407 pcNewBuf
= (char *)malloc(uiMemSize
);
408 if (NULL
== pcNewBuf
)
410 vdebug("Failed to alloc new buf.\n");
413 memcpy(pcNewBuf
, szJsonData
, uiMemSize
);
414 pcNewBuf
[uiMemSize
- 1] = 0;
416 Ret
= vtoy_json_parse_value(pcNewBuf
, (char *)szJsonData
, pstJson
, szJsonData
, &pcEnd
);
417 if (JSON_SUCCESS
!= Ret
)
419 vdebug("Failed to parse json data %s start=%p, end=%p:%s.\n",
420 szJsonData
, szJsonData
, pcEnd
, pcEnd
);
427 int vtoy_json_scan_parse
429 const VTOY_JSON
*pstJson
,
431 VTOY_JSON_PARSE_S
*pstJsonParse
435 const VTOY_JSON
*pstJsonCur
= NULL
;
436 VTOY_JSON_PARSE_S
*pstCurParse
= NULL
;
438 for (pstJsonCur
= pstJson
; NULL
!= pstJsonCur
; pstJsonCur
= pstJsonCur
->pstNext
)
440 if ((JSON_TYPE_OBJECT
== pstJsonCur
->enDataType
) ||
441 (JSON_TYPE_ARRAY
== pstJsonCur
->enDataType
))
446 for (i
= 0, pstCurParse
= NULL
; i
< uiParseNum
; i
++)
448 if (0 == strcmp(pstJsonParse
[i
].pcKey
, pstJsonCur
->pcName
))
450 pstCurParse
= pstJsonParse
+ i
;
455 if (NULL
== pstCurParse
)
460 switch (pstJsonCur
->enDataType
)
462 case JSON_TYPE_NUMBER
:
464 if (sizeof(uint32_t) == pstCurParse
->uiBufSize
)
466 *(uint32_t *)(pstCurParse
->pDataBuf
) = (uint32_t)pstJsonCur
->unData
.lValue
;
468 else if (sizeof(uint16_t) == pstCurParse
->uiBufSize
)
470 *(uint16_t *)(pstCurParse
->pDataBuf
) = (uint16_t)pstJsonCur
->unData
.lValue
;
472 else if (sizeof(uint8_t) == pstCurParse
->uiBufSize
)
474 *(uint8_t *)(pstCurParse
->pDataBuf
) = (uint8_t)pstJsonCur
->unData
.lValue
;
476 else if ((pstCurParse
->uiBufSize
> sizeof(uint64_t)))
478 snprintf((char *)pstCurParse
->pDataBuf
, pstCurParse
->uiBufSize
, "%llu",
479 (unsigned long long)(pstJsonCur
->unData
.lValue
));
483 vdebug("Invalid number data buf size %u.\n", pstCurParse
->uiBufSize
);
487 case JSON_TYPE_STRING
:
489 strncpy((char *)pstCurParse
->pDataBuf
, pstJsonCur
->unData
.pcStrVal
, pstCurParse
->uiBufSize
);
494 *(uint8_t *)(pstCurParse
->pDataBuf
) = (pstJsonCur
->unData
.lValue
) > 0 ? 1 : 0;
507 int vtoy_json_scan_array
511 VTOY_JSON
**ppstArrayItem
514 VTOY_JSON
*pstJsonItem
= NULL
;
516 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_ARRAY
, szKey
);
517 if (NULL
== pstJsonItem
)
519 vdebug("Key %s is not found in json data.\n", szKey
);
520 return JSON_NOT_FOUND
;
523 *ppstArrayItem
= pstJsonItem
;
528 int vtoy_json_scan_array_ex
532 VTOY_JSON
**ppstArrayItem
535 VTOY_JSON
*pstJsonItem
= NULL
;
537 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_ARRAY
, szKey
);
538 if (NULL
== pstJsonItem
)
540 vdebug("Key %s is not found in json data.\n", szKey
);
541 return JSON_NOT_FOUND
;
544 *ppstArrayItem
= pstJsonItem
->pstChild
;
549 int vtoy_json_scan_object
553 VTOY_JSON
**ppstObjectItem
556 VTOY_JSON
*pstJsonItem
= NULL
;
558 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_OBJECT
, szKey
);
559 if (NULL
== pstJsonItem
)
561 vdebug("Key %s is not found in json data.\n", szKey
);
562 return JSON_NOT_FOUND
;
565 *ppstObjectItem
= pstJsonItem
;
570 int vtoy_json_get_int
577 VTOY_JSON
*pstJsonItem
= NULL
;
579 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_NUMBER
, szKey
);
580 if (NULL
== pstJsonItem
)
582 vdebug("Key %s is not found in json data.\n", szKey
);
583 return JSON_NOT_FOUND
;
586 *piValue
= (int)pstJsonItem
->unData
.lValue
;
591 int vtoy_json_get_uint
598 VTOY_JSON
*pstJsonItem
= NULL
;
600 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_NUMBER
, szKey
);
601 if (NULL
== pstJsonItem
)
603 vdebug("Key %s is not found in json data.\n", szKey
);
604 return JSON_NOT_FOUND
;
607 *puiValue
= (uint32_t)pstJsonItem
->unData
.lValue
;
612 int vtoy_json_get_uint64
619 VTOY_JSON
*pstJsonItem
= NULL
;
621 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_NUMBER
, szKey
);
622 if (NULL
== pstJsonItem
)
624 vdebug("Key %s is not found in json data.\n", szKey
);
625 return JSON_NOT_FOUND
;
628 *pui64Value
= (uint64_t)pstJsonItem
->unData
.lValue
;
633 int vtoy_json_get_bool
640 VTOY_JSON
*pstJsonItem
= NULL
;
642 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_BOOL
, szKey
);
643 if (NULL
== pstJsonItem
)
645 vdebug("Key %s is not found in json data.\n", szKey
);
646 return JSON_NOT_FOUND
;
649 *pbValue
= pstJsonItem
->unData
.lValue
> 0 ? 1 : 0;
654 int vtoy_json_get_string
662 VTOY_JSON
*pstJsonItem
= NULL
;
664 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_STRING
, szKey
);
665 if (NULL
== pstJsonItem
)
667 vdebug("Key %s is not found in json data.\n", szKey
);
668 return JSON_NOT_FOUND
;
671 strncpy(pcBuf
, pstJsonItem
->unData
.pcStrVal
, uiBufLen
);
676 const char * vtoy_json_get_string_ex(VTOY_JSON
*pstJson
, const char *szKey
)
678 VTOY_JSON
*pstJsonItem
= NULL
;
680 if ((NULL
== pstJson
) || (NULL
== szKey
))
685 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_STRING
, szKey
);
686 if (NULL
== pstJsonItem
)
688 vdebug("Key %s is not found in json data.\n", szKey
);
692 return pstJsonItem
->unData
.pcStrVal
;
695 int vtoy_json_destroy(VTOY_JSON
*pstJson
)
702 if (NULL
!= pstJson
->pstChild
)
704 vtoy_json_free(pstJson
->pstChild
);
707 if (NULL
!= pstJson
->pstNext
)
709 vtoy_json_free(pstJson
->pstNext
);