cJSCON代码

C代码

/*
 *  ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
 *  │Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  ┌┐    ┌┐    ┌┐
 *  └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └┘    └┘    └┘
 *  ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
 *  │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │N L│ / │ * │ - │
 *  ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
 *  │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
 *  ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
 *  │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
 *  ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
 *  │ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
 *  ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
 *  │ Ctrl│    │Alt │         Space         │ Alt│    │    │Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
 *  └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 * @Description:
 * @Version: 1.0
 * @Autor: NelsonYoung
 * @Date: 2021-10-02 15:08:02
 */

#ifndef cJSON__c
#define cJSON__c
/*===========================================================================
 *                             Header file
 *===========================================================================*/
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"

/*===========================================================================
 *                              DEFINITION
 *==========================================================================*/
/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0,
                                               0xF0, 0xF8, 0xFC
                                              };
/*===========================================================================
 *                            Global variable
 *==========================================================================*/

void *Lifesense_mem_alloc(uint32_t sz)
{
    return malloc(sz);
}

void Lifesense_mem_free(void *ptr)
{
    free(ptr);
}

uint32_t memscpy(void *dst, uint32_t dst_size, const void *src, uint32_t src_size)
{
  uint32_t  copy_size = (dst_size <= src_size)? dst_size : src_size;
  memcpy(dst, src, copy_size);
  return copy_size;
}

static const char *ep;

/*===========================================================================
 *                                FUNCTION
 *==========================================================================*/

/**
 * @description:
 * @param {*}
 * @return {*}
 * @author: NelsonYoung
 */
const char *cJSON_GetErrorPtr(void)
{
    return ep;
}

/**
 * @description:
 * @param {int} c
 * @return {*}
 * @author: NelsonYoung
 */
static int cJSON_isupper(int c)
{
    return 'A' <= c && c <= 'Z';
}

/**
 * @description:
 * @param {int} c
 * @return {*}
 * @author: NelsonYoung
 */
static int cJSON_tolower(int c)
{
    return cJSON_isupper(c) ? c + ('a' - 'A') : c;
}

/**
 * @description:
 * @param {char} *s1
 * @param {char} *s2
 * @return {*}
 * @author: NelsonYoung
 */
static int cJSON_strcasecmp(const char *s1, const char *s2)
{
    if(!s1)
    { return (s1 == s2) ? 0 : 1; }
    if(!s2)
    { return 1; }
    for(; cJSON_tolower(*s1) == cJSON_tolower(*s2); ++s1, ++s2)
        if(*s1 == 0)
        { return 0; }
    return cJSON_tolower(*(const unsigned char *)s1) -
           cJSON_tolower(*(const unsigned char *)s2);
}

static void *(*cJSON_malloc)(size_t sz) = Lifesense_mem_alloc;
static void (*cJSON_free)(void *ptr) = Lifesense_mem_free;

/**
 * @description:
 * @param {char} *str
 * @return {*}
 * @author: NelsonYoung
 */
static char *cJSON_strdup(const char *str)
{
    size_t len;
    char *copy;
    if(!str)
    { return 0; }
    len = strlen(str) + 1;
    copy = (char *)cJSON_malloc(len);
    if(!copy)
    { return 0; }
    memscpy(copy, len, str, len);
    return copy;
}

/**
 * @description:
 * @param {cJSON_Hooks} *hooks
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_InitHooks(cJSON_Hooks *hooks)
{
    if(!hooks)   /* Reset hooks */
    {
        cJSON_malloc = malloc;
        cJSON_free = free;
        return;
    }
    cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
    cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
}

/* Internal constructor. */
/**
 * @description:
 * @param {*}
 * @return {*}
 * @author: NelsonYoung
 */
static cJSON *cJSON_New_Item(void)
{
    cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
    if(node)
    { memset(node, 0, sizeof(cJSON)); }
    return node;
}

/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
    cJSON *next;
    while(c)
    {
        next = c->next;
        if(!(c->type & cJSON_IsReference) && c->child)
        { cJSON_Delete(c->child); }
        if(!(c->type & cJSON_IsReference) && c->valuestring)
        { cJSON_free(c->valuestring); }
        if(c->string)
        { cJSON_free(c->string); }
        cJSON_free(c);
        c = next;
    }
}

/* Parse the input text to generate a number, and populate the result into item.
*/
/**
 * @description:
 * @param {cJSON} *item
 * @param {char} *num
 * @return {*}
 * @author: NelsonYoung
 */
static const char *parse_number(cJSON *item, const char *num)
{
    double n = 0, sign = 1, scale = 0;
    int subscale = 0, signsubscale = 1;
    if(*num == '-')
    { sign = -1, num++; } /* Has sign? */
    if(*num == '0')
    { num++; } /* is zero */
    if(*num >= '1' && *num <= '9')
        do
        { n = (n * 10.0) + (*num++ - '0'); }
        while(*num >= '0' && *num <= '9'); /* Number? */
    if(*num == '.' && num[1] >= '0' && num[1] <= '9')
    {
        num++;
        do
        { n = (n * 10.0) + (*num++ - '0'), scale--; }
        while(*num >= '0' && *num <= '9');
    }                              /* Fractional part? */
    if(*num == 'e' || *num == 'E') /* Exponent? */
    {
        num++;
        if(*num == '+')
        { num++; }
        else if(*num == '-')
        { signsubscale = -1, num++; } /* With sign? */
        while(*num >= '0' && *num <= '9')
        { subscale = (subscale * 10) + (*num++ - '0'); } /* Number? */
    }
    n = sign * n *
        pow(10.0, (scale + subscale * signsubscale)); /* number = +/-number.fraction *10^+/- exponent */
    item->valuedouble = n;
    item->valueint = (int)n;
    item->type = cJSON_Number;
    return num;
}

