cson beta

CSON:C的轻量级JSON解析器 CSON 请参阅lite分支以获取简单的hashmap实现 立即下载
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

//#define MEM_LEAK_TEST
#ifdef MEM_LEAK_TEST
#define BUFFER_SIZE 500
typedef char buffer_size_type[1024 * 1024];
buffer_size_type s_test_buffer[BUFFER_SIZE] = {0};
int s_test_list[BUFFER_SIZE] = {0};
#define  calloc(size,counts) calloc_p(size,counts)
#define  free(p) free_p(p)

static void* calloc_p(int size, int counts) {
    for (int i = 0; i < sizeof (s_test_buffer) / sizeof (s_test_buffer[0]); ++i) {
        if (s_test_list[i]) continue;
        s_test_list[i] = 1;
        return (void*) &s_test_buffer[i];
    }
}

static void free_p(void* p) {
    int index = (int) ((buffer_size_type*) p - s_test_buffer);
    if (index < 0) {
        return;
    }
    memset(&s_test_buffer[index], 0, sizeof (s_test_buffer[index]));
    s_test_list[index] = 0;
}

static void check() {
    for (int i = 0; i < sizeof (s_test_list) / sizeof (s_test_list[0]); ++i) {
        if (s_test_list[i]) {
            printf("%d leak...%s\n", i, (char*) &s_test_buffer[i]);
        }
    }
}
#endif


#if !defined(_GNU_SOURCE) && !defined(_USE_GNU)
#ifdef WIN32
#define snprintf _snprintf
#endif

int asprintf(char** dst, const char* fmt, ...) {
    static FILE* tmp_file = NULL;
    int size = 0;
    va_list ap, rp;
    va_start(ap, fmt);
    va_start(rp, fmt);
    if (NULL == tmp_file) {
        tmp_file = tmpfile();
    }
    size = vfprintf(tmp_file, fmt, ap);
    if (size < 0) {
        goto out;
    }
    *dst = (char*) calloc(sizeof (char), size + 1);
    size = vsnprintf(*dst, size + 1, fmt, rp);
out:
    va_end(ap);
    va_end(rp);
    return size;
}

char* strndup(const char*src, int len) {
    char* dst = (char*) calloc(sizeof (char), len + 1);
    strncpy(dst, src, len);
    return dst;
}
#endif



#ifndef BUCKET_SIZE
#define BUCKET_SIZE 1024
#endif

//#define LEVEL 1
#if defined(LEVEL)
#define DEBUG(fmt,...) printf("[%d,%s]:"fmt,__LINE__,__FUNCTION__,##__VA_ARGS__)
#define TRACE(fmt,...) printf("[%d,%s]:"fmt,__LINE__,__FUNCTION__,##__VA_ARGS__)
#else
#define DEBUG(fmt,...) 
#define TRACE(fmt,...) 
#endif

#define JSON_OBJ_BEGIN(x) const char* x[] = {
#define VALUE_ITEM(name,value) ("\"" #name "\":" #value )
#define ARRAY_ITEM(name,...) ("\""   #name "\":["#__VA_ARGS__"]")
#define STR_ITEM(name,value) ("\""   #name"\":"#value)
#define JSON_OBJ_END(x) }

typedef struct json_item_tag {
    char* key;
    char* value;
    unsigned flag;
} json_item_t, *json_item_handle;
enum{
    em_del = 0x1,
    em_sri = 0x2
};
typedef struct hash_bucket_tag {
    struct hash_bucket_tag* next;
    int position;
} hash_bucket_t, *hash_bucket_handle;

typedef struct json_obj_tag {
    int size, used;
    hash_bucket_t bucket[BUCKET_SIZE];
    json_item_t items[];
} json_obj_t, *json_obj_handle;

json_obj_handle create_json_obj(int size);
void  destroy_json_obj(json_obj_handle h);


#define name_id(name) ((strlen(name) + *(int*)name) % BUCKET_SIZE)


static void clear_bucket(hash_bucket_handle h) {
    if (NULL == h) {
        return;
    }
    clear_bucket(h->next);
    free(h);
}


#define free_and_nil(x) do{free(x);x=NULL;}while(0)        

static json_item_handle get_json_item(json_obj_handle h, const char* name) {
    int index = name_id(name);
    hash_bucket_handle hh = &h->bucket[index];
    if (0 == hh->position && NULL == hh->next) {
        hh->position = h->used++;
        DEBUG("new position at %d\n", hh->position);
        return &h->items[hh->position];
    }
    for (; 0 != strcmp(h->items[hh->position].key, name);) {
        if(h->items[hh->position].flag & em_del){
            json_item_handle it = &h->items[hh->position];
            free_and_nil(it->key);
            free_and_nil(it->value);
            it->flag = 0;
            DEBUG("reused deleted posion at %d\n",hh->position);
            break;
        }
        if (NULL == hh->next) {
            hh->next = (hash_bucket_handle) calloc(sizeof (hash_bucket_t), 1);
            hh->next->position = h->used++;
            hh = hh->next;
            DEBUG("%s crashed new pos at %d\n", name, hh->position);
            break;
        }
        hh = hh->next;
    }
    return &h->items[hh->position];
}

