JSON學習手記

jansson: http://www.digip.org/jansson/doc/2.2/apiref.html

#include "jansson.h"

json_t  這個數據結構用於描述庫中所有的JSON類型的值。它通常包含它列舉的JSON值(JSON value)的類型(type)和引用計數(reference count),依賴關係取決於值(value)的類型。

json_t對象通常是以指針的方式來使用。

除非有其它特殊聲明,API函數在錯誤的時候都是返回一個錯誤值。參照函數的符號特徵,出錯的返回值通常是NULL或 -1。無效的參數或無效的輸入通常是導致出錯的原因。申請內存(memory allocation)和I/O操作也可能導致出錯。

類型(type)

json_type枚舉類型用於JSON值類型的斷定:

typedef enum {
    JSON_OBJECT,
    JSON_ARRAY,
    JSON_STRING,
    JSON_INTEGER,
    JSON_REAL,         /*實型*/
    JSON_TRUE,
    JSON_FALSE,
    JSON_NULL
} json_type;

這些與JSON對象、數組、字符串、數字、布爾值和NULL值相符。一個數字(number)可以被描述成是一個JSON_INTEGER類型或者是JSON_REAL類型。值爲真的布爾型可以被描述爲JSON_TRUE,值爲假的布爾型就是JSON_FALSE。

typedef struct {
    json_type type;
    size_t refcount;
} json_t;

下面是一些用於斷定的API:

int json_typeof(const json_t *json)  

 /*返回一個被轉換成 int 的 JSON值的類型,json必需不爲NULL,這個函數實際上是作爲一個迅速轉換的宏來使用*/

json_is_object(const json_t *json)json_is_array(const json_t *json)json_is_string(const json_t *json)json_is_integer(const json_t *json)json_is_real(const json_t *json)json_is_true(const json_t *json)json_is_false(const json_t *json)

