• json-c初探(三)


    json对象有七种类型:

    /* supported object types */
    typedef enum json_type {
      /* If you change this, be sure to update json_type_to_name() too */
      json_type_null,
      json_type_boolean,
      json_type_double,
      json_type_int,
      json_type_object,
      json_type_array,
      json_type_string
    } json_type;
    

    创建json对象:

    /* generic object construction and destruction parts */
    static void json_object_generic_delete(struct json_object* jso)
    {
    #ifdef REFCOUNT_DEBUG
    	MC_DEBUG("json_object_delete_%s: %p
    ",
    	   json_type_to_name(jso->o_type), jso);
    	lh_table_delete(json_object_table, jso);
    #endif /* REFCOUNT_DEBUG */
    	printbuf_free(jso->_pb);
    	free(jso);
    }
    
    static struct json_object* json_object_new(enum json_type o_type)
    {
    	struct json_object *jso;
    
    	jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
    	if (!jso)
    		return NULL;
    	jso->o_type = o_type;
    	jso->_ref_count = 1;
    	jso->_delete = &json_object_generic_delete;
    #ifdef REFCOUNT_DEBUG
    	lh_table_insert(json_object_table, jso, jso);
    	MC_DEBUG("json_object_new_%s: %p
    ", json_type_to_name(jso->o_type), jso);
    #endif /* REFCOUNT_DEBUG */
    	return jso;
    }
    

    json_object_new分配json对象空间,设置json对象类型,并设置基本的json对象清理函数json_object_generic_delete。

    struct json_object* json_object_new_object(void)
    {
    	struct json_object *jso = json_object_new(json_type_object);
    	if (!jso)
    		return NULL;
    	jso->_delete = &json_object_object_delete;
    	jso->_to_json_string = &json_object_object_to_json_string;
    	jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
    					     &json_object_lh_entry_free);
    	if (!jso->o.c_object)
    	{
    		json_object_generic_delete(jso);
    		errno = ENOMEM;
    		return NULL;
    	}
    	return jso;
    }
    
    struct json_object* json_object_new_array(void)
    {
    	struct json_object *jso = json_object_new(json_type_array);
    	if (!jso)
    		return NULL;
    	jso->_delete = &json_object_array_delete;
    	jso->_to_json_string = &json_object_array_to_json_string;
    	jso->o.c_array = array_list_new(&json_object_array_entry_free);
            if(jso->o.c_array == NULL)
    	{
    	    free(jso);
    	    return NULL;
    	}
    	return jso;
    }
    
    struct json_object* json_object_new_string(const char *s)
    {
    	struct json_object *jso = json_object_new(json_type_string);
    	if (!jso)
    		return NULL;
    	jso->_delete = &json_object_string_delete;
    	jso->_to_json_string = &json_object_string_to_json_string;
    	jso->o.c_string.len = strlen(s);
    	if(jso->o.c_string.len < LEN_DIRECT_STRING_DATA) {
    		memcpy(jso->o.c_string.str.data, s, jso->o.c_string.len);
    	} else {
    		jso->o.c_string.str.ptr = strdup(s);
    		if (!jso->o.c_string.str.ptr)
    		{
    			json_object_generic_delete(jso);
    			errno = ENOMEM;
    			return NULL;
    		}
    	}
    	return jso;
    }
    
    struct json_object* json_object_new_int(int32_t i)
    {
    	struct json_object *jso = json_object_new(json_type_int);
    	if (!jso)
    		return NULL;
    	jso->_to_json_string = &json_object_int_to_json_string;
    	jso->o.c_int64 = i;
    	return jso;
    }
    
    struct json_object* json_object_new_boolean(json_bool b)
    {
    	struct json_object *jso = json_object_new(json_type_boolean);
    	if (!jso)
    		return NULL;
    	jso->_to_json_string = &json_object_boolean_to_json_string;
    	jso->o.c_boolean = b;
    	return jso;
    }
    

    从上述可以看出,创建不同的json对象时,一般会设置不同的json_object_to_json_string函数,对于需要动态分配内存的json对象(object、array、string),还会设置特定的清理函数,和动态分配空间用于存放json对象的数据。

    对于object类型的json对象,采用hash table来管理其数据

    #define JSON_OBJECT_DEF_HASH_ENTRIES 16
    jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, &json_object_lh_entry_free);
    

    创建hash table的函数如下:

    struct lh_table* lh_kchar_table_new(int size, lh_entry_free_fn *free_fn)
    {
    	return lh_table_new(size, free_fn, char_hash_fn, lh_char_equal);
    }
    
    struct lh_table* lh_table_new(int size,
    			                 lh_entry_free_fn *free_fn,
    			                 lh_hash_fn *hash_fn,
    			                 lh_equal_fn *equal_fn)
    {
    	int i;
    	struct lh_table *t;
    
    	t = (struct lh_table*)calloc(1, sizeof(struct lh_table));
    	if (!t)
    		return NULL;
    
    	t->count = 0;
    	t->size = size;
    	t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry));
    	if (!t->table)
    	{
    		free(t);
    		return NULL;
    	}
    	t->free_fn = free_fn;
    	t->hash_fn = hash_fn;
    	t->equal_fn = equal_fn;
    	for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
    	return t;
    }
    

    其中,free_fn、hash_fn、equal_fn实现如下:

    /* free_fn */
    static void json_object_lh_entry_free(struct lh_entry *ent)
    {
    	if (!ent->k_is_constant)
    		free(lh_entry_k(ent));
    	json_object_put((struct json_object*)lh_entry_v(ent));
    }
    
    static lh_hash_fn *char_hash_fn = lh_char_hash;
    /* hash_fn */
    static unsigned long lh_char_hash(const void *k)
    {
    #if defined _MSC_VER || defined __MINGW32__
    #define RANDOM_SEED_TYPE LONG
    #else
    #define RANDOM_SEED_TYPE int
    #endif
    	static volatile RANDOM_SEED_TYPE random_seed = -1;
    
    	if (random_seed == -1) {
    		RANDOM_SEED_TYPE seed;
    		/* we can't use -1 as it is the unitialized sentinel */
    		while ((seed = json_c_get_random_seed()) == -1);
    #if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
    #define USE_SYNC_COMPARE_AND_SWAP 1
    #endif
    #if SIZEOF_INT == 4 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
    #define USE_SYNC_COMPARE_AND_SWAP 1
    #endif
    #if SIZEOF_INT == 2 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
    #define USE_SYNC_COMPARE_AND_SWAP 1
    #endif
    #if defined USE_SYNC_COMPARE_AND_SWAP
    		(void)__sync_val_compare_and_swap(&random_seed, -1, seed);
    #elif defined _MSC_VER || defined __MINGW32__
    		InterlockedCompareExchange(&random_seed, seed, -1);
    #else
    //#warning "racy random seed initializtion if used by multiple threads"
    		random_seed = seed; /* potentially racy */
    #endif
    	}
    
    	return hashlittle((const char*)k, strlen((const char*)k), random_seed);
    }
    
    /* equal_fn */
    int lh_char_equal(const void *k1, const void *k2)
    {
    	return (strcmp((const char*)k1, (const char*)k2) == 0);
    }
    
  • 相关阅读:
    Ext Form
    Ext中 get、getDom、getCmp的区别
    Ext.state.Manager.setProvider(new Ext.state.CookieProvider())
    Ext BoxComponent
    Ext表单提示方式:msgTarget
    Ext.QuickTips.init()的使用
    Ext.Ajax.Request
    FitLayout
    视图Ext.Viewport和窗口Ext.Window用法
    禁用IE缓存
  • 原文地址:https://www.cnblogs.com/hustluotao/p/14697938.html
Copyright © 2020-2023  润新知