#ifdef insert_json_item
#undef insert_json_item
#endif
#define insert_json_item(fmt,h,name,v) do{\
	json_item_handle __ih__ = get_json_item(h,name);\
	if(NULL == __ih__->key) asprintf(&__ih__->key,"%s",name);\
	if(NULL != __ih__->value) free(__ih__->value);\
	asprintf(&__ih__->value,fmt,v);\
}while(0)

int insert_json_obj_handle_value(json_obj_handle h, const char* name, json_obj_handle son) {
    int i = 0;
    for (; i < son->used; ++i) {
        char* name_str = NULL;
        asprintf(&name_str, "%s.%s", name, son->items[i].key);
        insert_json_item("%s", h, name_str, son->items[i].value);
        free(name_str);
    }
    return i;
}
#define insert_float_value(h,name,value) insert_json_item("%lf",h,name,value)
#define insert_int_value(h,name,value) insert_json_item("%d",h,name,value)
#define insert_double_value(h,name,value) insert_json_item("%lf",h,name,value)
#define insert_string_value(h,name,value) insert_json_item("\"%s\"",h,name,value)
#define insert_bool_value(h,name,value) insert_json_item((value ? "true" : "false"),h,name,value)
#define insert_NULL_value(h,name,value) insert_json_item("null",h,name,value)
#define insert_value(h, name,type,value) insert_##type##_value(h,name,value)



const char* get_json_value(json_obj_handle h, const char* name,const char* fmt,void* value) {
    int index = name_id(name);
    hash_bucket_handle hh = &h->bucket[index];
    for (; NULL != hh; hh = hh->next) {
        json_item_handle it = &h->items[hh->position];
        if (0 != strcmp(it->key, name) || (it->flag & em_del)) {
            continue;
        }
        if (NULL != value && NULL != fmt) {
            TRACE("convert %s : %s by %s fmt\n", name, it->value, fmt);
            sscanf(it->value, fmt, value);
        }
        return it->value;
    }
    DEBUG("%s not found the value\n",name);
    return NULL;
}
#define get_float_value(h,name,value) (NULL != get_json_value(h,name,"%f",value))
#define get_double_value(h,name,value) get_float_value
#define get_int_value(h,name,value) (NULL != get_json_value(h,name,"%d",value))
#define get_bool_value(h,name,value) get_int_value

int get_string_value(json_obj_handle h, const char* name, char** value) {
    const char* ret = get_json_value(h, name, "", NULL);
    if (NULL == ret) {
        *value = NULL;
        DEBUG("%s not found the value\n",name);
        return 0;
    }
    TRACE("get %s = %s \n",name,ret);
    asprintf(value, "%s", ret);
    return 1;
}

int get_json_obj_handle_value(json_obj_handle h,const char* name,json_obj_handle* son){
    int i = 0,len = strlen(name);
    *son = create_json_obj(100);
    for (; i < h->used; ++i) {
        if (0 != strncmp(h->items[i].key, name, len) || (h->items[i].flag & em_del)) {
            continue;
        } else {
            const char* sub_key = &h->items[i].key[len + 1];
            const char* sub_val = h->items[i].value;
            json_item_handle it = get_json_item(*son, sub_key);
            /*
             * using "%s" copy string avoid src string had % act..
             */
            TRACE("%s.%s = %s\n", name, sub_key, sub_val);
            asprintf(&it->key, "%s", sub_key);
            asprintf(&it->value, "%s", sub_val);
        }
    }    
    if(0 != (*son)->used){
        DEBUG("new object %s had %d items created\n",name,(*son)->used);
        return 1;
    }
    destroy_json_obj(*son);
    *son = NULL;
    return 0;
}
#define get_value(h,name,type,value) get_##type##_value(h,name,&(value))

#ifdef create_array_insert
#undef create_array_insert
#endif
#ifdef insert_array_item
#undef  insert_array_item
#endif 
#define insert_array_item(h,name,type,index,val) do{\
        char* __name_str__ = NULL;\
        asprintf(&__name_str__,"%s[%d]",name,index);\
        insert_value(h,__name_str__,type,val);\
        free(__name_str__);\
}while(0)
#define create_array_insert(f_name,type) int insert_##f_name##_array(json_obj_handle h, const char* name, ...) {\
    union{\
        int  last;\
        type val;\
    }dst_val;\
    int i = 0,lbreak = 0;\
    va_list al;\
    va_start(al, name);\
    lbreak = va_arg(al,int);\
    for (dst_val.val = va_arg(al, type); dst_val.last != ']'; dst_val.val = va_arg(al, type)) {\
        insert_array_item(h,name,f_name,i++,dst_val.val);\
    }\
    return i;\
}
create_array_insert(int, int)
create_array_insert(double, double)
create_array_insert(string, char*)
create_array_insert(json_obj_handle, json_obj_handle)
#ifdef create_array_insert
#undef create_array_insert
#endif
#ifdef insert_array_item
#undef  insert_array_item
#endif 