/* Render the number nicely from the given item into a string. */
/**
 * @description:
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
static char *print_number(cJSON *item)
{
    char *str;
    double d = item->valuedouble;

    //由于MA510编译器不支持浮点数格式化输出,类型参数中增加小数位数参数用于处理小数显示
    if(item->valueplaces)
    {
        str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */
        if(str)
        {
            int factor = (int)pow(10, item->valueplaces);
            if(item->valueplaces)
            { snprintf(str, 64, "%d.%0*d", item->valueint / factor, item->valueplaces, abs(item->valueint) % factor); }
            else
            { snprintf(str, 64, "%f", d); }
        }
    }
    else if(fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX &&
            d >= INT_MIN)
    {
        str = (char *)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
        if(str)
        { snprintf(str, 21, "%d", item->valueint); }
    }
    else
    {
        str = (char *)cJSON_malloc(64); /* This is a nice tradeoff. */
        if(str)
        {
            if(fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)
            { snprintf(str, 64, "%.0f", d); }
            else if(fabs(d) < 1.0e-6 || fabs(d) > 1.0e9)
            { snprintf(str, 64, "%e", d); }
            else
            { snprintf(str, 64, "%f", d); }
        }
    }
    return str;
}

/**
 * @description:
 * @param {char} *str
 * @return {*}
 * @author: NelsonYoung
 */
static unsigned parse_hex4(const char *str)
{
    unsigned h = 0;
    if(*str >= '0' && *str <= '9')
    { h += (*str) - '0'; }
    else if(*str >= 'A' && *str <= 'F')
    { h += 10 + (*str) - 'A'; }
    else if(*str >= 'a' && *str <= 'f')
    { h += 10 + (*str) - 'a'; }
    else
    { return 0; }
    h = h << 4;
    str++;
    if(*str >= '0' && *str <= '9')
    { h += (*str) - '0'; }
    else if(*str >= 'A' && *str <= 'F')
    { h += 10 + (*str) - 'A'; }
    else if(*str >= 'a' && *str <= 'f')
    { h += 10 + (*str) - 'a'; }
    else
    { return 0; }
    h = h << 4;
    str++;
    if(*str >= '0' && *str <= '9')
    { h += (*str) - '0'; }
    else if(*str >= 'A' && *str <= 'F')
    { h += 10 + (*str) - 'A'; }
    else if(*str >= 'a' && *str <= 'f')
    { h += 10 + (*str) - 'a'; }
    else
    { return 0; }
    h = h << 4;
    str++;
    if(*str >= '0' && *str <= '9')
    { h += (*str) - '0'; }
    else if(*str >= 'A' && *str <= 'F')
    { h += 10 + (*str) - 'A'; }
    else if(*str >= 'a' && *str <= 'f')
    { h += 10 + (*str) - 'a'; }
    else
    { return 0; }
    return h;
}

/**
 * @description:
 * @param {cJSON} *item
 * @param {char} *str
 * @return {*}
 * @author: NelsonYoung
 */
static const char *parse_string(cJSON *item, const char *str)
{
    const char *ptr = str + 1;
    char *ptr2;
    char *out;
    int len = 0;
    unsigned uc, uc2;
    if(*str != '\"')
    {
        ep = str;
        return 0;
    } /* not a string! */
    while(*ptr != '\"' && *ptr && ++len)
        if(*ptr++ == '\\')
        { ptr++; } /* Skip escaped quotes. */
    out = (char *)cJSON_malloc(
                          len + 1); /* This is how long we need for the string, roughly. */
    if(!out)
    { return 0; }
    ptr = str + 1;
    ptr2 = out;
    while(*ptr != '\"' && *ptr)
    {
        if(*ptr != '\\')
        { *ptr2++ = *ptr++; }
        else
        {
            ptr++;
            switch(*ptr)
            {
                case 'b':
                    *ptr2++ = '\b';
                    break;
                case 'f':
                    *ptr2++ = '\f';
                    break;
                case 'n':
                    *ptr2++ = '\n';
                    break;
                case 'r':
                    *ptr2++ = '\r';
                    break;
                case 't':
                    *ptr2++ = '\t';
                    break;
                case 'u': /* transcode utf16 to utf8. */
                    uc = parse_hex4(ptr + 1);
                    ptr += 4; /* get the unicode char. */
                    if((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0)
                    { break; } /* check for invalid.  */
                    if(uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs.  */
                    {
                        if((ptr[1] != '\\') || (ptr[2] != 'u'))
                        { break; } /* missing second-half of surrogate. */
                        uc2 = parse_hex4(ptr + 3);
                        ptr += 6;
                        if((uc2 < 0xDC00) || (uc2 > 0xDFFF))
                        { break; } /* invalid second-half of surrogate. */
                        uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF));
                    }
                    len = 4;
                    if(uc < 0x80)
                    { len = 1; }
                    else if(uc < 0x800)
                    { len = 2; }
                    else if(uc < 0x10000)
                    { len = 3; }
                    ptr2 += len;
                    switch(len)
                    {
                        case 4:
                            *--ptr2 = ((uc | 0x80) & 0xBF);
                            uc >>= 6;
                        case 3:
                            *--ptr2 = ((uc | 0x80) & 0xBF);
                            uc >>= 6;
                        case 2:
                            *--ptr2 = ((uc | 0x80) & 0xBF);
                            uc >>= 6;
                        case 1:
                            *--ptr2 = (uc | firstByteMark[len]);
                    }
                    ptr2 += len;
                    break;
                default:
                    *ptr2++ = *ptr;
                    break;
            }
            ptr++;
        }
    }
    *ptr2 = 0;
    if(*ptr == '\"')
    { ptr++; }
    item->valuestring = out;
    item->type = cJSON_String;
    return ptr;
}

