json-c初探(三) - 创建json对象

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\n",
	   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\n", 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);
}
posted @ 2021-04-24 20:16  hustluotao  阅读(832)  评论(0编辑  收藏  举报