#ifdef insert_array
#undef insert_array
#endif
#define insert_array(h,name,type,...) insert_##type##_array(h,name,'[',__VA_ARGS__,']')

#define get_array_item(h,name,type,index,value) do{\
        char* __name_str__ = NULL;\
        asprintf(&__name_str__,"%s[%d]",name,index);\
        get_value(h,__name_str__,type,value);\
        free(__name_str__);\
}while(0)

#define get_array(h,name,type,dst,size) do{\
    int __i__ = 0,__k__ = 0;\
    for (; (__i__ < h->used) && (__k__ < size); ++__i__) {\
        char* __name_str__ = NULL;\
        asprintf(&__name_str__, "%s[%d]", name, __i__);\
        if(get_value(h, __name_str__, type, dst[__k__])){\
            TRACE("%s[%d] gotted the value at %d\n",__name_str__,__i__,__k__);\
            ++__k__;\
        };\
        free(__name_str__);\
    }\
    size = __k__;\
    DEBUG("%s got %d items\n",name,size);\
}while(0)

static void rebuild_josn_bucket(json_obj_handle h) {
    int i = 0;
    for (; i < BUCKET_SIZE; ++i) {
        clear_bucket(h->bucket[i].next);
    }
    memset(h->bucket, 0, sizeof (h->bucket));
    for (int i = 0; i < h->used; ++i) {
        int index = name_id(h->items[i].key);
        hash_bucket_handle hh = &h->bucket[index];
        for (; NULL != hh; hh = hh->next) {
            if (NULL == hh->next && 0 == hh->position) {
                h->bucket[index].position = i;
                break;
            }else if(NULL == hh->next){
                hh->next = (hash_bucket_t*)calloc(sizeof(hash_bucket_t),1);
                hh->next->position = i;
                break;
            }else{
                ;
            }
        }
    }
}


void pack_json_item(json_obj_handle h) {
    int i = 0;
    DEBUG("json had %d items\n",h->used);
    for (i = 0; i < h->used; ++i) {        
        json_item_handle it = &h->items[i];
        if(!(it->flag & em_del)){
            TRACE("%d(%s) not deleleted \n",i,it->key);
            continue;
        }
        DEBUG("removed %d(%s) item\n",i,it->key);
        free_and_nil(it->key);
        free_and_nil(it->value);
        memmove(&h->items[i], &h->items[i + 1], (h->used -i) * sizeof(json_item_t));
        memset(&h->items[h->used--], 0, sizeof (json_item_t));
        --i;
    }
    TRACE("left %d item in %p handle\n",h->used,h);
    rebuild_josn_bucket(h);
}

void remove_json_simple_item(json_obj_handle h, const char* name) {
    int index = name_id(name);
    hash_bucket_handle hh = &h->bucket[index];
    for (; NULL != hh; hh = hh->next) {
        json_item_handle it = &h->items[hh->position];
        if ((it->flag & em_del)||(0 != strcmp(it->key, name))) {
            continue;
        }        
        /*
         * logic delete item avoid rehash 
         */
        TRACE("will be remove %s at %d\n", it->key, hh->position);
        it->flag |= em_del;
    }
}

void remove_json_complex_item(json_obj_handle h, const char* name, const char* fix) {
    int i = 0;
    char* name_str = NULL;
    int len = asprintf(&name_str, "%s%s", name, fix);
    TRACE("try to remove %s(%d)\n",name_str,len);
    for (; i < h->used; ++i) {
        if ((h->items[i].flag & em_del) || (0 != strncmp(h->items[i].key, name_str, len))) {
            continue;
        }
        /*
         * logic delete item avoid rehash 
         */
        TRACE("will be remove %s at %d,name = %s(%d)\n", h->items[i].key, i,name_str,len);
        h->items[i].flag |= em_del;
    }
    free(name_str);
}

#define remove_int_value(h,name) remove_json_simple_item(h,name)
#define remove_string_value(h,name) remove_json_simple_item(h,name)
#define remove_double_value(h,name) remove_json_simple_item(h,name)
#define remove_float_value(h,name) remove_json_simple_item(h,name)
#define remove_bool_value(h,name) remove_json_simple_item(h,name)
#define remove_NULL_value(h,name) remove_json_simple_item(h,name)
#define remove_json_obj_handle_value(h,name) remove_json_complex_item(h,name,".")
#define remove_array_value(h,name) remove_json_complex_item(h,name,"[")
#define remove_value(h,name,type) remove_##type##_value(h,name)

#define remove_array_item(h,name,index,type) do{\
        char* __fix__ = NULL;\
        asprintf(&__fix__,"%s[%d]",name,index);\
        remove_value(h,__fix__,type);\
        free(__fix__);\
}while(0)




