为了更方便使用C的JSON库,对其进行了一层封装。
H文件:
1 #ifndef __JSONHELPER__ 2 #define __JSONHELPER__ 3 4 #ifdef __cplusplus 5 extern "C" 6 { 7 #endif 8 9 10 #define JSON_NAME_MAX_SIZE 128 11 12 enum 13 { 14 JSON_OK = 0, 15 JSON_ERROR, 16 JSON_ERR_NO_SUCH_NODE, 17 JSON_ERR_INVALID_NODE, 18 JSON_ERR_NO_SUCH_ARRAY, 19 JSON_ERR_INVALID_ARRAY_INDEX, 20 JSON_ERR_UNMATCH_TYPE 21 }; 22 23 #define JSON_ERROR_STRING "Okay\0" \ 24 "Error\0" \ 25 "No Such Node\0" \ 26 "Invalid Node\0" \ 27 "No Such Array\0" \ 28 "Invalid Array Index\0" \ 29 "Unmatch Type\0" 30 31 32 const char *jsonNodeType(void *json); 33 const char *jsonErrorString(int ret); 34 35 void *jsonParse(const char *text); 36 void jsonDelete(void *json); 37 void jsonDumpError(const char *text); 38 void jsonDump(void *json); 39 40 char *jsonToString(void *json, int format); 41 char *jsonToBuffer(void *json, int format, char *buffer, int len); 42 43 int jsonTestNumber(void *json); 44 int jsonTestString(void *json); 45 int jsonTestArray(void *json); 46 int jsonTestObject(void *json); 47 int jsonTestBool(void *json); 48 49 void *jsonGetNode(void *json, const char *node, int *ret); 50 int jsonGetString(void *json, const char *node, char *buf, int len); 51 int jsonGetInt(void *json, const char *node, int *value); 52 int jsonGetBool(void *json, const char *node, int *value); 53 int jsonGetUint64(void *json, const char *node, unsigned long long *value); 54 int jsonGetArraySize(void *json); 55 void *jsonGetArrayItem(void *json, int item); 56 int *jsonGetIntArray(void *json, const char *node, int *size); 57 58 int jsonMatchString(void *json, const char *node, char *value); 59 int jsonMatchInt(void *json, const char *node, int value); 60 int jsonMatchBool(void *json, const char *node, int value); 61 int jsonMatchUint64(void *json, const char *node, unsigned long long value); 62 63 int jsonSetString(void *json, const char *node, const char *str); 64 int jsonSetInt(void *json, const char *node, int value); 65 int jsonSetBool(void *json, const char *node, int value); 66 int jsonSetUint64(void *json, const char *node, unsigned long long value); 67 68 void *jsonDuplicate(void *json, int withChild); 69 70 #define jsonNewRoot() jsonNewOject(NULL, NULL) 71 void *jsonNewOject(void *json, const char *name); 72 void *jsonNewArray(void *json, const char *name); 73 void *jsonArrayAddItem(void *array); 74 75 void *jsonAttach(void *json, const char *name, void *obj); 76 77 void *jsonAddBool(void *json, const char *name, int b); 78 void *jsonAddInt(void *json, const char *name, int v); 79 void *jsonAddDouble(void *json, const char *name, double v); 80 void *jsonAddUint64(void *json, const char *name, unsigned long long v); 81 void *jsonAddString(void *json, const char *name, const char *str); 82 void *jsonAddIntArray(void *json, const char *name, const int *numbers,int count); 83 void *jsonAddStringArray(void *json, const char *name, const char **str, int count); 84 85 #ifdef __cplusplus 86 } 87 #endif 88 89 #endif /* __JSONHELPER__ */
C文件:
1 /* 2 @File: jsonHelper.c 3 @Description: json helper functions 4 @Date: 2018-04-27 5 @Author: Liu Chuansen ([email protected]) 6 7 */ 8 9 #include10 #include <string.h> 11 #include 12 13 #include "jsonHelper.h" 14 #include "cJSON.h" 15 16 static const char *cJsonType(int type) 17 { 18 const char *p = "False\0True\0NULL\0Number\0String\0Array\0Object\0"; 19 int i = 0; 20 21 if (type == 0) 22 { 23 return p; 24 } 25 26 while(*p) 27 { 28 p ++; 29 if (*p == '\0') 30 { 31 i ++; 32 p ++; 33 if (*p && (i == type)) 34 { 35 return p; 36 } 37 } 38 } 39 40 return "[Unknown]"; 41 } 42 43 const char *jsonNodeType(void *json) 44 { 45 return cJsonType(((cJSON *)json)->type); 46 } 47 48 const char *jsonErrorString(int ret) 49 { 50 const char *p = JSON_ERROR_STRING; 51 int i = 0; 52 53 if (ret == 0) 54 { 55 return p; 56 } 57 58 while(*p) 59 { 60 p ++; 61 if (*p == '\0') 62 { 63 i ++; 64 p ++; 65 if (*p && (i == ret)) 66 { 67 return p; 68 } 69 } 70 } 71 72 return "[Unknown]"; 73 } 74 75 76 void *jsonParse(const char *text) 77 { 78 return cJSON_Parse(text); 79 } 80 81 void jsonDelete(void *json) 82 { 83 return cJSON_Delete(json); 84 } 85 86 /* 87 @input: text, origin text pass to jsonParse 88 @desc: only call this function when jsonParse() failed 89 */ 90 void jsonDumpError(const char *text) 91 { 92 static char buffer[128]; 93 int len = strlen(text); 94 const char *p = cJSON_GetErrorPtr(); 95 96 printf("------------json error dump------------\n"); 97 98 if (p && (p < text + len)) 99 { 100 const char *pre = text; 101 int preLen = 16; 102 int offset = 0; 103 104 if ((p - text) > 16) 105 { 106 pre = p - 16; 107 } 108 else { 109 preLen = p - text; 110 } 111 112 if (preLen > 0) 113 { 114 strncpy(buffer, pre, preLen); 115 strcpy(buffer + preLen, "\\_/"); 116 offset = preLen + 3; 117 } 118 119 strncpy(buffer + offset, p, sizeof(buffer) - offset - 1); 120 buffer[sizeof(buffer) - 1] = 0; 121 122 printf("%s\n", buffer); 123 } 124 else 125 { 126 printf("***Unable to find error text\n"); 127 } 128 129 printf("=======================================\n"); 130 } 131 132 133 void jsonDump(void *json) 134 { 135 printf("---------------json dump---------------\n"); 136 137 char *d = cJSON_Print(json); 138 printf("%s\n", d ? d : "(null)"); 139 printf("=======================================\n"); 140 141 if (d) 142 { 143 free(d); 144 } 145 } 146 147 char *jsonToString(void *json, int format) 148 { 149 return format ? cJSON_Print(json) : cJSON_PrintUnformatted(json); 150 } 151 152 char *jsonToBuffer(void *json, int format, char *buffer, int len) 153 { 154 if (!buffer || !len) 155 { 156 return "Buffer is not valid"; 157 } 158 159 return cJSON_PrintToBuffer(json, buffer, len, format); 160 } 161 162 163 int jsonTestNumber(void *json) 164 { 165 if (json == NULL) return 0; 166 return (((cJSON *)json)->type == cJSON_Number) ? 1 : 0; 167 } 168 169 int jsonTestString(void *json) 170 { 171 if (json == NULL) return 0; 172 return (((cJSON *)json)->type == cJSON_String) ? 1 : 0; 173 } 174 175 int jsonTestArray(void *json) 176 { 177 if (json == NULL) return 0; 178 return (((cJSON *)json)->type == cJSON_Array) ? 1 : 0; 179 } 180 181 int jsonTestObject(void *json) 182 { 183 if (json == NULL) return 0; 184 return (((cJSON *)json)->type == cJSON_Object) ? 1 : 0; 185 } 186 187 int jsonTestBool(void *json) 188 { 189 cJSON *j = json; 190 if (j == NULL) return 0; 191 192 if ((j->type == cJSON_False) || (j->type == cJSON_True)) 193 { 194 return 1; 195 } 196 197 if ((j->type == cJSON_Number) && ((j->valueint == 0) || (j->valueint == 1))) 198 { 199 return 1; 200 } 201 202 return 0; 203 } 204 205 /* 206 @function: jsonGetNode 207 --- 208 @json: json parent node 209 @node: node path, such as "sys.info[0].root" 210 @ret: return status 211 --- 212 @return the node handle of destination node 213 */ 214 215 void *jsonGetNode(void *json, const char *node, int *ret) 216 { 217 cJSON *s; 218 const char *subItem = NULL; 219 const char *p; 220 char *pe; 221 char item[JSON_NAME_MAX_SIZE + 1]; 222 int len, index = -1; 223 224 if ((node == NULL) || (*node == '\0')) 225 { 226 *ret = JSON_ERR_INVALID_NODE; 227 return NULL; 228 } 229 230 /* split first node name */ 231 p = strchr(node, '.'); 232 233 if (p) 234 { 235 len = p - node; 236 subItem = p + 1; 237 } 238 else 239 { 240 len = strlen(node); 241 } 242 243 if (!len || (len > sizeof(item) - 1)) 244 { 245 *ret = JSON_ERR_INVALID_NODE; 246 return NULL; 247 } 248 249 strncpy(item, node, len); 250 item[len] = '\0'; 251 252 /* get array if it is */ 253 pe = strchr(item, '['); 254 if (pe) 255 { 256 *pe = '\0'; 257 index = strtoul(pe + 1, NULL, 10); 258 } 259 260 s = cJSON_GetObjectItem(json, item); 261 262 if (s && (index >= 0)) 263 { 264 265 if (s->type != cJSON_Array) 266 { 267 *ret = JSON_ERR_NO_SUCH_ARRAY; 268 return NULL; 269 } 270 271 if (index >= cJSON_GetArraySize(s)) 272 { 273 *ret = JSON_ERR_INVALID_ARRAY_INDEX; 274 return NULL; 275 } 276 277 s = cJSON_GetArrayItem(s, index); 278 } 279 280 if (s == NULL) 281 { 282 *ret = JSON_ERR_NO_SUCH_NODE; 283 return NULL; 284 } 285 286 if (subItem) 287 { 288 return jsonGetNode(s, subItem, ret); 289 } 290 else 291 { 292 *ret = JSON_OK; 293 return s; 294 } 295 } 296 297 int jsonGetString(void *json, const char *node, char *buf, int len) 298 { 299 int ret = JSON_OK; 300 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 301 302 if (ret != JSON_OK) return ret; 303 304 if (!jsonTestString(d)) 305 { 306 return JSON_ERR_UNMATCH_TYPE; 307 } 308 309 if (buf && len) 310 { 311 strncpy(buf, d->valuestring, len - 1); 312 buf[len - 1] = '\0'; 313 } 314 315 return JSON_OK; 316 } 317 318 int jsonGetInt(void *json, const char *node, int *value) 319 { 320 int ret = JSON_OK; 321 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 322 323 if (ret != JSON_OK) return ret; 324 325 if (!jsonTestNumber(d)) 326 { 327 return JSON_ERR_UNMATCH_TYPE; 328 } 329 330 if (value) 331 { 332 *value = d->valueint; 333 } 334 335 return JSON_OK; 336 } 337 338 int jsonGetBool(void *json, const char *node, int *value) 339 { 340 int ret = JSON_OK; 341 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 342 343 if (ret != JSON_OK) return ret; 344 345 if (!jsonTestBool(d)) 346 { 347 return JSON_ERR_UNMATCH_TYPE; 348 } 349 350 if (value) 351 { 352 if (d->type == cJSON_True) 353 { 354 *value = 1; 355 } 356 else if (d->type == cJSON_Number) 357 { 358 *value = d->valueint ? 1 : 0; 359 } 360 else 361 { 362 *value = 0; 363 } 364 } 365 366 return JSON_OK; 367 } 368 369 370 int jsonGetUint64(void *json, const char *node, unsigned long long *value) 371 { 372 int ret = JSON_OK; 373 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 374 375 if (ret != JSON_OK) return ret; 376 377 if (!jsonTestNumber(d)) 378 { 379 return JSON_ERR_UNMATCH_TYPE; 380 } 381 382 if (value) 383 { 384 *value = d->valueuint64; 385 } 386 387 return JSON_OK; 388 } 389 390 /* need to free */ 391 int *jsonGetIntArray(void *json, const char *node, int *size) 392 { 393 int ret = JSON_OK; 394 int num; 395 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 396 int *intArray = NULL; 397 int i; 398 399 if (ret != JSON_OK) return ret; 400 401 if (!jsonTestArray(d)) 402 { 403 return NULL; 404 } 405 406 num = cJSON_GetArraySize(d); 407 408 if (num > 0) 409 { 410 intArray = malloc(sizeof(num) * sizeof(int)); 411 412 for (i = 0; i < num; i ++) 413 { 414 cJSON *s = cJSON_GetArrayItem(d, i); 415 if (s->type != cJSON_Number) 416 { 417 free(intArray); 418 return NULL; 419 } 420 intArray[i] = s->valueint; 421 } 422 } 423 424 if (size) 425 { 426 *size = num; 427 } 428 429 return intArray; 430 } 431 432 433 434 435 int jsonGetArraySize(void *json) 436 { 437 if (!jsonTestArray(json)) 438 { 439 return 0; 440 } 441 442 return cJSON_GetArraySize(json); 443 } 444 445 void *jsonGetArrayItem(void *json, int item) 446 { 447 if (!jsonTestArray(json)) 448 { 449 return NULL; 450 } 451 452 return cJSON_GetArrayItem(json, item); 453 } 454 455 int jsonMatchString(void *json, const char *node, char *value) 456 { 457 int ret = JSON_OK; 458 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 459 460 if (ret != JSON_OK) return 0; 461 462 if (!jsonTestString(d)) 463 { 464 return 0; 465 } 466 467 if (value) 468 { 469 return !strcmp(value, d->valuestring) ? 1 : 0; 470 } 471 472 return 0; 473 } 474 475 int jsonMatchInt(void *json, const char *node, int value) 476 { 477 int ret = JSON_OK; 478 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 479 480 if (ret != JSON_OK) return 0; 481 482 if (!jsonTestNumber(d)) 483 { 484 return 0; 485 } 486 487 return (value == d->valueint) ? 1 : 0; 488 } 489 490 int jsonMatchBool(void *json, const char *node, int value) 491 { 492 int ret = JSON_OK, bv; 493 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 494 495 if (ret != JSON_OK) return 0; 496 497 if (!jsonTestBool(d)) 498 { 499 return 0; 500 } 501 502 if (d->type == cJSON_True) 503 { 504 bv = 1; 505 } 506 else if (d->type == cJSON_Number) 507 { 508 bv = d->valueint ? 1 : 0; 509 } 510 else 511 { 512 bv = 0; 513 } 514 515 if (value > 1) 516 { 517 value = 1; 518 } 519 520 return (bv == value) ? 1 : 0; 521 } 522 523 524 int jsonMatchUint64(void *json, const char *node, unsigned long long value) 525 { 526 int ret = JSON_OK; 527 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 528 529 if (ret != JSON_OK) return 0; 530 531 if (!jsonTestNumber(d)) 532 { 533 return 0; 534 } 535 536 return (value == d->valueuint64) ? 1 : 0; 537 } 538 539 /* it is not safe function */ 540 int jsonSetString(void *json, const char *node, const char *str) 541 { 542 int ret = JSON_OK; 543 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 544 545 if (ret != JSON_OK) return ret; 546 547 if (!jsonTestString(d)) 548 { 549 return JSON_ERR_UNMATCH_TYPE; 550 } 551 552 if (str && str[0]) 553 { 554 if (!(d->type & cJSON_IsReference) && d->valuestring) 555 { 556 free(d->valuestring); 557 } 558 559 d->valuestring = strdup(str); 560 } 561 562 return JSON_OK; 563 } 564 565 int jsonSetInt(void *json, const char *node, int value) 566 { 567 int ret = JSON_OK; 568 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 569 570 if (ret != JSON_OK) return ret; 571 572 if (!jsonTestNumber(d)) 573 { 574 return JSON_ERR_UNMATCH_TYPE; 575 } 576 577 d->valueint = value; 578 d->valuedouble = (double)value; 579 d->valueuint64 = 0; 580 581 return JSON_OK; 582 } 583 584 int jsonSetBool(void *json, const char *node, int value) 585 { 586 int ret = JSON_OK; 587 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 588 589 if (ret != JSON_OK) return ret; 590 591 if (!jsonTestBool(d)) 592 { 593 return JSON_ERR_UNMATCH_TYPE; 594 } 595 596 if ((d->type == cJSON_True) || (d->type == cJSON_False)) 597 { 598 d->type = value ? cJSON_True : cJSON_False; 599 } 600 else if (d->type == cJSON_Number) 601 { 602 d->valueint = value ? 1 : 0; 603 d->valuedouble = (double)d->valueint; 604 d->valueuint64 = 0; 605 } 606 607 return JSON_OK; 608 } 609 610 611 int jsonSetUint64(void *json, const char *node, unsigned long long value) 612 { 613 int ret = JSON_OK; 614 cJSON *d = node ? jsonGetNode(json, node, &ret) : json; 615 616 if (ret != JSON_OK) return ret; 617 618 if (!jsonTestNumber(d)) 619 { 620 return JSON_ERR_UNMATCH_TYPE; 621 } 622 623 d->valueuint64 = value; 624 625 return JSON_OK; 626 } 627 628 void *jsonDuplicate(void *json, int withChild) 629 { 630 return cJSON_Duplicate(json, withChild); 631 } 632 633 void *jsonNewOject(void *json, const char *name) 634 { 635 cJSON *j = cJSON_CreateObject(); 636 if (json && name) 637 { 638 cJSON_AddItemToObject(json, name, j); 639 } 640 return j; 641 } 642 643 void *jsonNewArray(void *json, const char *name) 644 { 645 cJSON *j = cJSON_CreateArray(); 646 if (json && name) 647 { 648 cJSON_AddItemToObject(json, name, j); 649 } 650 return j; 651 } 652 653 void *jsonArrayAddItem(void *array) 654 { 655 cJSON *j = cJSON_CreateObject(); 656 if (array) 657 { 658 cJSON_AddItemToArray(array, j); 659 } 660 return j; 661 } 662 663 void *jsonAttach(void *json, const char *name, void *obj) 664 { 665 cJSON_AddItemToObject(json, name, obj); 666 667 return obj; 668 } 669 670 671 void *jsonAddBool(void *json, const char *name, int b) 672 { 673 cJSON *j = cJSON_CreateBool(b); 674 if (json && name) 675 { 676 cJSON_AddItemToObject(json, name, j); 677 } 678 679 return j; 680 } 681 682 void *jsonAddInt(void *json, const char *name, int v) 683 { 684 cJSON *j = cJSON_CreateNumber(v); 685 if (json && name) 686 { 687 cJSON_AddItemToObject(json, name, j); 688 } 689 690 return j; 691 } 692 693 void *jsonAddDouble(void *json, const char *name, double v) 694 { 695 cJSON *j = cJSON_CreateNumber(v); 696 if (json && name) 697 { 698 cJSON_AddItemToObject(json, name, j); 699 } 700 701 return j; 702 } 703 704 705 void *jsonAddUint64(void *json, const char *name, unsigned long long v) 706 { 707 cJSON *j = cJSON_CreateUint64(v); 708 if (json && name) 709 { 710 cJSON_AddItemToObject(json, name, j); 711 } 712 713 return j; 714 } 715 716 void *jsonAddString(void *json, const char *name, const char *str) 717 { 718 cJSON *j = cJSON_CreateString(str); 719 if (json && name) 720 { 721 cJSON_AddItemToObject(json, name, j); 722 } 723 724 return j; 725 } 726 727 void *jsonAddIntArray(void *json, const char *name, const int *numbers,int count) 728 { 729 cJSON *j = cJSON_CreateIntArray(numbers, count); 730 if (json && name) 731 { 732 cJSON_AddItemToObject(json, name, j); 733 } 734 735 return j; 736 } 737 738 void *jsonAddStringArray(void *json, const char *name, const char **str, int count) 739 { 740 cJSON *j = cJSON_CreateStringArray(str, count); 741 if (json && name) 742 { 743 cJSON_AddItemToObject(json, name, j); 744 } 745 746 return j; 747 }
后续将提供使用示例。