データ構造
yyjsonには、不変と可変の2種類のデータ構造があります。
| 不変 | 可変 | |
|---|---|---|
| ドキュメント | yyjson_doc | yyjson_mut_doc |
| 値 | yyjson_val | yyjson_mut_val |
- 不変のデータ構造は、JSONドキュメントを読み込むと返されます。変更はできません。
- 可変のデータ構造は、JSONドキュメントを構築するときに作られます。変更できます。
- yyjsonは、これらの2種類のデータ構造を相互に変換する関数も提供しています。
この文書で説明するデータ構造は非公開扱いであることに注意してください。アクセスには公開APIを使うことを推奨します。
不変の値
各JSON値は、不変のyyjson_val構造体に格納されます。
struct yyjson_val {
uint64_t tag;
union {
uint64_t u64;
int64_t i64;
double f64;
const char *str;
void *ptr;
size_t ofs;
} uni;
}値の型は、tagの下位8ビットに格納します。
文字列長、オブジェクトサイズ、配列サイズなど、値のサイズは、tagの上位56ビットに格納します。
現代の64ビットプロセッサーでは、RAMアドレスに使えるビット数が通常64ビット未満に制限されています(Wikipedia)。たとえば、Intel64、AMD64、ARMv8の物理アドレスは52ビット(4PB)が上限です。そのため、64ビットのtag内に型とサイズの情報を格納しても安全です。
不変のドキュメント
JSONドキュメントは、すべての文字列を連続したメモリ領域に格納します。
各文字列は、その場所でエスケープが解除され、NUL終端文字で終わります。
例:
JSONドキュメントは、すべての値を、別の連続したメモリ領域に格納します。
objectとarrayのコンテナーは、自身のメモリ使用量を格納するため、子の値を容易に走査できます。
例:
可変の値
各可変JSON値は、yyjson_mut_val構造体に格納されます。
struct yyjson_mut_val {
uint64_t tag;
union {
uint64_t u64;
int64_t i64;
double f64;
const char *str;
void *ptr;
size_t ofs;
} uni;
yyjson_mut_val *next;
}tagとuniフィールドは、不変の値と同じです。nextフィールドは、連結リストの構築に使います。
可変のドキュメント
可変JSONドキュメントは、複数のyyjson_mut_valで構成されます。
objectまたはarrayの子の値は、循環するように連結されています。
親は循環連結リストの末尾を保持するため、yyjsonはappend、prepend、remove_firstを定数時間で実行できます。
例:
メモリ管理
JSONドキュメント(yyjson_doc、yyjson_mut_doc)は、すべてのJSON値と文字列のメモリを管理します。ドキュメントが不要になったら、利用者はyyjson_doc_free()またはyyjson_mut_doc_free()を呼び出して、関連するメモリを解放することが重要です。
JSON値(yyjson_val、yyjson_mut_val)の寿命は、そのドキュメントと同じです。メモリはドキュメントが管理し、個別に解放することはできません。
詳細はAPI文書を参照してください。