概要
sj.h は、C99で書かれた約150行の 超小型JSONパーサー。 ゼロアロケーション 設計で、状態管理も最小限。 エラー時は 行:列 情報付きのメッセージを出力。 数値や文字列のパースは ライブラリ外部で処理 する方針。 パブリックドメイン として公開され、商用利用も自由。
sj.h 超小型JSONパーサーの特徴
- C99準拠 かつ約150行のシンプル実装
- 動的メモリアロケーション非依存 設計
- 最小限の内部状態管理 による高速動作
- エラー発生時は行番号・列番号を含むメッセージ を返却
- 数値パース機能非搭載
- 利用者が strtod や atoi などで独自処理
- 文字列パース機能非搭載
- Unicodeサロゲートペア などのハンドリングは利用者側で実装
- パブリックドメインライセンス
- 商用・非商用問わず自由に利用可能
基本的な使い方
- JSON文字列から構造体への変換例
- JSON例:
{ "x": 10, "y": 20, "w": 30, "h": 40 } - 変換先構造体:
Rect(int型のx, y, w, hフィールドを持つ)
- JSON例:
char *json_text = "{ \"x\": 10, \"y\": 20, \"w\": 30, \"h\": 40 }";
typedef struct { int x, y, w, h; } Rect;
bool eq(sj_Value val, char *s) {
size_t len = val.end - val.start;
return strlen(s) == len && !memcmp(s, val.start, len);
}
int main(void) {
Rect rect = {0};
sj_Reader r = sj_reader(json_text, strlen(json_text));
sj_Value obj = sj_read(&r);
sj_Value key, val;
while (sj_iter_object(&r, obj, &key, &val)) {
if (eq(key, "x")) { rect.x = atoi(val.start); }
if (eq(key, "y")) { rect.y = atoi(val.start); }
if (eq(key, "w")) { rect.w = atoi(val.start); }
if (eq(key, "h")) { rect.h = atoi(val.start); }
}
printf("rect: { %d, %d, %d, %d }\n", rect.x, rect.y, rect.w, rect.h);
return 0;
}
- オブジェクトイテレーション
- sj_iter_object でkey-valueペアを繰り返し取得
- 値の比較
- eq関数 でJSONのキー名と比較
- 値の変換
- atoi など標準関数で数値へ変換
注意点・制約
- 数値パースは外部関数任せ
- 浮動小数点や整数のフォーマットエラーは 自己責任
- 文字列エスケープやUnicode処理は未対応
- 必要に応じて 独自実装 が必要
- JSON仕様の一部(例:特殊なUnicodeやエスケープ文字)には非対応
- エラーメッセージ は 行:列 情報付きで分かりやすい
- スレッドセーフ設計ではない ため、必要に応じて保護処理を実装
ライセンス・利用条件
- パブリックドメイン
- 商用・非商用問わず制限なし
- クレジット表記不要
- 詳細はLICENSEファイル 参照
関連資料
- demoフォルダ に追加サンプルコード
- 公式リポジトリ で最新情報・アップデートを確認
sj.h は、 組み込み用途 や 最小限のJSONパースが必要なCプロジェクト に最適な選択肢。 自己責任での拡張 や カスタマイズ が前提のため、柔軟な運用が可能。