json_obj_handle create_json_obj(int size) {
    json_obj_t* ret = (json_obj_handle) calloc(size * sizeof (json_item_t) + sizeof (json_obj_t), 1);
    ret->size = size;
    return ret;
}

char** sort_json_key(json_obj_handle h) {
    int i = 0, j = 0;
    char** results = (char**) calloc(sizeof (char*), h->used + 1);
    results[0] = h->items[0].key;
    for (; i < h->used; ++i) {
        for (j = 0; j < i; ++j) {
            if (strcmp(h->items[i].key, results[j]) < 0) {
                break;
            }
        }
        memmove(&results[j + 1], &results[j], h->used - j - 1);
        results[j] = h->items[i].key;
    }
    return results;
}

static int object_to_string(json_obj_handle h, const char*const skip_name, char buffer[], int size) {
    int i = 0, len = 0;
    char *sub_str = NULL, *array = NULL, *objec = NULL;
    DEBUG("skip = %s(%d), len = %d\n", skip_name, strlen(skip_name), size);
    for (; i < h->used; ++i) {
        DEBUG("buffer[%d,%s] = %s\n", i, h->items[i].key, buffer);
        if ((h->items[i].flag & em_sri) || (h->items[i].flag & em_del)) {
            DEBUG("processed %s pass...\n", h->items[i].key);
            continue;
        }
        if (0 != strncmp(h->items[i].key, skip_name, strlen(skip_name))) {
            DEBUG("no match %s pass...\n", h->items[i].key);
            continue;
        }
        sub_str = h->items[i].key + strlen(skip_name);
        array = strstr(sub_str, "[");
        objec = strstr(sub_str, ".");
        DEBUG("sub_str = %s(%p),array = %p,objec = %p\n", sub_str, sub_str, array, objec);
        /*
         * normal key:value pair
         */
        if (NULL == array && NULL == objec) {
            char* str = NULL;
            asprintf(&str, "\"%s\":%s", sub_str, h->items[i].value);
            h->items[i].flag |= em_sri;
            len += snprintf(&buffer[len], size - len, "%s,", str);
            free(str);
            continue;
        }
        DEBUG("item name = %s\n", h->items[i].key);
        /*
         * array list key : []
         */
        if (NULL != array && (NULL == objec || array < objec)) {
            char* name = strndup(sub_str, (int) (array - sub_str));
            int index = 0, j = 0;
            DEBUG("array sub_str = %s,name = %s\n", sub_str, name);
            len += snprintf(&buffer[len], size - len, "\"%s\":[", name);
            for (j = 0; j < h->used; ++j) {
                char* skip = NULL;
                if ((h->items[j].flag & em_sri) || (h->items[j].flag & em_del)) {
                    continue;
                }
                asprintf(&skip, "%s[%d]", name, index++);
                if (0 != strncmp(h->items[j].key, skip, strlen(skip))) {
                    free(skip);
                    continue;
                }
                DEBUG("will be process array : %s\n", skip);
                if (h->items[j].key[strlen(skip)] == '.') {
                    len += object_to_string(h, skip, &buffer[len], size - len);
                } else {
                    len += snprintf(&buffer[len], size - len, "%s,", h->items[j].value);
                    h->items[j].flag |= em_sri;
                }
                free(skip);
            }
            free(name);
            --len;
            len += snprintf(&buffer[len], size - len, "],");
            TRACE("array buffer = %s\n", buffer);
        } else {
            /*
             * object key : {}
             */
            char* name = strndup(sub_str, (int) (objec - sub_str));
            char* skip = strndup(h->items[i].key, (int) (objec - h->items[i].key) + 1);
            DEBUG("object sub_str = %s, name = %s,skip_str = %s\n", sub_str, name, skip);
            if (0 != strlen(name)) {
                len += snprintf(&buffer[len], size - len, "\"%s\":{", name);
            } else {
                len += snprintf(&buffer[len], size - len, "{");
            }
            len += object_to_string(h, skip, &buffer[len], size - len) - 1;
            len += snprintf(&buffer[len], size - len, "},");
            TRACE("object buffer = %s\n", buffer);
            free(skip);
            free(name);
        }

    }
    TRACE("%s %s %d\n", skip_name, buffer, len);
    return len;
}

const char* to_string(json_obj_handle h, char buffer[], int size) {
    int len = snprintf(buffer, size, "{");
    len += object_to_string(h, "", &buffer[len], size - len) - 1;
    len = (len > 0) ? len : 1;
    snprintf(&buffer[len], size - len, "}");
    for (len = 0; len < h->used; ++len) {
        h->items[len].flag &= ~(em_sri);
    }
    return buffer;
}

