【ソース分析】cJSONライブラリ学習

3657 ワード


cJSONライブラリは何ですか?
cJSONは軽量級のjson解析ライブラリです.使用は非常に簡単で、ライブラリ全体が非常に簡潔で、コア機能の実現はcJSONにある.cファイルは、ソースコードを読んでC言語を学ぶのに非常に適しています.最近このライブラリのソースコードを読み終わって、自分の収穫のいくつかの心得を分かち合います.
jsonとは何か、jsonの公式サイトの言い方をそのままにします.
JSON(JavaScript Object Notation)は、軽量レベルのデータ交換フォーマットです.読みやすく、書きやすい.同時に機械の解析と生成も容易である.JavaScript Programming Language,Standard ECMA-2623 rd Edition-December 1999のサブセットに基づいています.JSONは完全に言語から独立したテキスト形式を採用しているが、C言語ファミリーに似た習慣(C,C++,C#,Java,JavaScript,Perl,Pythonなどを含む)も使用している.これらの特性はJSONを理想的なデータ交換言語にした.
cJSONライブラリの中に何がありますか?
cjsonライブラリgithubアドレス:https://github.com/DaveGamble/cJSONライブラリ全体にcJSONが含まれています.hとcJSON.c 2つのファイル、ヘッダファイルは一連のAPIを定義している.このライブラリの最も基本的で最も重要な機能はjson文字列を解析することであり、使用するAPIはcJSON_である.Parse.cJSON_Parse関数がcJSON_を呼び出しました特定の論理を実現するParseWithOpts関数.
2つの関数のプロトタイプは次のとおりです.
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);

関数は文字列を受信し、解析して返します.解析が完了すると、cjson構造が返されます.cJSON構造の定義は次のとおりです.
typedef struct cJSON
{    struct cJSON *next; //     
    struct cJSON *prev; //     

    struct cJSON *child; //      ,          

    int type; //      

    char *valuestring; //        ,  type == cJSON_String    type == cJSO_Raw

    int valueint; //    ,    cJSON_SetNumberValue     

    double valuedouble; //       ,  type == cJSON_Number

    char *string; //         ,         } cJSON;

json文字列をどのように解析しますか?
jsonの公式サイトはここです.http://www.json.orgサイトのトップページには、jsonが何であるか、フォーマット仕様が記載されており、仕様があれば、jsonがどのように構成されているかを知ることができるため、jsonデータをどのように解析するかの方向がある.
jsonは、オブジェクトまたは配列の2つの構造を使用して構築されます.
オブジェクトは{を先頭とし、}を末尾とし、中の各要素はキー値ペアの無秩序な集合であり、キー名と値は:で区切られ、,で各要素を区切る.配列は[先頭を作成,]を末尾に使用し,中の要素はすべて秩序ある値からなる集合であり,,を区切り記号として使用する.
各値は文字列、整数、true、false、nullなどの定数であってもよく、json構造がネスト可能であるため、オブジェクトまたは配列であってもよい.
そのため、私たちは以下のことを知ることができます.
1、jsonの頭文字からjson全体のタイプを判断することができ、jsonが'{'で始まると対象であり、'['で始まると配列であり、そうでないと文字列またはその他の定数である.
2、対象であれば、必ずキー名があり、まずそのキー名を解析し、それからその値を解析し、値を解析する過程は第一歩と同じで、再帰的に解析する
3、配列であれば、配列内の要素を1つずつ解析し、]に遭遇するまで、配列内の要素を解析する過程も第1ステップと一致し、再帰的に解析する.
これがjson公式サイトの定義に基づいてjson文字列を解析する考え方であり,次にcJSONライブラリがどのように実現されているかを見る.cJSON_Parseの実装フローチャートは以下の通りである.
cJSON_ParseWithOpts関数でparse_が呼び出されましたvalueは、関数全体のコア実装です.parse_value関数のフローチャートは次のとおりです.
見えますparsevalueは,json値の先頭を判断し,対応する分岐に入って解析し,次に各分岐を解析する.解析した値はcJSONの構造体に保存され,以下itemと命名する.
定数
json値が'null','true','false'の場合、itemのtypeはそれぞれcJSON_に設定されます.NULL、cJSON_TRUE、cJSON_FALSE.その後、残りのjson値の解析を続行します.
string
「先頭にjson値が文字列であることを示す場合、その値を解析します.この場合、2つの値を取得するだけです.」保存文字列も構造体で、メモリを申請する必要があり、長さを計算する過程で、エスケープ文字に遭遇した場合、エスケープ文字が保存されないため記録する必要があります.
number
数字の先頭に遭遇した場合、その後ろの数字文字を記録し、整数数字に変換し、値の範囲をチェックします.
array
配列を解析するときに、配列の要素に新しいjson構造体new_を作成します.itemは、配列内の値を解析し続け、次の要素の位置を','で判断し、得られた値を構造体に保存し、複数の要素をチェーンテーブルで接続します.']'記号に出会うまで解析します.
object
解析オブジェクトのプロシージャは配列と同様に、オブジェクトの要素に新しいjson構造体new_を作成します.item、それからオブジェクトの中の値を解析し続け、オブジェクトはキー値ペアで構成されているので、まずキーの値を得て、それから':'で値の位置を判断して、さらに解析し続けて値を得て、複数のキー値ペアの間を','で区切って、最後にチェーンテーブルで接続します.'}'記号に出会うまで解析します.
その他
すべての値を解析する前にskip_が呼び出されます.whitespace関数は、文字列の両方の空白文字をすべてフィルタします.ここでは、ASCIIコードが32以下の文字、例えば:t、.関数は次のとおりです.
static const unsigned char *skip_whitespace(const unsigned char *in)
{    while (in && *in && (*in <= 32))
    {        in++;
    }    return in;
}