/* Render the cstring provided to an escaped version that can be printed. */
/**
 * @description:
 * @param {char} *str
 * @return {*}
 * @author: NelsonYoung
 */
static char *print_string_ptr(const char *str)
{
    const char *ptr;
    char *ptr2, *out;
    int len = 0;
    int len_avalible = 0;
    unsigned char token;
    if(!str)
    { return cJSON_strdup(""); }
    ptr = str;
    token = *ptr;
    while((token) && ++len)
    {
        if(strchr("\"\\\b\f\n\r\t", token))
        { len++; }
        else if(token < 32)
        { len += 5; }
        ptr++;
        token = *ptr;
    }
    out = (char *)cJSON_malloc(len + 3);
    if(!out)
    { return 0; }
    len_avalible = len + 3;
    ptr2 = out;
    ptr = str;
    *ptr2++ = '\"';
    len_avalible--;
    while(*ptr)
    {
        if((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
        {
            *ptr2++ = *ptr++;
            len_avalible--;
        }
        else
        {
            *ptr2++ = '\\';
            len_avalible--;
            switch(token = *ptr++)
            {
                case '\\':
                    *ptr2++ = '\\';
                    len_avalible--;
                    break;
                case '\"':
                    *ptr2++ = '\"';
                    len_avalible--;
                    break;
                case '\b':
                    *ptr2++ = 'b';
                    len_avalible--;
                    break;
                case '\f':
                    *ptr2++ = 'f';
                    len_avalible--;
                    break;
                case '\n':
                    *ptr2++ = 'n';
                    len_avalible--;
                    break;
                case '\r':
                    *ptr2++ = 'r';
                    len_avalible--;
                    break;
                case '\t':
                    *ptr2++ = 't';
                    len_avalible--;
                    break;
                default:
                    // snprintf(ptr2, len + 3, "u%04x", token);
                    snprintf(ptr2, len_avalible, "u%04x", token);
                    ptr2 += 5;
                    len_avalible -= 5;
                    break; /* escape and print */
            }
        }
    }
    *ptr2++ = '\"';
    *ptr2++ = 0;
    return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
/**
 * @description:
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
static char *print_string(cJSON *item)
{
    return print_string_ptr(item->valuestring);
}

/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item, const char *value);
static char *print_value(cJSON *item, int depth, int fmt);
static const char *parse_array(cJSON *item, const char *value);
static char *print_array(cJSON *item, int depth, int fmt);
static const char *parse_object(cJSON *item, const char *value);
static char *print_object(cJSON *item, int depth, int fmt);

/* Utility to jump whitespace and cr/lf */
/**
 * @description:
 * @param {char} *in
 * @return {*}
 * @author: NelsonYoung
 */
static const char *skip(const char *in)
{
    while(in && *in && (unsigned char)*in <= 32)
    { in++; }
    return in;
}

/* Parse an object - create a new root, and populate. */
/**
 * @description:
 * @param {*}
 * @return {*}
 * @author: NelsonYoung
 */
cJSON *cJSON_ParseWithOpts(const char *value,
                           const char **return_parse_end,
                           int require_null_terminated)
{
    const char *end = 0;
    cJSON *c = cJSON_New_Item();
    ep = 0;
    if(!c)
    { return 0; } /* memory fail */
    end = parse_value(c, skip(value));
    if(!end)
    {
        cJSON_Delete(c);
        return 0;
    } /* parse failure. ep is set. */
    /* if we require null-terminated JSON without appended garbage, skip and
     * then check for a null terminator */
    if(require_null_terminated)
    {
        end = skip(end);
        if(*end)
        {
            cJSON_Delete(c);
            ep = end;
            return 0;
        }
    }
    if(return_parse_end)
    { *return_parse_end = end; }
    return c;
}
/* Default options for cJSON_Parse */
/**
 * @description:
 * @param {char} *value
 * @return {*}
 * @author: NelsonYoung
 */
cJSON *cJSON_Parse(const char *value)
{
    return cJSON_ParseWithOpts(value, 0, 0);
}

/* Render a cJSON item/entity/structure to text. */
/**
 * @description:
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
char *cJSON_Print(cJSON *item)
{
    return print_value(item, 0, 1);
}
/**
 * @description:
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
char *cJSON_PrintUnformatted(cJSON *item)
{
    return print_value(item, 0, 0);
}

/* Parser core - when encountering text, process appropriately. */
/**
 * @description:
 * @param {cJSON} *item
 * @param {char} *value
 * @return {*}
 * @author: NelsonYoung
 */
static const char *parse_value(cJSON *item, const char *value)
{
    if(!value)
    { return 0; } /* Fail on null. */
    if(!strncmp(value, "null", 4))
    {
        item->type = cJSON_NULL;
        return value + 4;
    }
    if(!strncmp(value, "false", 5))
    {
        item->type = cJSON_False;
        return value + 5;
    }
    if(!strncmp(value, "true", 4))
    {
        item->type = cJSON_True;
        item->valueint = 1;
        return value + 4;
    }
    if(*value == '\"')
    {
        return parse_string(item, value);
    }
    if(*value == '-' || (*value >= '0' && *value <= '9'))
    {
        return parse_number(item, value);
    }
    if(*value == '[')
    {
        return parse_array(item, value);
    }
    if(*value == '{')
    {
        return parse_object(item, value);
    }
    ep = value;
    return 0; /* failure. */
}

/* Render a value to text. */
/**
 * @description:
 * @param {cJSON} *item
 * @param {int} depth
 * @param {int} fmt
 * @return {*}
 * @author: NelsonYoung
 */
static char *print_value(cJSON *item, int depth, int fmt)
{
    char *out = 0;
    if(!item)
    { return 0; }
    switch((item->type) & 255)
    {
        case cJSON_NULL:
            out = cJSON_strdup("null");
            break;
        case cJSON_False:
            out = cJSON_strdup("false");
            break;
        case cJSON_True:
            out = cJSON_strdup("true");
            break;
        case cJSON_Number:
            out = print_number(item);
            break;
        case cJSON_String:
            out = print_string(item);
            break;
        case cJSON_Array:
            out = print_array(item, depth, fmt);
            break;
        case cJSON_Object:
            out = print_object(item, depth, fmt);
            break;
    }
    return out;
}

/* Build an array from input text. */
/**
 * @description:
 * @param {cJSON} *item
 * @param {char} *value
 * @return {*}
 * @author: NelsonYoung
 */
static const char *parse_array(cJSON *item, const char *value)
{
    cJSON *child;
    if(*value != '[')
    {
        ep = value;
        return 0;
    } /* not an array! */
    item->type = cJSON_Array;
    value = skip(value + 1);
    if(*value == ']')
    { return value + 1; } /* empty array. */
    item->child = child = cJSON_New_Item();
    if(!item->child)
    { return 0; } /* memory fail */
    value = skip(
                            parse_value(child, skip(value))); /* skip any spacing, get the value. */
    if(!value)
    { return 0; }
    while(*value == ',')
    {
        cJSON *new_item = cJSON_New_Item();
        if(!new_item)
        { return 0; } /* memory fail */
        child->next = new_item;
        new_item->prev = child;
        child = new_item;
        value = skip(parse_value(child, skip(value + 1)));
        if(!value)
        { return 0; } /* memory fail */
    }
    if(*value == ']')
    { return value + 1; } /* end of array */
    ep = value;
    return 0; /* malformed. */
}

/* Render an array to text */
/**
 * @description:
 * @param {cJSON} *item
 * @param {int} depth
 * @param {int} fmt
 * @return {*}
 * @author: NelsonYoung
 */
static char *print_array(cJSON *item, int depth, int fmt)
{
    char **entries;
    char *out = 0, *ptr, *ret;
    int len = 5;
    cJSON *child = item->child;
    int numentries = 0, i = 0, fail = 0;
    /* How many entries in the array? */
    while(child)
    { numentries++, child = child->next; }
    /* Explicitly handle numentries==0 */
    if(!numentries)
    {
        out = (char *)cJSON_malloc(3);
        if(out)
        { strlcpy(out, "[]", 3); }
        return out;
    }
    /* Allocate an array to hold the values for each */
    entries = (char **)cJSON_malloc(numentries * sizeof(char *));
    if(!entries)
    { return 0; }
    memset(entries, 0, numentries * sizeof(char *));
    /* Retrieve all the results: */
    child = item->child;
    while(child && !fail)
    {
        ret = print_value(child, depth + 1, fmt);
        entries[i++] = ret;
        if(ret)
        { len += strlen(ret) + 2 + (fmt ? 1 : 0); }
        else
        { fail = 1; }
        child = child->next;
    }
    /* If we didn't fail, try to malloc the output string */
    if(!fail)
    { out = (char *)cJSON_malloc(len); }
    /* If that fails, we fail. */
    if(!out)
    { fail = 1; }
    /* Handle failure. */
    if(fail)
    {
        for(i = 0; i < numentries; i++)
            if(entries[i])
            { cJSON_free(entries[i]); }
        cJSON_free(entries);
        return 0;
    }
    /* Compose the output array. */
    *out = '[';
    ptr = out + 1;
    *ptr = 0;
    for(i = 0; i < numentries; i++)
    {
        strlcpy(ptr, entries[i], (strlen(entries[i]) + 1));
        ptr += strlen(entries[i]);
        if(i != numentries - 1)
        {
            *ptr++ = ',';
            if(fmt)
            {
                *ptr++ = ' ';
            }
            *ptr = 0;
        }
        cJSON_free(entries[i]);
    }
    cJSON_free(entries);
    *ptr++ = ']';
    *ptr++ = 0;
    return out;
}

/* Build an object from the text. */
/**
 * @description:
 * @param {cJSON} *item
 * @param {char} *value
 * @return {*}
 * @author: NelsonYoung
 */
static const char *parse_object(cJSON *item, const char *value)
{
    cJSON *child;
    cJSON *new_item;
    if(*value != '{')
    {
        ep = value;
        return 0;
    } /* not an object! */
    item->type = cJSON_Object;
    value = skip(value + 1);
    if(*value == '}')
    { return value + 1; } /* empty array. */
    item->child = child = cJSON_New_Item();
    if(!item->child)
    { return 0; }
    value = skip(parse_string(child, skip(value)));
    if(!value)
    { return 0; }
    child->string = child->valuestring;
    child->valuestring = 0;
    if(*value != ':')
    {
        ep = value;
        return 0;
    } /* fail! */
    value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
    if(!value)
    { return 0; }
    while(*value == ',')
    {
        const char *c_str = value + 1;
        while(1)
        {
            if(*c_str == 0)
            {
                ep = value;
                return 0;
            } /* fail! */
            if(*c_str == '}')
            {
                return c_str + 1; /* end of array */
            }
            if((unsigned char)*c_str > 32)
            { break; }
            c_str++;
        }
        new_item = cJSON_New_Item();
        if(!new_item)
        { return 0; } /* memory fail */
        child->next = new_item;
        new_item->prev = child;
        child = new_item;
        value = skip(parse_string(child, skip(value + 1)));
        if(!value)
        { return 0; }
        child->string = child->valuestring;
        child->valuestring = 0;
        if(*value != ':')
        {
            ep = value;
            return 0;
        } /* fail! */
        value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */
        if(!value)
        { return 0; }
    }
    if(*value == '}')
    { return value + 1; } /* end of array */
    ep = value;
    return 0; /* malformed. */
}

/* Render an object to text. */
/**
 * @description:
 * @param {cJSON} *item
 * @param {int} depth
 * @param {int} fmt
 * @return {*}
 * @author: NelsonYoung
 */
static char *print_object(cJSON *item, int depth, int fmt)
{
    char **entries = 0, **names = 0;
    char *out = 0, *ptr, *ret, *str;
    int len = 7, i = 0, j;
    cJSON *child = item->child;
    int numentries = 0, fail = 0;
    /* Count the number of entries. */
    while(child)
    { numentries++, child = child->next; }
    /* Explicitly handle empty object case */
    if(!numentries)
    {
        out = (char *)cJSON_malloc(fmt ? depth + 4 : 3);
        if(!out)
        { return 0; }
        ptr = out;
        *ptr++ = '{';
        if(fmt)
        {
            *ptr++ = '\n';
            for(i = 0; i < depth - 1; i++)
            { *ptr++ = '\t'; }
        }
        *ptr++ = '}';
        *ptr++ = 0;
        return out;
    }
    /* Allocate space for the names and the objects */
    entries = (char **)cJSON_malloc(numentries * sizeof(char *));
    if(!entries)
    { return 0; }
    names = (char **)cJSON_malloc(numentries * sizeof(char *));
    if(!names)
    {
        cJSON_free(entries);
        return 0;
    }
    memset(entries, 0, sizeof(char *) * numentries);
    memset(names, 0, sizeof(char *) * numentries);
    /* Collect all the results into our arrays: */
    child = item->child;
    depth++;
    if(fmt)
    { len += depth; }
    while(child)
    {
        names[i] = str = print_string_ptr(child->string);
        entries[i++] = ret = print_value(child, depth, fmt);
        if(str && ret)
        { len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); }
        else
        { fail = 1; }
        child = child->next;
    }
    /* Try to allocate the output string */
    if(!fail)
    { out = (char *)cJSON_malloc(len); }
    if(!out)
    { fail = 1; }
    /* Handle failure */
    if(fail)
    {
        for(i = 0; i < numentries; i++)
        {
            if(names[i])
            { cJSON_free(names[i]); }
            if(entries[i])
            { cJSON_free(entries[i]); }
        }
        cJSON_free(names);
        cJSON_free(entries);
        return 0;
    }
    /* Compose the output: */
    *out = '{';
    ptr = out + 1;
    if(fmt)
    {
        *ptr++ = '\n';
    }
    *ptr = 0;
    for(i = 0; i < numentries; i++)
    {
        if(fmt)
        {
            for(j = 0; j < depth; j++)
            {
                *ptr++ = '\t';
            }
        }
        strlcpy(ptr, names[i], (strlen(names[i]) + 1));
        ptr += strlen(names[i]);
        *ptr++ = ':';
        if(fmt)
        {
            *ptr++ = '\t';
        }
        strlcpy(ptr, entries[i], (strlen(entries[i]) + 1));
        ptr += strlen(entries[i]);
        if(i != numentries - 1)
        { *ptr++ = ','; }
        if(fmt)
        { *ptr++ = '\n'; }
        *ptr = 0;
        cJSON_free(names[i]);
        cJSON_free(entries[i]);
    }
    cJSON_free(names);
    cJSON_free(entries);
    if(fmt)
        for(i = 0; i < depth - 1; i++)
        { *ptr++ = '\t'; }
    *ptr++ = '}';
    *ptr++ = 0;
    return out;
}

/* Get Array size/item / object item. */
/**
 * @description:
 * @param {cJSON} *array
 * @return {*}
 * @author: NelsonYoung
 */
int cJSON_GetArraySize(cJSON *array)
{
    cJSON *c = array->child;
    int i = 0;
    while(c)
    { i++, c = c->next; }
    return i;
}
/**
 * @description:
 * @param {cJSON} *array
 * @param {int} item
 * @return {*}
 * @author: NelsonYoung
 */
cJSON *cJSON_GetArrayItem(cJSON *array, int item)
{
    cJSON *c = array->child;
    while(c && item > 0)
    { item--, c = c->next; }
    return c;
}
/**
 * @description:
 * @param {cJSON} *object
 * @param {char} *string
 * @return {*}
 * @author: NelsonYoung
 */
cJSON *cJSON_GetObjectItem(cJSON *object, const char *string)
{
    cJSON *c = object->child;
    while(c && cJSON_strcasecmp(c->string, string))
    { c = c->next; }
    return c;
}

/* Utility for array list handling. */
/**
 * @description:
 * @param {cJSON} *prev
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
static void suffix_object(cJSON *prev, cJSON *item)
{
    prev->next = item;
    item->prev = prev;
}
/* Utility for handling references. */
/**
 * @description:
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
static cJSON *create_reference(cJSON *item)
{
    cJSON *ref = cJSON_New_Item();
    if(!ref)
    { return 0; }
    memscpy(ref, sizeof(cJSON), item, sizeof(cJSON));
    ref->string = 0;
    ref->type |= cJSON_IsReference;
    ref->next = ref->prev = 0;
    return ref;
}

/* Add item to array/object. */
/**
 * @description:
 * @param {cJSON} *array
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_AddItemToArray(cJSON *array, cJSON *item)
{
    cJSON *c = array->child;
    if(!item)
    { return; }
    if(!c)
    {
        array->child = item;
    }
    else
    {
        while(c && c->next)
        { c = c->next; }
        if(c)
        { suffix_object(c, item); }
    }
}
/**
 * @description:
 * @param {cJSON} *object
 * @param {char} *string
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
{
    if(!item)
    { return; }
    if(item->string)
    { cJSON_free(item->string); }
    item->string = cJSON_strdup(string);
    cJSON_AddItemToArray(object, item);
}
/**
 * @description:
 * @param {cJSON} *array
 * @param {cJSON} *item
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
{
    cJSON_AddItemToArray(array, create_reference(item));
}
/**
 * @description:
 * @param {*}
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_AddItemReferenceToObject(cJSON *object,
                                    const char *string,
                                    cJSON *item)
{
    cJSON_AddItemToObject(object, string, create_reference(item));
}

/**
 * @description:
 * @param {cJSON} *array
 * @param {int} which
 * @return {*}
 * @author: NelsonYoung
 */
cJSON *cJSON_DetachItemFromArray(cJSON *array, int which)
{
    cJSON *c = array->child;
    while(c && which > 0)
    { c = c->next, which--; }
    if(!c)
    { return 0; }
    if(c->prev)
    { c->prev->next = c->next; }
    if(c->next)
    { c->next->prev = c->prev; }
    if(c == array->child)
    { array->child = c->next; }
    c->prev = c->next = 0;
    return c;
}
/**
 * @description:
 * @param {cJSON} *array
 * @param {int} which
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_DeleteItemFromArray(cJSON *array, int which)
{
    cJSON_Delete(cJSON_DetachItemFromArray(array, which));
}
/**
 * @description:
 * @param {cJSON} *object
 * @param {char} *string
 * @return {*}
 * @author: NelsonYoung
 */
cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string)
{
    int i = 0;
    cJSON *c = object->child;
    while(c && cJSON_strcasecmp(c->string, string))
    { i++, c = c->next; }
    if(c)
    { return cJSON_DetachItemFromArray(object, i); }
    return 0;
}
/**
 * @description:
 * @param {cJSON} *object
 * @param {char} *string
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_DeleteItemFromObject(cJSON *object, const char *string)
{
    cJSON_Delete(cJSON_DetachItemFromObject(object, string));
}

/* Replace array/object items with new ones. */
/**
 * @description:
 * @param {cJSON} *array
 * @param {int} which
 * @param {cJSON} *newitem
 * @return {*}
 * @author: NelsonYoung
 */
void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem)
{
    cJSON *c = array->child;
    while(c && which > 0)
    { c = c->next, which--; }
    if(!c)
    { return; }
    newitem->next = c->next;
    newitem->prev = c->prev;
    if(newitem->next)
    { newitem->next->prev = newitem; }
    if(c == array->child)
    { array->child = newitem; }
    else
    { newitem->prev->next = newitem; }
    c->next = c->prev = 0;
    cJSON_Delete(c);
}
void cJSON_ReplaceItemInObject(cJSON *object,
                               const char *string,
                               cJSON *newitem)
{
    int i = 0;
    cJSON *c = object->child;
    while(c && cJSON_strcasecmp(c->string, string))
    { i++, c = c->next; }
    if(c)
    {
        newitem->string = cJSON_strdup(string);
        cJSON_ReplaceItemInArray(object, i, newitem);
    }
}

