• 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);
    }
    
  • 相关阅读:
    POJ 3253 Fence Repair
    POJ 2431 Expedition
    NYOJ 269 VF
    NYOJ 456 邮票分你一半
    划分数问题 DP
    HDU 1253 胜利大逃亡
    NYOJ 294 Bot Trust
    NYOJ 36 最长公共子序列
    HDU 1555 How many days?
    01背包 (大数据)
  • 原文地址:https://www.cnblogs.com/hustluotao/p/14697938.html
Copyright © 2020-2023  润新知