]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Ventoy2Disk/Ventoy2Disk/VentoyJson.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/>.
21 #ifdef FOR_VTOY_JSON_CHECK
27 #include "Ventoy2Disk.h"
30 #include "VentoyJson.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 Log("Failed to parse json number %s.", 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 Log("Invalid string %s.", pcData
);
131 uiLen
= (UINT32
)(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 Log("Failed to parse array child.");
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 Log("Failed to parse array child.");
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 Log("Failed to parse array child.");
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 Log("Failed to parse array child.");
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 Log("Failed to parse array child.");
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 Log("Failed to parse array child.");
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 Log("Invalid json data %u.", (UINT8
)(*pcData
));
386 VTOY_JSON
* vtoy_json_create(void)
388 VTOY_JSON
*pstJson
= NULL
;
390 pstJson
= (VTOY_JSON
*)malloc(sizeof(VTOY_JSON
));
395 memset(pstJson
, 0, sizeof(VTOY_JSON
));
399 int vtoy_json_parse(VTOY_JSON
*pstJson
, const char *szJsonData
)
401 UINT32 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 Log("Failed to alloc new buf.");
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 Log("Failed to parse json data start=%p, end=%p", szJsonData
, pcEnd
);
426 int vtoy_json_scan_parse
428 const VTOY_JSON
*pstJson
,
430 JSON_PARSE
*pstJsonParse
434 const VTOY_JSON
*pstJsonCur
= NULL
;
435 JSON_PARSE
*pstCurParse
= NULL
;
437 for (pstJsonCur
= pstJson
; NULL
!= pstJsonCur
; pstJsonCur
= pstJsonCur
->pstNext
)
439 if ((JSON_TYPE_OBJECT
== pstJsonCur
->enDataType
) ||
440 (JSON_TYPE_ARRAY
== pstJsonCur
->enDataType
))
445 for (i
= 0, pstCurParse
= NULL
; i
< uiParseNum
; i
++)
447 if (0 == strcmp(pstJsonParse
[i
].pcKey
, pstJsonCur
->pcName
))
449 pstCurParse
= pstJsonParse
+ i
;
454 if (NULL
== pstCurParse
)
459 switch (pstJsonCur
->enDataType
)
461 case JSON_TYPE_NUMBER
:
463 if (sizeof(UINT32
) == pstCurParse
->uiBufSize
)
465 *(UINT32
*)(pstCurParse
->pDataBuf
) = (UINT32
)pstJsonCur
->unData
.lValue
;
467 else if (sizeof(UINT16
) == pstCurParse
->uiBufSize
)
469 *(UINT16
*)(pstCurParse
->pDataBuf
) = (UINT16
)pstJsonCur
->unData
.lValue
;
471 else if (sizeof(UINT8
) == pstCurParse
->uiBufSize
)
473 *(UINT8
*)(pstCurParse
->pDataBuf
) = (UINT8
)pstJsonCur
->unData
.lValue
;
475 else if ((pstCurParse
->uiBufSize
> sizeof(UINT64
)))
477 sprintf_s((char *)pstCurParse
->pDataBuf
, pstCurParse
->uiBufSize
, "%llu",
478 (unsigned long long)(pstJsonCur
->unData
.lValue
));
482 Log("Invalid number data buf size %u.", pstCurParse
->uiBufSize
);
486 case JSON_TYPE_STRING
:
488 strcpy_s((char *)pstCurParse
->pDataBuf
, pstCurParse
->uiBufSize
, pstJsonCur
->unData
.pcStrVal
);
493 *(UINT8
*)(pstCurParse
->pDataBuf
) = (pstJsonCur
->unData
.lValue
) > 0 ? 1 : 0;
506 int vtoy_json_scan_array
510 VTOY_JSON
**ppstArrayItem
513 VTOY_JSON
*pstJsonItem
= NULL
;
515 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_ARRAY
, szKey
);
516 if (NULL
== pstJsonItem
)
518 Log("Key %s is not found in json data.", szKey
);
519 return JSON_NOT_FOUND
;
522 *ppstArrayItem
= pstJsonItem
;
527 int vtoy_json_scan_array_ex
531 VTOY_JSON
**ppstArrayItem
534 VTOY_JSON
*pstJsonItem
= NULL
;
536 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_ARRAY
, szKey
);
537 if (NULL
== pstJsonItem
)
539 Log("Key %s is not found in json data.", szKey
);
540 return JSON_NOT_FOUND
;
543 *ppstArrayItem
= pstJsonItem
->pstChild
;
548 int vtoy_json_scan_object
552 VTOY_JSON
**ppstObjectItem
555 VTOY_JSON
*pstJsonItem
= NULL
;
557 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_OBJECT
, szKey
);
558 if (NULL
== pstJsonItem
)
560 Log("Key %s is not found in json data.", szKey
);
561 return JSON_NOT_FOUND
;
564 *ppstObjectItem
= pstJsonItem
;
569 int vtoy_json_get_int
576 VTOY_JSON
*pstJsonItem
= NULL
;
578 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_NUMBER
, szKey
);
579 if (NULL
== pstJsonItem
)
581 Log("Key %s is not found in json data.", szKey
);
582 return JSON_NOT_FOUND
;
585 *piValue
= (int)pstJsonItem
->unData
.lValue
;
590 int vtoy_json_get_uint
597 VTOY_JSON
*pstJsonItem
= NULL
;
599 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_NUMBER
, szKey
);
600 if (NULL
== pstJsonItem
)
602 Log("Key %s is not found in json data.", szKey
);
603 return JSON_NOT_FOUND
;
606 *puiValue
= (UINT32
)pstJsonItem
->unData
.lValue
;
611 int vtoy_json_get_uint64
618 VTOY_JSON
*pstJsonItem
= NULL
;
620 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_NUMBER
, szKey
);
621 if (NULL
== pstJsonItem
)
623 Log("Key %s is not found in json data.", szKey
);
624 return JSON_NOT_FOUND
;
627 *pui64Value
= (UINT64
)pstJsonItem
->unData
.lValue
;
632 int vtoy_json_get_bool
639 VTOY_JSON
*pstJsonItem
= NULL
;
641 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_BOOL
, szKey
);
642 if (NULL
== pstJsonItem
)
644 Log("Key %s is not found in json data.", szKey
);
645 return JSON_NOT_FOUND
;
648 *pbValue
= pstJsonItem
->unData
.lValue
> 0 ? 1 : 0;
653 int vtoy_json_get_string
661 VTOY_JSON
*pstJsonItem
= NULL
;
663 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_STRING
, szKey
);
664 if (NULL
== pstJsonItem
)
666 Log("Key %s is not found in json data.", szKey
);
667 return JSON_NOT_FOUND
;
670 strcpy_s(pcBuf
, uiBufLen
, pstJsonItem
->unData
.pcStrVal
);
675 const char * vtoy_json_get_string_ex(VTOY_JSON
*pstJson
, const char *szKey
)
677 VTOY_JSON
*pstJsonItem
= NULL
;
679 if ((NULL
== pstJson
) || (NULL
== szKey
))
684 pstJsonItem
= vtoy_json_find_item(pstJson
, JSON_TYPE_STRING
, szKey
);
685 if (NULL
== pstJsonItem
)
687 Log("Key %s is not found in json data.", szKey
);
691 return pstJsonItem
->unData
.pcStrVal
;
694 int vtoy_json_destroy(VTOY_JSON
*pstJson
)
701 if (NULL
!= pstJson
->pstChild
)
703 vtoy_json_free(pstJson
->pstChild
);
706 if (NULL
!= pstJson
->pstNext
)
708 vtoy_json_free(pstJson
->pstNext
);
717 #ifdef FOR_VTOY_JSON_CHECK
719 int main(int argc
, char**argv
)
725 VTOY_JSON
*json
= NULL
;
727 fp
= fopen(argv
[1], "rb");
730 Log("Failed to open %s\n", argv
[1]);
734 fseek(fp
, 0, SEEK_END
);
735 FileSize
= (int)ftell(fp
);
736 fseek(fp
, 0, SEEK_SET
);
738 Data
= malloc(FileSize
+ 4);
741 Log("Failed to malloc %d\n", FileSize
+ 4);
744 *((char *)Data
+ FileSize
) = 0;
746 fread(Data
, 1, FileSize
, fp
);
748 json
= vtoy_json_create();
751 Log("Failed vtoy_json_create\n");
755 if (vtoy_json_parse(json
, (char *)Data
) != JSON_SUCCESS
)
764 if (Data
) free(Data
);
765 if (json
) vtoy_json_destroy(json
);