/* Create basic types: */
cJSON *cJSON_CreateNull(void)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    { item->type = cJSON_NULL; }
    return item;
}
cJSON *cJSON_CreateTrue(void)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    { item->type = cJSON_True; }
    return item;
}
cJSON *cJSON_CreateFalse(void)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    { item->type = cJSON_False; }
    return item;
}
cJSON *cJSON_CreateBool(int b)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    { item->type = b ? cJSON_True : cJSON_False; }
    return item;
}
cJSON *cJSON_CreateNumber(double num)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    {
        item->type = cJSON_Number;
        item->valuedouble = num;
        item->valueint = (int)num;
    }
    return item;
}
cJSON *cJSON_CreateDouble(int decimal, int place)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    {
        item->type = cJSON_Number;
        item->valuedouble = (double)decimal/pow(10, place);
        item->valueint = decimal;
        item->valueplaces = place;
    }
    return item;
}
cJSON *cJSON_CreateString(const char *string)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    {
        item->type = cJSON_String;
        item->valuestring = cJSON_strdup(string);
    }
    return item;
}
cJSON *cJSON_CreateArray(void)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    { item->type = cJSON_Array; }
    return item;
}
cJSON *cJSON_CreateObject(void)
{
    cJSON *item = cJSON_New_Item();
    if(item)
    { item->type = cJSON_Object; }
    return item;
}