void destroy_json_obj(json_obj_handle h) {
    int i = 0;
    for (; i < h->used; ++i) {
        free(h->items[i].key);
        free(h->items[i].value);
    }
    for (i = 0; i < BUCKET_SIZE; ++i) {
        clear_bucket(h->bucket[i].next);
    }
    free(h);
}

test

JSON_OBJ_BEGIN(obj)
VALUE_ITEM(age, 18),
ARRAY_ITEM(arrays, 1, 2, 3, 4, 5.6),
STR_ITEM(name, "zhang san"),
JSON_OBJ_END(obj);


char buffer[10240] = {0};

static void param_test() {
    json_obj_handle h = create_json_obj(10240);

    /*
            insert value
     */
    insert_value(h, "age", int, 18);
    {
        int age = 0;
        get_value(h,"age",int,age);
        assert(age == 18);
    }
    /*
            insert string
     */
    insert_value(h, "name", string, "zhangsan");
    {
        char* name_str = NULL;
        get_value(h,"name",string,name_str);
        assert(0 == strcmp(name_str,"\"zhangsan\""));
        free(name_str);
    }
    /*
            insert object
     */
    {
        json_obj_handle local = create_json_obj(10);
        insert_value(local, "city", string, "sh");
        insert_value(local, "mailNo", string, "200240");
        insert_value(h, "local", json_obj_handle, local);
        destroy_json_obj(local);
    }
    {
        json_obj_handle jh = NULL;
        get_value(h,"local",json_obj_handle,jh);
        assert(NULL != jh);
        destroy_json_obj(jh);
    }
    /*
            insert array
     */
    {
        json_obj_handle f1 = create_json_obj(10);
        json_obj_handle f2 = create_json_obj(10);

        insert_value(f1, "city", string, "sh");
        insert_value(f1, "mailNo", string, "200240");
        insert_value(f1, "mailNo",int,200241);
        insert_value(f2, "city", string, "sh");
        insert_value(f2, "mailNo", string, "200240");
        
        insert_array(h, "friends", json_obj_handle, f1, f2);
        
        destroy_json_obj(f1);
        destroy_json_obj(f2);
    }
    insert_array(h, "number", int, 1, 2, 3, 4, 5, 6, 7, 8);
    insert_array(h, "string", string, "a", "b", "c", "d", "e");
    {
        json_obj_handle jh[10] = {NULL,NULL};
        char* s[10] = {NULL};
        int   i[10] = {0};
        int len = 10,k = 1;

        get_array(h,"friends",json_obj_handle,jh,len);
        assert(2 == len);
        assert(NULL != jh[0]);
        assert(NULL != jh[1]);
        assert(NULL == jh[2]);
        for(k = 0; k < 2; ++k){
            destroy_json_obj(jh[k]);
        }
        len = 10;
        get_array(h,"number",int,i,len);
        assert(8 == len);
        for(k = 0; k < 8; ++k){
            assert( (k+1) == i[k]);
        }        
        assert(0 == i[9]);
        len = 10;
        get_array(h,"string",string,s,len);
        assert(5 == len);
        assert(0 == strcmp(s[0],"\"a\""));
        assert(NULL == s[9]);
        get_array_item(h,"number",int,3,len);
        assert(4 == len);
        get_array_item(h,"string",string,0,s[9]);
        assert(0 == strcmp(s[0],s[9]));
        for(k = 0; k < 5 ; ++k){
            free(s[k]);
        }                      
        free(s[9]);
    }
    /*
            insert bool
     */
    insert_value(h, "boolean1", bool, 1);
    insert_value(h, "boolean2", bool, 0);
    /*
            insert null
     */
    insert_value(h, "null", NULL, NULL);
    
    to_string(h, buffer, sizeof (buffer));
    //printf("%s\n", buffer);
    /*
     * remove test
     */
    {
        int age = 0;
        remove_value(h,"age",int);
        assert(0 == get_value(h,"age",int,age));
    }
    {
        char* name = NULL;
        remove_value(h,"name",string);
        assert(0 == get_value(h,"name",string,name));
        assert(NULL == name);
    }
    {
        json_obj_handle jh = NULL;
        remove_value(h,"local",json_obj_handle);        
        assert(0 == get_value(h,"local",json_obj_handle,jh));
        assert(NULL == jh);
    }
    {
        json_obj_handle ja[10] = {0},jh = NULL;
        int size = 10;
        remove_array_item(h,"friends",0,json_obj_handle);
        get_array_item(h,"friends",json_obj_handle,0,jh);
        assert(0 == jh);
        get_array(h,"friends",json_obj_handle,ja,size);
        assert(1 == size);
        assert(NULL != ja[0]);
        assert(NULL == ja[1]);
        destroy_json_obj(ja[0]);
        remove_value(h,"friends",array);
        size = 10;
        get_array(h,"friends",json_obj_handle,ja,size);
        assert(0 == size);
        assert(NULL == ja[0]);
    }
    {
        int ai[10] = {0},len = 10;
        remove_array_item(h,"number",3,int);
        get_array(h,"number",int,ai,len);
        assert(7 == len);
        assert(5 == ai[3]);
        assert(0 == ai[9]);
        remove_value(h,"number",array);
        len = 10;
        get_array(h,"number",int,ai,len);
        assert(0 == len);
    }
    {
        char* ai[10] = {NULL};
        int len = 10;
        remove_array_item(h,"string",3,string);
        get_array(h,"string",string,ai,len);
        assert(4 == len);
        assert(0 == strcmp("\"e\"",ai[3]));
        assert(NULL == ai[9]);
        remove_value(h,"string",array);
        for(len = 0; len < 10; ++len){
            free(ai[len]);
            ai[len] = NULL;
        }
        len = 10;
        get_array(h,"string",string,ai,len);
        assert(0 == len);
    }    
    {
        remove_value(h,"boolean1",bool);
        remove_value(h,"boolean2",bool);
        remove_value(h,"null",NULL);
    }
    memset(buffer, 0, sizeof (buffer));
    to_string(h, buffer, sizeof (buffer));
    assert(0 == strcmp("{}",buffer));
    {
        assert(24 == h->used);
        insert_value(h,"test",string,"this is a test");
        pack_json_item(h);    
        assert(1 == h->used);
    }  
    {
        char* test_str = NULL;
        get_value(h,"test",string,test_str);
        assert(NULL != test_str);
        assert(0 == strcmp("\"this is a test\"",test_str));   
        free(test_str);
    }
    
    destroy_json_obj(h);
}