json_is_null(const json_t *json

/*這些函數(實際上是宏) 返回一個trun(非0值,已在json_type中給定,轉換得來)或false(zero) for values of other types and for NULL*/

json_is_number(const json_t *json)
/*Returns true for values of types JSON_INTEGER and JSON_REAL, and false for other types and for NULL.*/
json_is_boolean(const json_t *json)

/*Returns true for types JSON_TRUE and JSON_FALSE, and false for values of other types and for NULL.*/

在源碼中的定義是:

#define json_typeof(json)      ((json)->type)
#define json_is_object(json)   (json && json_typeof(json) == JSON_OBJECT)
#define json_is_array(json)    (json && json_typeof(json) == JSON_ARRAY)
#define json_is_string(json)   (json && json_typeof(json) == JSON_STRING)
#define json_is_integer(json)  (json && json_typeof(json) == JSON_INTEGER)
#define json_is_real(json)     (json && json_typeof(json) == JSON_REAL)
#define json_is_number(json)   (json_is_integer(json) || json_is_real(json))
#define json_is_true(json)     (json && json_typeof(json) == JSON_TRUE)
#define json_is_false(json)    (json && json_typeof(json) == JSON_FALSE)
#define json_is_boolean(json)  (json_is_true(json) || json_is_false(json))
#define json_is_null(json)     (json && json_typeof(json) == JSON_NULL)

引用計數(reference count) 

引用計數是用於追蹤一個值是否正在使用。當一個值被創建後,它的引用計數值就被設爲1。如果引用了一個值(例如在最後使用時在某處保存了一個值),它的引用計數值就會增加,而當這個值不再需要的時候,引用計數值就會遞減。當引用計數值減小到0的時候,它就不能再被引用了,它的值也會被銷燬。

下面的函數用於操作引用計數值(reference count):

json_t *json_incref(json_t *json/ *爲json增加一個引用計數值(non-NULL),然後返回json*/

static JSON_INLINE json_t *json_incref(json_t *json)
{    if(json && json->refcount != (size_t)-1)
        ++json->refcount;
    return json;
}

void json_decref(json_t *json)   /* 爲json遞減一個引用計數值,調用json_decref()時引用計數值一但減少到0,值(value)就會被銷燬不能再使用*/

static JSON_INLINE
void json_decref(json_t *json)
{
    if(json && json->refcount != (size_t)-1 && --json->refcount == 0)
        json_delete(json);
}


函數在創建新的JSON value時會把引用計數值設爲1.These functions are said to return a new reference. Other functions returning (existing) JSON values do not normally increase the reference count. These functions are said to return a borrowed reference. So, if the user will hold a reference to a value returned as a borrowed reference, he must call json_incref(). As soon as the value is no longer needed,json_decref() should be called to release the reference.

  正常來說,所有函數在接收一個作爲參數的JSON value時,都會對引用計數值進行管理。i.e. increase and decrease the reference count as needed. However, some functions steal the reference, i.e. they have the same result as if the user called json_decref() on the argument right after calling the function. These functions are suffixed with _new or have _new_ somewhere in their name.

下面代碼是創建一個新的JSON數組和它添加一個整數:

json_t *array, *integer;

array = json_array();
integer = json_integer(42);

json_array_append(array, integer);
json_decref(integer);

注意上面使用了 json_decref() 去釋放了一個引用計數,但如果用一個引用偷取函數(a reference stealing function) json_array_append_new() 來代替 json_array_append(),那就變得簡單多了,如下:

json_t *array = json_array();
json_array_append_new(array, json_integer(42));
In this case, the user doesn’t have to explicitly release the reference to the integer value, as json_array_append_new() steals the reference when appending the value to the array.
In the following sections it is clearly documented whether a function will return a new or borrowed reference or steal a reference to its argument.

循環引用Circular References

在一個對象(object)或數組(array)被創建後會直接地或間接地創建一個循環引用circular references,嵌入它自身當中,直接的例子:


json_t *obj = json_object();
json_object_set(obj, "foo", obj);

Jansson會拒絕這樣做,json_object_set()會返回一個錯誤狀態(所有其它對object & arrays操作的函數也是如此)。

間接的也是很危險的,如下:

json_t *arr1 = json_array(), *arr2 = json_array();
json_array_append(arr1, arr2);
json_array_append(arr2, arr1);


在上面的例子中,arr2數組中包含了arr1數組,反過來也是一樣,在當前性能的限制下,jansson不能檢查像這種間接循環引用(Jansson cannot check for this kind of indirect circular references without a performance hit),所以這是由使用者去避免發生這種情況
如果發生了一個循環引用,內存將會被這些值耗光而且不能被json_decref()釋放。而引用計數(reference count)從不會掉到0的,因爲計數值一直被每個引用佔有着。此外,trying to encode the values with any of the encoding functions will fail. The encoder detects circular references and returns an error status.
真,假和空(True,False and Null)

這些值是單獨使用,所以函數每次都返回相同的值
json_t *json_true(void)
  Return value: New reference.
  Returns the JSON true value.
json_t *json_false(void)
  Return value: New reference.
  Returns the JSON false value.
json_t *json_null(void)
  Return value: New reference.
  Returns the JSON null value.
源代碼爲:<jansson-2.2.1/src/value.c>
/*** simple values ***/
json_t *json_true(void)
{
    static json_t the_true = {JSON_TRUE, (size_t)-1};
    return &the_true;
}

json_t *json_false(void)
{
    static json_t the_false = {JSON_FALSE, (size_t)-1};
    return &the_false;
}

json_t *json_null(void)
{
    static json_t the_null = {JSON_NULL, (size_t)-1};
    return &the_null;
}

字符串String Jansson使用UTF-8來作爲字符編碼,All JSON strings must be valid UTF-8 (or ASCII, as it’s a subset of UTF-8).正常的空字符C字符串也可以使用, 所以JSON字符串不包含嵌入的空字符. All other Unicode codepoints U+0001 through U+10FFFF are allowed.
源代碼:<jansson-2.2.1/src/value.c>
json_t *json_string(const char *value)
Return value: New reference.
用value構造一個json_string;
返回一個新的JSON字符串,在出錯時返回空,jaon value必需是一個有效的UTF-8編碼的Unicode字符串。
json_t *json_string_nocheck(const char *value)
Return value: New reference.

Like json_string(), but doesn’t check that value is valid UTF-8. Use this function only if you are certain that this really is the case (e.g. 你已經用各種方法檢查過了).

const char *json_string_value(const json_t *string)

返回jaon_t *string 的字符串值

Returns the associated value of string as a null terminated UTF-8 encoded string, or NULL if string is not a JSON string.返回一個UTF-8編碼空字符結尾的字符串相關值,如果字符串不是一個JSON字符串則返回空。

返回值是隻讀的,不能被用戶修改和釋放。它(json)在字符串存在期間一直有效(也是在它的引用計數值被減到0之前一直有效)。

int json_string_set(const json_t *string, const char *value)

設置一個相關的字符串值到value(json)裏,值必需是一個有效的UTF-8編碼的Unicoded字符串。成功時返回0,出錯時返回-1。

int json_string_set_nocheck(const json_t *string, const char *value)< style="margin-top: 3px; margin-bottom: 10px; margin-left: 30px; line-height: 20px; text-align: justify; ">

Like json_string_set(), 但不檢查值是否是一個有效的UTF-8. Use this function only if you are certain that this really is the case (e.g. you have already checked it by other means).

/*** string ***/

json_t *json_string_nocheck(const char *value)
{
    json_string_t *string;

    if(!value)
        return NULL;

    string = jsonp_malloc(sizeof(json_string_t));
    if(!string)
        return NULL;
    json_init(&string->json, JSON_STRING);

    string->value = jsonp_strdup(value);
    if(!string->value) {
        jsonp_free(string);
        return NULL;
    }

    return &string->json;
}

json_t *json_string(const char *value)
{
    if(!value || !utf8_check_string(value, -1))
        return NULL;

    return json_string_nocheck(value);
}

const char *json_string_value(const json_t *json)
{
    if(!json_is_string(json))
        return NULL;

    return json_to_string(json)->value;
}

int json_string_set_nocheck(json_t *json, const char *value)
{
    char *dup;
    json_string_t *string;

    if(!json_is_string(json) || !value)
        return -1;

    dup = jsonp_strdup(value);
    if(!dup)
        return -1;

    string = json_to_string(json);
    jsonp_free(string->value);
    string->value = dup;

    return 0;
}

int json_string_set(json_t *json, const char *value)
{
    if(!value || !utf8_check_string(value, -1))
        return -1;

    return json_string_set_nocheck(json, value);
}

static void json_delete_string(json_string_t *string)
{
    jsonp_free(string->value);
    jsonp_free(string);
}

static int json_string_equal(json_t *string1, json_t *string2)
{
    return strcmp(json_string_value(string1), json_string_value(string2)) == 0;
}

static json_t *json_string_copy(json_t *string)
{
    return json_string_nocheck(json_string_value(string));
}

數值Number
JSON規格只能容納一種數字類型:"number"。C語言區別整型(integer)與浮點型(floating-point)爲不同類型,所以因爲這個現在條件,jansson也爲它們區分不同類型,它們被分別叫"integer"和"real"。json_int_t這是一個常用於存儲整數值的C類型, It represents the widest integer type available on your system.實際上它只是一個long long 型的typedef 定義,當然,需要你的編譯器支持long long型,否則它是long型。#typedef long long json_int_t; /* 源代碼 jansson-2.2.1/src/jansson.h */通常可以在使用json_int_t的地方使用純粹的 int,and the implicit C integer conversion handles the rest.只有當你知道需要去使用全64位範圍的值時,你可以明確地使用json_int_t。JSON_INTEGER_IS_LONG_LONG:這是一個預處理器變量,當json_int_t是long long型時,它是1;當json_int_t是long型時,它是0;( jansson-2.2.1/src/jansson_config.h )
JSON_INTEGER_FORMAT:
這是一個用於printf()擴展的宏,它可以使printf()在打印json_int_t類型的數據時可以適應不同的數據長度。JSON_INTEGER_FORMAT "lld"
typedef long long json_int_t;
#else
#define JSON_INTEGER_FORMAT "ld"
typedef long json_int_t;
#endif /* JSON_INTEGER_IS_LONG_LONG */下是操作API: 源代碼:<jansson-2.2.1/src/value.c>
json_t *json_integer(json_int_t value)
Return value: New reference.

返回一個新的JSON整數,在出錯時返回NULL.

json_int_t json_integer_value(const json_t *integer)

返回一個整型的關係值,在不是一個整型值的時候返回0。

int json_integer_set(const json_t *integerjson_int_t value)

Sets the associated value of integer to value. Returns 0 on success and -1 if integer is not a JSON integer, 把value設置到integer的value中,成功時返回0,如果不是JSON integer型時返回 -1(用上面的宏進行判斷).

json_t *json_real(double value)
Return value: New reference.

Returns a new JSON real, or NULL on error.

double json_real_value(const json_t *real)

Returns the associated value of real, or 0.0 if real is not a JSON real.

int json_real_set(const json_t *real, double value)

Sets the associated value of real to value. Returns 0 on success and -1 if real is not a JSON real.

In addition to the functions above, there’s a common query function for integers and reals:

double json_number_value(const json_t *json)

Returns the associated value of the JSON integer or JSON real json, cast to double regardless of the actual type. If json is neither JSON real nor JSON integer, 0.0 is returned.

數組Array
JSON數組是JSON values的有序集合; 源碼在:<value.c>
json_t *json_array(void)
Return value: New reference.

Returns a new JSON array, or NULL on error. Initially, the array is empty.

size_t json_array_size(const json_t *array)

Returns the number of elements in array, or 0 if array is NULL or not a JSON array.

json_t *json_array_get(const json_t *array, size_t index)
Return value: Borrowed reference.

Returns the element in array at position index. The valid range for index is from 0 to the return value of json_array_size() minus 1. If array is not a JSON array, if array is NULL, or if index is out of range, NULL is returned.

int json_array_set(json_t *array, size_t indexjson_t *value)

Replaces the element in array at position index with value. The valid range for index is from 0 to the return value of json_array_size() minus 1. Returns 0 on success and -1 on error.

int json_array_set_new(json_t *array, size_t indexjson_t *value)

Like json_array_set() but steals the reference to value. This is useful when value is newly created and not used after the call.

int json_array_append(json_t *arrayjson_t *value)

Appends value to the end of array, growing the size of array by 1. Returns 0 on success and -1 on error.

int json_array_append_new(json_t *arrayjson_t *value)

Like json_array_append() but steals the reference to value. This is useful when value is newly created and not used after the call.

int json_array_insert(json_t *array, size_t indexjson_t *value)

Inserts value to array at position index, shifting the elements at index and after it one position towards the end of the array. Returns 0 on success and -1 on error.

int json_array_insert_new(json_t *array, size_t indexjson_t *value)

Like json_array_insert() but steals the reference to value. This is useful when value is newly created and not used after the call.

int json_array_remove(json_t *array, size_t index)

Removes the element in array at position index, shifting the elements after index one position towards the start of the array. Returns 0 on success and -1 on error. The reference count of the removed value is decremented.

int json_array_clear(json_t *array)

Removes all elements from array. Returns 0 on sucess and -1 on error. The reference count of all removed values are decremented.

int json_array_extend(json_t *arrayjson_t *other_array)

Appends all elements in other_array to the end of array. Returns 0 on success and -1 on error.




























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章