/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers, int count)
{
    int i;
    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
    for(i = 0; a && i < count; i++)
    {
        n = cJSON_CreateNumber(numbers[i]);
        if(!i)
        { a->child = n; }
        else
        { suffix_object(p, n); }
        p = n;
    }
    return a;
}
cJSON *cJSON_CreateFloatArray(const float *numbers, int count)
{
    int i;
    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
    for(i = 0; a && i < count; i++)
    {
        n = cJSON_CreateNumber(numbers[i]);
        if(!i)
        { a->child = n; }
        else
        { suffix_object(p, n); }
        p = n;
    }
    return a;
}
cJSON *cJSON_CreateDoubleArray(const double *numbers, int count)
{
    int i;
    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
    for(i = 0; a && i < count; i++)
    {
        n = cJSON_CreateNumber(numbers[i]);
        if(!i)
        { a->child = n; }
        else
        { suffix_object(p, n); }
        p = n;
    }
    return a;
}
cJSON *cJSON_CreateStringArray(const char **strings, int count)
{
    int i;
    cJSON *n = 0, *p = 0, *a = cJSON_CreateArray();
    for(i = 0; a && i < count; i++)
    {
        n = cJSON_CreateString(strings[i]);
        if(!i)
        { a->child = n; }
        else
        { suffix_object(p, n); }
        p = n;
    }
    return a;
}