int main(int argn, const char* argv[]) {
    for(;;)param_test();
#ifdef MEM_LEAK_TEST
    check();
#endif
    return 0;
}


手把手教你用西门子博图V18配置阿特拉斯PF6000拧紧枪PN通讯(附完整GSD文件与ToolsTalk配置文件) 本文详细介绍了如何使用西门子博图V18配置阿特拉斯PF6000拧紧枪的PN通讯,包括硬件连接、网络参数规划、ToolsTalk软件配置及博图工程设置。通过完整的GSD文件和配置文件,帮助工程师快速实现高精度拧紧设备与PLC的高效通讯,适用于汽车装配和电子制造等工业自动化场景。 阅读详情

相关推荐

从0到1:.NET 9 OpenAPI全攻略!Swagger vs Scalar UI谁更强?

OpenAPI:.NET 9的智能文档革命 本文深入解析.NET 9的OpenAPI支持,对比Swagger UI与Scalar UI的优劣,提供实战代码示例: 一键生成:AddOpenApi()+MapOpenApi()快速生成标准文档 UI工具对决: Swagger UI功能全面但复杂 Scalar UI简约现代,原生支持cURL/HTTPie 进阶技巧: XML注释增强文档可读性 自定义Transformer实现文档动态修改 🔥核心价值:.NET 9的OpenAPI方案显著降低API文档维护成本,开

java专栏 1427

cson基于C语言的json数据映射解析库

https://github.com/NevermindZZT/cson

ZHANG13HAO的博客 3093

亲友圈棋牌的逆向工程_棋牌透视分析研究(一)

透视也能实现,有些台子就自带控制,这种东西权限只是存在于平台运营者手中,即便逆向破解也很难发现,但也有那么一些棋牌 比如斗牛或者跑得快,会先发给你的内存中存放当前的牌的信息,这样你就可以知道对面的牌是什么,但肯定也是加密了。明明是zip却无法解压,这很明显是属于被加密了, 那么我们就要开始找他的加密内容,一般加密的秘钥都会存储在so里面。写这一篇文章了,其实也想了很久,最终还是决定写了, 有些朋友找我做过菠菜的逆向,bjl,甚至是足球的!但很遗憾的告诉大家,这里是找不到的。

m0_63368535的博客 5801

【免费下载】 CSON 项目使用教程

CSON 是一个基于 cJSON 的 JSON 数据映射解析库,运行于 C 语言平台。它通过模型映射的方式,将 JSON 数据直接解析成结构体,简化了使用原生 cJSON 进行多次 API 调用的复杂性。CSON 借鉴了高级语言的反射机制,通过建立数据模型记录结构体的元素、类型和偏移,在内存层面进行操作,提供了高效的 JSON 解析工具。 ## 项目快速启动 ### 安装 首先,确保你已经安...

gitblog_00441的博客 6935

我想自己组装一台服务器,微调大模型通义千问2.5 Omni 72B,但是我是个人购买,资金非常有限,最省的方案

阶段动作✅ 推理用 GGUF + llama.cpp + 4090 加载 14B INT4✅ 微调训练 Qwen2.5-7B-Chat,使用 LoRA / QLoRA❌ 放弃Qwen2.5-Omni-72B 全量微调(显存需求 >160G,不现实)

AngelCryToo的专栏 2822

手把手拆解:储能电站如何实现‘孤岛运行’与‘黑启动’?从SVPWM控制到无缝并网