/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item, int recurse)
{
    cJSON *newitem, *cptr, *nptr = 0, *newchild;
    /* Bail on bad ptr */
    if(!item)
    { return 0; }
    /* Create new item */
    newitem = cJSON_New_Item();
    if(!newitem)
    { return 0; }
    /* Copy over all vars */
    newitem->type = item->type & (~cJSON_IsReference),
             newitem->valueint = item->valueint,
                      newitem->valuedouble = item->valuedouble;
    if(item->valuestring)
    {
        newitem->valuestring = cJSON_strdup(item->valuestring);
        if(!newitem->valuestring)
        {
            cJSON_Delete(newitem);
            return 0;
        }
    }
    if(item->string)
    {
        newitem->string = cJSON_strdup(item->string);
        if(!newitem->string)
        {
            cJSON_Delete(newitem);
            return 0;
        }
    }
    /* If non-recursive, then we're done! */
    if(!recurse)
    { return newitem; }
    /* Walk the ->next chain for the child. */
    cptr = item->child;
    while(cptr)
    {
        newchild = cJSON_Duplicate(cptr, 1); /* Duplicate (with recurse) each item in the ->next chain */
        if(!newchild)
        {
            cJSON_Delete(newitem);
            return 0;
        }
        if(nptr)
        {
            nptr->next = newchild, newchild->prev = nptr;
            nptr = newchild;
        } /* If newitem->child already set, then crosswire ->prev and ->next and
         move on */
        else
        {
            newitem->child = newchild;
            nptr = newchild;
        } /* Set newitem->child and move to it */
        cptr = cptr->next;
    }
    return newitem;
}

void cJSON_Minify(char *json)
{
    char *into = json;
    while(*json)
    {
        if(*json == ' ')
        { json++; }
        else if(*json == '\t')
        { json++; } // Whitespace characters.
        else if(*json == '\r')
        { json++; }
        else if(*json == '\n')
        { json++; }
        else if((*json == '/') && (json[1] == '/'))
            while(*json && *json != '\n')
            { json++; } // double-slash comments, to end of line.
        else if((*json == '/') && (json[1] == '*'))
        {
            while(*json && !(*json == '*' && json[1] == '/'))
            { json++; }
            json += 2;
        } // multiline comments.
        else if(*json == '\"')
        {
            *into++ = *json++;
            while(*json && *json != '\"')
            {
                if(*json == '\\')
                { *into++ = *json++; }
                *into++ = *json++;
            }
            *into++ = *json++;
        } // string literals, which are \" sensitive.
        else
        { *into++ = *json++; } // All other characters.
    }
    *into = 0; // and null-terminate.
}
#endif

头文件

/*
 *
 *    ┏┓   ┏┓
 *  ┏┛┻━━━┛┻┓
 *  ┃       ┃
 *  ┃   ━   ┃
 *  ┃ >   < ┃
 *  ┃       ┃
 *  ┃... ⌒ ... ┃
 *  ┃       ┃
 *  ┗━┓   ┏━┛
 *      ┃   ┃ 
 *      ┃   ┃
 *      ┃   ┃
 *      ┃   ┃  神兽保佑
 *      ┃   ┃  代码无bug  
 *      ┃   ┃
 *      ┃   ┗━━━┓
 *      ┃       ┣┓
 *      ┃       ┏┛
 *      ┗┓┓┏━┳┓┏┛
 *        ┃┫┫ ┃┫┫
 *        ┗┻┛ ┗┻┛
 * @Description:
 * @Version: 1.0
 * @Autor: NelsonYoung
 * @Date: 2021-10-02 15:34:51
 */