本文深入解析储能电站的孤岛运行与黑启动技术,从SVPWM控制策略到电网重构实战。通过详细的三环控制架构和黑启动五阶段技术路线,展示储能电站在电网故障时如何快速切换为独立电压源并实现电网重建。文章还探讨了虚拟惯量补偿、多站协同控制等前沿技术,为电力系统应急恢复提供关键解决方案。

weixin_30509393的博客 304

在C语言上优雅地使用json - CSON原理解析

前言 json是目前最为流行的文本数据传输格式,特别是在网络通信上广泛应用,随着物联网的兴起,在嵌入式设备上,也需要开始使用json进行数据传输,那么,如何快速简洁地用C语言进行json的序列化和反序列化呢 当前,应用最广泛的C语言json解析库当属cJSON,但是,使用cJSON读json进行序列化和反序列化,需要根据key一个一个进行处理,会导致代码冗余,逻辑性不强,哪有没有更好的方法呢 思路...

Letter 1万+

ADS中HB仿真自动优化报错问题解决心得

在ADS HB仿真中自动优化出现报错被强制暂停,解决方法如下

yyyyyyyyyyjy的博客 6536

【亲测免费】 CSON:基于C语言的JSON解析库及其使用指南

**项目基础介绍:** CSON(C Son)是由开发者NevermindZZT创建并维护的一个开源项目,它是一个专为C语言设计的JSON数据映射解析库。这个库的核心目标是简化JSON数据与C语言结构体之间的相互转换过程。不同于传统的逐层解析方式,CSON利用模型映射方法,允许开发者定义数据模型来描述结构体特性,从而实现JSON数据的快速、高效解析。项目遵循MIT许可协议,这使得它在开源社区内非常...

gitblog_01210的博客 1944

【01】Canoe零基础手把手教学 --- Canoe安装

Canoe零基础手把手教学

jaytinlove的博客 7742

CAPL控制程控电源

汽车电子测试过程中,除了实车测试,还有台架测试,在进行台架测试时,都需要通过电源来模拟汽车电瓶给ECU供电,如果要进一步进行比较高效的压力测试或自动化测试,就需要用到程控电源,所以本章主要介绍CAPL是如何来控制程控电源的。

测试领域技术分享 4387

CJSON入门(CJSON下载,基本使用)

CJSON的安装,CJSON的介绍,CJSON的常用函数介绍,使用CJSON库解析字符串,使用CJSON函数组json数据

m0_51531114的博客 6729

GEE:本地影像上传到GEE的Assets中,并输入机器学习算法中作为特征变量

当我们在 Google Earth Engine(GEE)中应用机器学习算法时,会输入一些影像作为特征变量数据,进一步根据这些特征影像去推理未知区域的数据。但是 GEE 平台上计算特征变量的 API 函数并不是非常全面,我们希望获得更多的特征用于分类。这个时候,我们可以将本地计算的特征影像上传到 GEE 中进行后续处理。本文记录了从本地上传特征数据到 GEE 的 Assets 中的教程,用于后续在 GEE 中分类或者回归使用。本文也可作为《》一文的补充。

养乐多的博客 1730

atom使用笔记

atom使用笔记

enthan809882的博客 1644

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

探索 CSON:强大的数据处理利器

CSON 作为一种创新的数据交换格式,以其独特的设计和丰富的功能,在数据处理领域展现出了强大的潜力。它的出现为开发者在处理配置文件、数据备份、API 数据传输等场景时提供了更优的选择。无论是在前端开发、后端开发还是嵌入式开发等不同领域,CSON 都能够凭借其易读易写、灵活的数据类型支持、高效性和良好的兼容性等特点,为项目的开发和维护带来便利。如果您正在寻找一种既有 JSON 的简洁性,又具备更多灵活性的数据格式,不妨尝试一下 CSON,相信它会给您带来惊喜。

ZHANGKB_的博客 5704

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

序列化的不同格式:JSON、XML、TOML、CSON、YAML

总的来说,每种格式均有其独特的侧重点,根据不同的使用场景可以选择不同的格式。JSON 简洁通用,YAML 功能全面可读性强,XML啰嗦但自描述能力强,TOML 紧凑易用但缺乏支持,CSON 则过于语言绑定。

Fishermen_sail的博客 1389

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C语言实现Json与结构体相互转换——cson

写在最前面,不擅长写文档和博客,自惭行文拖沓,不爱看的直接移步:https://github.com/sunchb/cson.git 目录前言实现1.实现“反射”1.1.描述结构体属性1.2.访问结构体属性1.3.结构体属性赋值1.3.数组和结构体类型的描述2.序列化3.反序列化代码及Demo 前言 之前用C语言解析过json,虽然借助jansson这样强大的解析库,可以将字符串转化为json对象...

s448573057的博客 2万+

CSON 项目下载及安装教程