#ifndef cJSON__h
#define cJSON__h

#ifdef __cplusplus
extern "C"
{
#endif
/*===========================================================================
 *                             Header file
 *===========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef TARGET_LINUX
#include <unistd.h>
#endif /*TARGET_LINUX*/
#include <limits.h>
#include <string.h>
#include <inttypes.h>

/*===========================================================================
 *                              DEFINITION
 *===========================================================================*/
/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6

#define cJSON_IsReference 256

/* The cJSON structure: */
typedef struct cJSON
{
    struct cJSON *next,
               *prev;  /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON
        *child;        /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

    int type;                   /* The type of the item, as above. */

    char *valuestring;          /* The item's string, if type==cJSON_String */
    int valueint;               /* The item's number, if type==cJSON_Number */
    double valuedouble;         /* The item's number, if type==cJSON_Number */
    int valueplaces;            /* The item's decimal places, if type==cJSON_Number and show in float*/
    char *string;               /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

typedef struct cJSON_Hooks
{
    void *(*malloc_fn)(size_t sz);
    void (*free_fn)(void *ptr);
} cJSON_Hooks;

/*===========================================================================
 *                            Global variable
 *===========================================================================*/


/*===========================================================================
 *                                FUNCTION
 *===========================================================================*/

/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks *hooks);

/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char  *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char  *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
extern void   cJSON_Delete(cJSON *c);

/* Returns the number of items in an array (or object). */
extern int    cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array, int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string);

/* For analysing failed parses. This returns a pointer to the parse error.
 * You'll probably need to look a few chars back to make sense of it.
 * Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);

/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateDouble(int decimal, int place);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);

/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers, int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers, int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers, int count);
extern cJSON *cJSON_CreateStringArray(const char **strings, int count);

/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object.
 * Use this when you want to add an existing cJSON to a new cJSON,
 * but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);

/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which);
extern void   cJSON_DeleteItemFromArray(cJSON *array, int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string);
extern void   cJSON_DeleteItemFromObject(cJSON *object, const char *string);

/* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);

/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item, int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */

/* ParseWithOpts allows you to require (and check) that the JSON is null
 * terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value, const char **return_parse_end,
                                  int require_null_terminated);

extern void cJSON_Minify(char *json);

/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name)          cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name)          cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name)         cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b)        cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n)      cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)      cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddDoubleToObject(object,name,d,p)    cJSON_AddItemToObject(object, name, cJSON_CreateDouble(d,p))

/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val)           ((object)?(object)->valueint=(object)->valuedouble=(val):(val))

#ifdef __cplusplus
}
#endif

#endif

测试代码

#define HTTPS_KEY_OPT1              "opt1"
#define HTTPS_KEY_OPT1_PARAM        "opt1_param"
#define HTTPS_KEY_USE_MC            "use_mc"
#define HTTPS_KEY_SER_URL           "r_url"
#define HTTPS_KEY_CA_SER_URL        "rc_url"
#define HTTPS_KEY_API_KEY           "api_key"
    cJSON *cJsonRoot  = NULL;
    cJSON *cJsonOpt1 = NULL;
    cJSON *cJsonUrl = NULL;
    size_t tmp;
    cJsonRoot = cJSON_CreateObject();
    cJSON_AddBoolToObject(cJsonRoot, HTTPS_KEY_OPT1, false);
    cJSON_AddBoolToObject(cJsonRoot, HTTPS_KEY_USE_MC, true);
    cJSON_AddStringToObject(cJsonRoot, HTTPS_KEY_SER_URL, "www.baidu.com");
    cJSON_AddStringToObject(cJsonRoot, HTTPS_KEY_CA_SER_URL, "");
    cJSON_AddStringToObject(cJsonRoot, HTTPS_KEY_OPT1_PARAM, "");
    cJSON_AddStringToObject(cJsonRoot, HTTPS_KEY_API_KEY, "");
    
    
    printf("cJSON_Print : [%s]\n",cJSON_Print(cJsonRoot));
    cJsonOpt1 = cJSON_GetObjectItem(cJsonRoot, HTTPS_KEY_OPT1);
    printf("%d-opt:%d\n",cJsonOpt1->type,cJsonOpt1->valueint);
    cJsonUrl = cJSON_GetObjectItem(cJsonRoot, HTTPS_KEY_SER_URL);
    printf("%d-[%s]\n",cJsonUrl->type,cJsonUrl->valuestring);
    while(1)
    {
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值