CSON 是一个基于 C 语言的 JSON 数据映射解析库。它通过模型映射的方式,将 JSON 数据直接解析成结构体,免去了使用原生 cJSON 需要多次调用 API 的复杂性,可以很大程度减少代码冗余,增加代码逻辑性。CSON 的模型映射借鉴了高级语言(如 Java)的反射机制,通过建立数据模型,记录结构体的元素、类型、偏移,然后直接在内存层面进行操作,对 C 语言提供类似于 gson 这样的高...

gitblog_01219的博客 1304

【亲测免费】 CSON:基于C语言的JSON解析库安装与配置完全指南

CSON(C-based Object Notation)是一个专为C语言开发者设计的开源项目,它提供了一种高效的方式来处理JSON数据。这个项目由NevermindZZT维护,并且在GitHub上托管,链接为[https://github.com/NevermindZZT/cson.git](https://github.com/NevermindZZT/cson.git)。CSON的核心特性在...

gitblog_01235的博客 1330

10分钟入门CSON:从安装到实战的终极教程

CSON(CoffeeScript-Object-Notation)是一种基于CoffeeScript语法的配置文件格式,它像JSON一样用于数据交换,但提供了更灵活的语法和更好的可读性。本文将带你快速掌握CSON的核心优势、安装方法和实战技巧,让你在10分钟内从入门到熟练使用这个强大的工具。 ## 🚀 为什么选择CSON?JSON的完美替代方案 相比JSON的严格语法,CSON带来了多项革

gitblog_00065的博客 1012

探索CSON:C语言中的高效JSON解析工具

在现代软件开发中,JSON作为一种轻量级的数据交换格式,被广泛应用于各种系统和平台之间的数据传输。对于C语言开发者而言,高效且易用的JSON解析工具尤为重要。今天,我们将深入介绍一个基于C语言的开源项目——CSON,它通过模型映射的方式,极大地简化了JSON数据的解析和序列化过程。 ## 项目介绍 CSON是一个运行于C语言平台的JSON-Struct模型解析工具,它基于cJSON进行二次封装...

gitblog_00697的博客 728

AI驱动的项目管理:Awesome Claude Skills任务自动化工具

在当今快节奏的工作环境中,高效的项目管理和任务自动化已成为团队成功的关键因素。Awesome Claude Skills作为一个精心策划的Claude技能集合,为用户提供了强大的任务自动化工具,帮助团队轻松实现项目管理流程的智能化和自动化。通过这些工具,用户可以显著提高工作效率,减少重复劳动,让团队专注于更有价值的创造性工作。 ## 项目管理自动化的核心优势 任务自动化在现代项目管理中扮演着越

gitblog_00064的博客 1082

CouchDB-Triq 项目使用教程

CouchDB-Triq 项目使用教程 1. 项目的目录结构及介绍 CouchDB-Triq 项目的目录结构如下: couchdb-triq/ ├── doc/ ├── include/ ├── pages/ ├── src/ ├── test/ ├── util/ ├── .gitignore ├── .gitlab-ci.yml ├── CONTRIBUTING.org ├── LICENSE...

gitblog_00980的博客 981

CSON解析器(cson-parser)使用手册

CSON解析器(cson-parser)使用手册 欢迎来到 CSON解析器 的快速入门指南。本教程将引导您了解此项目的目录结构、关键的启动文件以及配置文件的相关知识,帮助您迅速上手这个简单且安全的CSON解析工具。 1. 项目目录结构及介绍 CSON解析器 (cson-parser) 是一个基于Node.js的库,用于解析Coffeescript对象表示法(CSON)。以下是其典型的项目结构概览:...

gitblog_00216的博客 761

解锁CSON:重新定义数据交换的灵活性

在数据交换格式的江湖中,JSON凭借其简洁性占据半壁江山,但你是否曾因无法添加注释而抓狂?是否为必须使用双引号包裹字符串而感到束缚?CSON(CoffeeScript Object Notation)的出现,正是为了解决这些痛点。作为JSON的超集,它如何在保持兼容性的同时注入灵活性?让我们深入探索这种被低估的数据格式。 ## 🔍 技术解析:CSON的工作原理 ### 核心架构:解析器与序列

gitblog_00740的博客 1051

发现CSON:重新定义C语言中的JSON解析体验

💡 **告别重复劳动的模型映射** 你是否厌倦了用原生cJSON时反复调用`cJSON_GetObjectItem`的繁琐过程?CSON通过**数据模型映射**机制,将JSON解析简化为一行代码操作。只需定义结构体与JSON键的对应关系,就能自动完成内存分配与数据绑定,让代码量减少60%以上。 🔍 **C语言也能拥有"反射"能力** CSON创新性地模拟了高级语言的反射机制,通过`C

gitblog_00404的博客 1037
上一篇: +_*/ 0.1
下一篇: 线程A分为A1,A2两个步骤,A1执行完毕后通知线程B,线程B执行完毕后通知线程A,线程A接下来执行步骤A2
FlyAnyWhere
博客等级 码龄24年 5粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值