JunkBox_Lib  1.10.2
tjson.c File Reference

Tiny JSON ライブラリ More...

#include "tjson.h"
#include "jbxl_state.h"
Include dependency graph for tjson.c:

Go to the source code of this file.

Functions

tJsonjson_parse (const char *str, int num)
 文字列のJSONデータを解釈して,tJsonのツリーを生成する.ANCHOR付き. More...
 
tJsonjson_parse_prop (tJson *json, const char *str, int num)
 JSON Main Parser.json が NULL の場合は ANCHOR付き. More...
 
tJson_json_array_parse (tJson *json, int num)
 json_parse_prop() の補助関数.配列処理用. More...
 
tJsonjson_array_parse (tJson *json, const char *str, int num)
 JSONデータの 配列ノードの値(配列データ)を処理する. More...
 
tJson_json_parse_term (tJson *json, const char *st, const char *ed, const char *com)
 json_parse_prop() の補助関数.断片的な入力データ用. More...
 
tJsonjson_parse_seq (tJson *json, const char *str, int num)
 断片化した JSONデータを読み込んで処理する. More...
 
Buffer json_inverse_parse (tJson *pp, int mode)
 tJsonデータをmodeに従って元の書式に戻して Bufferに格納する. More...
 
Buffer json_inverse_parse_opt (tJson *pp, const char *crlf, const char *space)
 tJsonデータを指定に従って元の書式に戻して Bufferに格納する. More...
 
void _json_to_Buffer (tJson *pp, Buffer *buf, const char *crlf, const char *space)
 tJsonデータを元の書式に戻して Bufferに格納する.補助関数. More...
 
void print_json (FILE *fp, tJson *json, int mode)
 tJsonデータをmodeに従って fp に出力する. More...
 
void print_json_opt (FILE *fp, tJson *json, const char *crlf, const char *space)
 tJsonデータを指定に従って fp に出力する. More...
 
tJsonjson_parse_file (const char *fn, int num)
 JSONデータをファイルから読み込んで,パースする. More...
 
void json_set_str_val (tJson *json, const char *val)
 json ノード "key":val に文字列の属性値(value)を設定する. More...
 
void json_set_int_val (tJson *json, int val)
 json ノード "key":val に整数の属性値(value)を設定する. More...
 
void json_set_real_val (tJson *json, float val)
 json ノード "key":val に実数の属性値(value)を設定する. More...
 
void json_copy_val (tJson *f_json, tJson *t_json)
 f_json から t_json へ属性値(value)をコピーする. More...
 
void json_copy_data (tJson *f_json, tJson *t_json)
 f_json から t_json へ属性名(key)と属性値(value)をコピーする. More...
 
tJsonjson_insert_child (tJson *parent, tJson *child)
 parent に dict または array の child を繋げる. More...
 
tJsonjson_insert_parse (tJson *json, const char *str)
 str をパースして繋げる.str は { または [ で始まる必要がある. More...
 
tJsonjson_append_obj_key (tJson *json, const char *key)
 属性値(value)なしのリストデータ "key":{} を追加する. More...
 
tJsonjson_append_array_key (tJson *json, const char *key)
 値(value)なしの配列 "key":[] を追加する. More...
 
void json_append_obj_str_val (tJson *json, const char *key, const char *val)
 {} の要素として "key":val(val は文字列)を追加する. More...
 
void json_append_obj_int_val (tJson *json, const char *key, int val)
 {} の要素として "key":val(val は整数)を追加する. More...
 
void json_append_obj_real_val (tJson *json, const char *key, float val)
 {} の要素として "key":val(va lは実数)を追加する. More...
 
void json_append_array_str_val (tJson *json, const char *val)
 配列 [] の要素として 文字列 val を追加する. More...
 
void json_append_array_int_val (tJson *json, int val)
 配列 [] の要素として 整数 val を追加する. More...
 
void json_append_array_real_val (tJson *json, float val)
 配列 [] の要素として 実数 val を追加する. More...
 
tJsonjoin_json (tJson *parent, tJson **child)
 parent の子として child そのものを 直接繋げる. More...
 
tJsonsearch_top_bracket_json (tJson *pp, int nn)
 ツリーが複数のルート(TOP)を持つ場合(JBXL_JSON_MULTI_ROOT),指定されたTOPへのポインタを返す. More...
 
tJsonsearch_key_json (tJson *pp, const char *key, int needval, int nn)
 名前(属性名)が key である nn番目のノードへのポインタを返す More...
 
tJsonsearch_sister_json (tJson *pp, int nn)
 nn個先の sister ノードを返す.正数の場合は younger sister. 負数の場合は elder sister. More...
 
tJsonsearch_key_child_json (tJson *pp, const char *key, int needval)
 子の姉妹ノードで名前(属性名)が key である nn番目のノードへのポインタを返す.
More...
 
tJsonsearch_key_sister_json (tJson *pp, const char *key, int needval)
 姉妹ノードで名前(属性名)が key である nn番目のノードへのポインタを返す.
More...
 
tJsonsearch_key_json_obj (tJson *pp, const char *key, int nn)
 名前(属性名)が key である nn番目のオブジェクトノード(JSON_VALUE_OBJ)へのポインタを返す.ex.) "key":{} More...
 
tJsonsearch_double_key_json (tJson *pp, const char *key1, const char *key2, int needval)
 属性名が key1 -> key2 の親子関係を持つ,key2ノードのポインタを返す. More...
 
tJson_search_key_json (tJson *pp, const char *key, int needval, int *nn)
 search_key_json() の補助関数 More...
 
tJson_search_key_json_obj (tJson *pp, const char *key, int *nn)
 search_key_json_obj() の補助関数 More...
 
int _json_check_node_bykey (tJson *pp, const char *key, int needval, int nn)
 search 系関数の補助関数 More...
 
tListsearch_all_node_strval_json (tJson *pp, const char *name, const char *val)
 指定した条件に合う全てのノードへのポインタを,リストに格納して返す. More...
 
tList_search_all_node_strval_json (tList *list, tJson *pp, const char *name, const char *val)
 search_all_node_strval_json() の補助関数
More...
 
Buffer get_json_val (tJson *json)
 
Buffer get_key_json_val (tJson *pp, const char *key, int nn)
 名前(属性名)が key である nn番目のノードの属性値を返す. More...
 
Buffer get_key_sister_json_val (tJson *pp, const char *key)
 姉妹ノードで名前(属性名)が key である nn番目のノードの属性値を返す. More...
 
Buffer get_double_key_json_val (tJson *pp, const char *key1, const char *key2)
 key1 -> key2 の親子関係を持つ,key2ノードの属性値を返す. More...
 
Buffer get_Buffer_from_json (tJson *json)
 
char * get_string_from_json (tJson *json)
 要 free() More...
 

Detailed Description

Version
1.2.1
Author
Fumi.Iseki (C)
Date
2021 8/19
タイトル
サブセット版 JSON 簡易 Parser
Attention
全てのパターンのパース可能性は保障しない.
See also
tJson

Definition in file tjson.c.

Function Documentation

◆ _json_array_parse()

tJson* _json_array_parse ( tJson json,
int  num 
)

tJson* _json_array_parse(tJson* json, int num)

JSONデータの 配列ノードの値(配列データ)を処理する.

Parameters
json配列処理を行う JSON ノードデータ.
num配列処理の残り段数.
Returns
処理された JSON ノードデータ.

Definition at line 375 of file tjson.c.

376 {
377  char* pp = (char*)(json->ldat.val.buf);
378  //
379  json = json_array_parse(json, pp, num);
380  free_Buffer(&(json->ldat.val));
381 
382  return json;
383 }
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
tJson * json_array_parse(tJson *json, const char *str, int num)
JSONデータの 配列ノードの値(配列データ)を処理する.
Definition: tjson.c:401

References free_Buffer(), and json_array_parse().

Referenced by json_array_parse(), and json_parse_prop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _json_check_node_bykey()

int _json_check_node_bykey ( tJson pp,
const char *  key,
int  needval,
int  nn 
)

int _json_check_node_bykey(tJson* pp, const char* key, int needval, int nn)

pp が指すノードの名前(属性名)が key である場合,nnを 1減算して返す. needval が TRUE の場合は,値(属性値)を持っている場合のみ減算する.

Definition at line 1632 of file tjson.c.

1633 {
1634  if (pp->ldat.key.buf!=NULL) {
1635  if (!strcmp(key, (char*)pp->ldat.key.buf)) {
1636  if (needval) {
1637  unsigned char* pm = pp->ldat.val.buf;
1638  if (pm!=NULL) {
1639  if (!((pm[0]=='\'' && pm[1]=='\'') || (pm[0]=='"' && pm[1]=='"')) && pm[0]!='\0') nn--;
1640  }
1641  }
1642  else {
1643  nn--;
1644  }
1645  }
1646  }
1647  return nn;
1648 }

Referenced by _search_key_json(), _search_key_json_obj(), search_key_json(), search_key_json_obj(), and search_key_sister_json().

Here is the caller graph for this function:

◆ _json_parse_term()

tJson* _json_parse_term ( tJson json,
const char *  st,
const char *  ed,
const char *  com 
)

tJson* _json_parse_term(tJson* json, const char* st, const char* ed, const char* com)

入力データが途中で終了した場合の処理

Definition at line 551 of file tjson.c.

552 {
553  if (json==NULL) return NULL;
554 
555  json->state = JBXL_JSON_PARSE_TERM;
556  if (com!=NULL) {
557  json->ldat.val = set_Buffer((void*)com, -1);
558  if (st!=NULL && ed!=NULL) {
559  int len = (int)(ed - st) + 1;
560  cat_b2Buffer((char*)st, &(json->ldat.val), len);
561  json->ldat.val.vldsz = (int)strlen((char*)json->ldat.val.buf);
562  }
563  }
564  return json;
565 }
Buffer set_Buffer(void *dat, int len)
Buffer型変数のバッファ部を新しく作り, そのバッファに bufをコピーする.
Definition: buffer.c:170
int cat_b2Buffer(void *src, Buffer *dst, int len)
任意のバイナリデータsrcを Buffer型変数dstへ lenバイト catする.
Definition: buffer.c:585
#define JBXL_JSON_PARSE_TERM
JSON のパースが途中で終了した.入力データが不完全.
Definition: jbxl_state.h:112
unsigned char unsigned long * len
Definition: jpeg_tool.h:96

References cat_b2Buffer(), JBXL_JSON_PARSE_TERM, len, and set_Buffer().

Referenced by json_parse_prop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _json_to_Buffer()

void _json_to_Buffer ( tJson pp,
Buffer buf,
const char *  crlf,
const char *  space 
)

void _json_to_Buffer(tJson* pp, Buffer* buf, const char* crlf, const char* space)

json_inverse_parse()用の補助関数. ppに格納された JSONデータを元の書式に戻して Bufferに格納する.

Parameters
ppJSONデータが格納されたツリーへのポインタ
buf変換したJSONデータを格納する Buffer変数.データ格納領域は予め確保しておく.
crlfJSONへ戻す時の改行コード
spaceインデントを付ける場合の空白やTAB

Definition at line 688 of file tjson.c.

689 {
690  if (pp==NULL) return;
691  if (buf==NULL || buf->buf==NULL) return;
692  //
693  if (pp->ldat.id==JSON_ANCHOR_NODE) pp = pp->next;
694 
695  if (pp!=NULL) {
696  if (pp->ctrl!=TREE_NOSIS_NODE) while(pp->esis!=NULL) pp = pp->esis; // 長女から逆パースを開始.
697  do {
698  int i;
699  if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
700  //
701  if (pp->ldat.id==JSON_BRACKET_NODE) {
702  //PRINT_MESG("JSON_BRACKET_NODE\n");
703  cat_s2Buffer("{", buf);
704  if (pp->next!=NULL) {
705  if (crlf[0]!='\0') cat_s2Buffer(crlf, buf);
706  _json_to_Buffer(pp->next, buf, crlf, space);
707  if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
708  }
709  //if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
710  cat_s2Buffer("}", buf);
711  }
712  //
713  else if (pp->ldat.id==JSON_DATA_NODE) {
714  //PRINT_MESG("JSON_DATA_NODE\n");
715  cat_s2Buffer("\"", buf);
716  cat_s2Buffer(pp->ldat.key.buf, buf);
717  cat_s2Buffer("\"", buf);
718  //
719  if (pp->ldat.lv==JSON_VALUE_OBJ) {
720  if (space[0]!='\0') cat_s2Buffer(": {", buf);
721  else cat_s2Buffer(":{", buf);
722  if (pp->next!=NULL) {
723  if (crlf[0]!='\0') cat_s2Buffer(crlf, buf);
724  _json_to_Buffer(pp->next, buf, crlf, space);
725  if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
726  }
727  //if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
728  cat_s2Buffer("}", buf);
729  }
730  else {
731  if (pp->ldat.lv==JSON_VALUE_NULL) {
732  if (space[0]!='\0') cat_s2Buffer(": null", buf);
733  else cat_s2Buffer(":null", buf);
734  }
735  else {
736  if (space[0]!='\0') cat_s2Buffer(": ", buf);
737  else cat_s2Buffer(":", buf);
738  cat_s2Buffer(pp->ldat.val.buf, buf);
739  }
740  }
741  }
742  //
743  // array
744  else if (pp->ldat.id==JSON_ARRAY_NODE) {
745  //PRINT_MESG("JSON_ARRAY_NODE\n");
746  if (pp->ldat.key.buf!=NULL) {
747  cat_s2Buffer("\"", buf);
748  cat_s2Buffer(pp->ldat.key.buf, buf);
749  if (space[0]!='\0') cat_s2Buffer("\": ", buf);
750  else cat_s2Buffer("\":", buf);
751  }
752  if (pp->ldat.val.buf!=NULL) {
753  cat_s2Buffer(pp->ldat.val.buf, buf);
754  }
755  else {
756  cat_s2Buffer("[", buf);
757  if (pp->next!=NULL) {
758  if (crlf[0]!='\0') cat_s2Buffer(crlf, buf);
759  _json_to_Buffer(pp->next, buf, crlf, space);
760  if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
761  }
762  //if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
763  cat_s2Buffer("]", buf);
764  }
765  }
766 
767  else if (pp->ldat.id==JSON_ARRAY_VALUE_NODE) {
768  //PRINT_MESG("JSON_ARRAY_VALUE_NODE\n");
769  if (pp->ldat.lv==JSON_VALUE_OBJ) {
770  if (pp->ldat.val.buf==NULL) {
771  cat_s2Buffer("{", buf);
772  if (pp->next!=NULL) {
773  if (crlf[0]!='\0') cat_s2Buffer(crlf, buf);
774  _json_to_Buffer(pp->next, buf, crlf, space);
775  if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
776  }
777  //if (space[0]!='\0') for(i=0; i<pp->depth; i++) cat_s2Buffer(space, buf);
778  cat_s2Buffer("}", buf);
779  }
780  else {
781  cat_Buffer(&pp->ldat.val, buf);
782  }
783  }
784  else {
785  if (pp->ldat.lv==JSON_VALUE_NULL) {
786  cat_s2Buffer("null", buf);
787  }
788  else {
789  cat_s2Buffer(pp->ldat.val.buf, buf);
790  }
791  }
792  }
793 
794  if (pp->ctrl!=TREE_NOSIS_NODE && pp->ysis!=NULL &&
795  pp->prev!=NULL && pp->prev->ldat.id!=JSON_ANCHOR_NODE) cat_s2Buffer(",", buf);
796  if (crlf[0]!='\0') cat_s2Buffer(crlf, buf);
797 
798  if (pp->ctrl!=TREE_NOSIS_NODE) pp = pp->ysis;
799  else pp = NULL;
800  } while(pp!=NULL);
801  }
802 
803  return;
804 }
int cat_Buffer(Buffer *src, Buffer *dst)
Buffer変数 srcから dstへバッファを catする.
Definition: buffer.c:384
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
unsigned char ** buf
Definition: jpeg_tool.h:96
void _json_to_Buffer(tJson *pp, Buffer *buf, const char *crlf, const char *space)
tJsonデータを元の書式に戻して Bufferに格納する.補助関数.
Definition: tjson.c:688
#define JSON_ARRAY_VALUE_NODE
配列の要素データのノード.
Definition: tjson.h:32
#define JSON_DATA_NODE
key:val の形の通常のノード
Definition: tjson.h:30
#define JSON_BRACKET_NODE
'{' を格納したノード.key は持たない.
Definition: tjson.h:29
#define JSON_ANCHOR_NODE
アンカーノード
Definition: tjson.h:27
#define JSON_VALUE_NULL
属性値なし.
Definition: tjson.h:36
#define JSON_VALUE_OBJ
属性値:オブジェクト
Definition: tjson.h:41
#define JSON_ARRAY_NODE
配列ノード.処理された場合,JSON_ARRAY_VALUE_NODE を子ノードとして持つ.
Definition: tjson.h:31
#define TREE_NOSIS_NODE
このノードの姉妹ノードは処理しない.一部の関数のみ有効.
Definition: ttree.h:56

References buf, cat_Buffer(), cat_s2Buffer, JSON_ANCHOR_NODE, JSON_ARRAY_NODE, JSON_ARRAY_VALUE_NODE, JSON_BRACKET_NODE, JSON_DATA_NODE, JSON_VALUE_NULL, JSON_VALUE_OBJ, and TREE_NOSIS_NODE.

Referenced by json_inverse_parse(), and json_inverse_parse_opt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _search_all_node_strval_json()

tList* _search_all_node_strval_json ( tList list,
tJson pp,
const char *  name,
const char *  val 
)

Definition at line 1674 of file tjson.c.

1675 {
1676  while (pp->esis!=NULL) pp = pp->esis;
1677  do {
1678  if (pp->ldat.id==JSON_DATA_NODE || pp->ldat.id==JSON_ARRAY_VALUE_NODE) {
1679  if (!strncasecmp(name, (char*)pp->ldat.key.buf, strlen(name))) {
1680  if (pp->ldat.lv==JSON_VALUE_STR) {
1681  if (!strncasecmp(val, (char*)(pp->ldat.val.buf+1), strlen(val))) {
1682  list->altp = pp;
1683  tList* temp = new_tList_node();
1684  temp->ldat.id = list->ldat.id + 1;
1685  add_tList_node(list, temp);
1686  list = temp;
1687  }
1688  }
1689  }
1690  else if (pp->ldat.lv==JSON_VALUE_OBJ) {
1691  if (pp->next!=NULL) {
1692  list = _search_all_node_strval_json(list, pp->next, name, val);
1693  }
1694  }
1695  }
1696  else if (pp->ldat.id==JSON_BRACKET_NODE || pp->ldat.id==JSON_ARRAY_NODE) {
1697  if (pp->next!=NULL) {
1698  list = _search_all_node_strval_json(list, pp->next, name, val);
1699  }
1700  }
1701  pp = pp->ysis;
1702  } while (pp!=NULL);
1703 
1704  return list;
1705 }
tList * _search_all_node_strval_json(tList *list, tJson *pp, const char *name, const char *val)
search_all_node_strval_json() の補助関数
Definition: tjson.c:1674
#define JSON_VALUE_STR
属性値:文字列
Definition: tjson.h:40
tList * new_tList_node(void)
リスト用の空ノードを動的に生成する.
Definition: tlist.c:198
#define add_tList_node(p, t)
insert_tList()
Definition: tlist.h:179

References add_tList_node, JSON_ARRAY_NODE, JSON_ARRAY_VALUE_NODE, JSON_BRACKET_NODE, JSON_DATA_NODE, JSON_VALUE_OBJ, JSON_VALUE_STR, and new_tList_node().

Referenced by search_all_node_strval_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _search_key_json()

tJson* _search_key_json ( tJson pp,
const char *  key,
int  needval,
int *  nn 
)

Definition at line 1559 of file tjson.c.

1560 {
1561  while(pp->esis!=NULL) pp = pp->esis;
1562  tJson* esis = pp;
1563 
1564  while(pp!=NULL) {
1565  *nn = _json_check_node_bykey(pp, key, needval, *nn);
1566  if ((*nn)<=0) return pp;
1567  pp = pp->ysis;
1568  }
1569 
1570  // 子ノード
1571  pp = esis;
1572  while(pp!=NULL) {
1573  if (pp->next!=NULL) {
1574  tJson* json = _search_key_json(pp->next, key, needval, nn);
1575  if (json!=NULL) return json;
1576  }
1577  pp = pp->ysis;
1578  }
1579 
1580  return NULL;
1581 }
int _json_check_node_bykey(tJson *pp, const char *key, int needval, int nn)
search 系関数の補助関数
Definition: tjson.c:1632
tJson * _search_key_json(tJson *pp, const char *key, int needval, int *nn)
search_key_json() の補助関数
Definition: tjson.c:1559

References _json_check_node_bykey().

Referenced by search_key_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _search_key_json_obj()

tJson* _search_key_json_obj ( tJson pp,
const char *  key,
int *  nn 
)

Definition at line 1598 of file tjson.c.

1599 {
1600  if (pp==NULL) return NULL;
1601  while(pp->esis!=NULL) pp = pp->esis;
1602  tJson* esis = pp;
1603 
1604  while(pp!=NULL) {
1605  if (pp->ldat.lv==JSON_VALUE_OBJ) {
1606  *nn = _json_check_node_bykey(pp, key, FALSE, *nn);
1607  }
1608  if ((*nn)<=0) return pp;
1609  pp = pp->ysis;
1610  }
1611 
1612  // 子ノード
1613  pp = esis;
1614  while(pp!=NULL) {
1615  if (pp->next!=NULL) {
1616  tJson* json = _search_key_json_obj(pp->next, key, nn);
1617  if (json!=NULL) return json;
1618  }
1619  pp = pp->ysis;
1620  }
1621 
1622  return NULL;
1623 }
#define FALSE
Definition: common.h:223
tJson * _search_key_json_obj(tJson *pp, const char *key, int *nn)
search_key_json_obj() の補助関数
Definition: tjson.c:1598

References _json_check_node_bykey(), FALSE, and JSON_VALUE_OBJ.

Referenced by search_key_json_obj().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_Buffer_from_json()

Buffer get_Buffer_from_json ( tJson json)

Buffer get_Buffer_from_json(tJson* json)

JSON データのノード値の文字列をを含む Buffer変数を返す. "" または '' で囲まれている場合は,その内部のデータ("", ''の中味)の返す.

Definition at line 1795 of file tjson.c.

1796 {
1797  Buffer buf = init_Buffer();
1798 
1799  if (json==NULL) return buf;
1800 
1801  char* pp = (char*)json->ldat.val.buf;
1802 
1803  if (pp!=NULL && json->ldat.lv!=JSON_VALUE_ARRAY) {
1804  if (*pp=='\"' || *pp=='\'') {
1805  char* pt = (char*)&(json->ldat.val.buf[json->ldat.val.vldsz-1]);
1806  if (*pp==*pt) {
1807  pp++;
1808  char bkup = *pt;
1809  *pt = '\0';
1810  buf = make_Buffer_str(pp);
1811  *pt = bkup;
1812  }
1813  }
1814  else {
1815  buf = make_Buffer_str(pp);
1816  }
1817  }
1818 
1819  return buf;
1820 }
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
#define make_Buffer_str(str)
set_Buffer()
Definition: buffer.h:61
Definition: buffer.h:35
#define JSON_VALUE_ARRAY
属性値:配列
Definition: tjson.h:42

References buf, init_Buffer(), JSON_VALUE_ARRAY, and make_Buffer_str.

Here is the call graph for this function:

◆ get_double_key_json_val()

Buffer get_double_key_json_val ( tJson pp,
const char *  key1,
const char *  key2 
)

Buffer get_double_key_json_val(tJson* pp, const char* key1, const char* key2)

key1 -> key2 の親子関係を持つ,key2ノードの属性値を返す. 属性値が文字列の場合,先頭と最後の " または ' は削除する.

Parameters
pp探索を開始するノード.
key1探索するノード名.
key2探索するノード名.
Returns
見つかったノードの属性値を格納した Buffer 変数.

Definition at line 1780 of file tjson.c.

1781 {
1782  tJson* json = search_double_key_json(pp, key1, key2, TRUE);
1783  Buffer val = get_json_val(json);
1784 
1785  return val;
1786 }
#define TRUE
Definition: common.h:226
Buffer get_json_val(tJson *json)
Definition: tjson.c:1708
tJson * search_double_key_json(tJson *pp, const char *key1, const char *key2, int needval)
属性名が key1 -> key2 の親子関係を持つ,key2ノードのポインタを返す.
Definition: tjson.c:1529

References get_json_val(), search_double_key_json(), and TRUE.

Here is the call graph for this function:

◆ get_json_val()

Buffer get_json_val ( tJson json)

Definition at line 1708 of file tjson.c.

1709 {
1710  Buffer val = init_Buffer();
1711 
1712  if (json!=NULL) {
1713  char* pp = (char*)json->ldat.val.buf;
1714  if ((*pp=='\"') || (*pp=='\'')) {
1715  val = set_Buffer(pp+1, (int)strlen(pp)-1);
1716  val.buf[val.vldsz-1] = '\0';
1717  val.vldsz = (int)strlen((const char*)val.buf);
1718  }
1719  else {
1720  val = set_Buffer(pp, (int)strlen(pp));
1721  }
1722  }
1723  return val;
1724 }
int vldsz
データの長さ.バイナリデータの場合も使用可能.文字列の場合は 0x00 を含まない.
Definition: buffer.h:37
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39

References Buffer::buf, init_Buffer(), set_Buffer(), and Buffer::vldsz.

Referenced by get_double_key_json_val(), get_key_json_val(), and get_key_sister_json_val().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_key_json_val()

Buffer get_key_json_val ( tJson pp,
const char *  key,
int  nn 
)

Buffer get_key_json_val(tJson* pp, const char* key, int nn)

pp が指すノード以下で,名前(属性名)が key である nn番目のノードへの属性値を返す.
属性値が文字列の場合,先頭と最後の " または ' は削除する. pp の姉妹ノードは探索しない.

Parameters
pp探索を開始するノード.ppがオブジェクト要素(JSON_VALUE_OBJ)なら,次のノードから探索する.
key探索するノード名.
nn一致するノード内,何番目を返すか指定する.nn<=0 は nn==1 とみなす.
Returns
見つかったノードの属性値を格納した Buffer 変数.

Definition at line 1739 of file tjson.c.

1740 {
1741  tJson* json = search_key_json(pp, key, TRUE, nn);
1742  Buffer val = get_json_val(json);
1743 
1744  return val;
1745 }
tJson * search_key_json(tJson *pp, const char *key, int needval, int nn)
名前(属性名)が key である nn番目のノードへのポインタを返す
Definition: tjson.c:1383

References get_json_val(), search_key_json(), and TRUE.

Here is the call graph for this function:

◆ get_key_sister_json_val()

Buffer get_key_sister_json_val ( tJson pp,
const char *  key 
)

Buffer get_key_sister_json_val(tJson* pp, const char* key)

pp が指すノードの姉妹で,名前(属性名)が key である nn番目のノードの属性値を返す. 探索対象は探索を開始した姉妹ノードのみ. 属性値が文字列の場合,先頭と最後の " または ' は削除する.

Parameters
pp探索を開始するノード.
key探索するノード名.
needvalノードが値(属性値)を持っていない場合は無視する."", '' の場合も無視する.
Returns
見つかったノードの属性値を格納した Buffer 変数.

Definition at line 1760 of file tjson.c.

1761 {
1762  tJson* json = search_key_sister_json(pp, key, TRUE);
1763  Buffer val = get_json_val(json);
1764 
1765  return val;
1766 }
tJson * search_key_sister_json(tJson *pp, const char *key, int needval)
姉妹ノードで名前(属性名)が key である nn番目のノードへのポインタを返す.
Definition: tjson.c:1470

References get_json_val(), search_key_sister_json(), and TRUE.

Here is the call graph for this function:

◆ get_string_from_json()

char* get_string_from_json ( tJson json)

char* get_string_from_json(tJson* json)

JSON データのノード値の文字列を返す. "" または '' で囲まれている場合は,その内部のデータ("", ''の中味)の返す. 要 free

Definition at line 1830 of file tjson.c.

1831 {
1832  if (json==NULL) return NULL;
1833 
1834  char* str = NULL;
1835  char* pp = (char*)json->ldat.val.buf;
1836 
1837  if (pp!=NULL) {
1838  if (json->ldat.lv!=JSON_VALUE_ARRAY) {
1839  if (*pp=='\"' || *pp=='\'') {
1840  char* pt = (char*)&(json->ldat.val.buf[json->ldat.val.vldsz-1]);
1841  if (*pp==*pt) {
1842  pp++;
1843  char bkup = *pt;
1844  *pt = '\0';
1845  str = dup_str(pp);
1846  *pt = bkup;
1847  }
1848  }
1849  }
1850  if (str==NULL) str = dup_str(pp);
1851  }
1852 
1853  return str;
1854 }
char * dup_str(char *buf)
文字列を複製する.要 free()
Definition: tools.c:1368

References dup_str(), and JSON_VALUE_ARRAY.

Here is the call graph for this function:

◆ join_json()

tJson* join_json ( tJson parent,
tJson **  child 
)

tJson* join_json(tJson* parent, tJson** child)

parent の子として child そのものを 直接結合する(add_tTreeを使用). child の TOPが ANCHORノードまたは JSON_TEMP_NODE の場合,そのノードは削除され,*child は書き換えられる.

Parameters
parent結合対象の JSONノード
[in]child結合するJSONノード
[out]childchild のTOPがANCHOR または JSON_TEMP_NODE の場合,そのノードを削除したjsonツリーのTOP.
Returns
結合結果の JSON Treeの TOP

Definition at line 1314 of file tjson.c.

1315 {
1316  if (*child==NULL) return parent;
1317  if (parent==NULL) return *child; // この場合 ANCHOR, TEMP_NODE はそのまま
1318 
1319  if ((*child)->ldat.id==JSON_ANCHOR_NODE || (*child)->ldat.id==JSON_TEMP_NODE) { // 子として繋げる場合,ANCHOR, TEMP_NODE は削除
1320  tJson* jtmp = (*child)->next;
1321  del_json_node(child); // ANCHOR, TEMP_NODE を削除してつめる.
1322  *child = jtmp;
1323  }
1324 
1325  add_tTree(parent, *child);
1326 
1327  return parent;
1328 }
#define JSON_TEMP_NODE
一時的なノード.削除対象.
Definition: tjson.h:28
#define del_json_node(j)
JSONデータのノード削除 del_tTree_node()
Definition: tjson.h:62
tTree * add_tTree(tTree *tp, tTree *tt)
ツリー tpへ ツリー ttを追加.
Definition: ttree.c:778

References add_tTree(), del_json_node, JSON_ANCHOR_NODE, and JSON_TEMP_NODE.

Here is the call graph for this function:

◆ json_append_array_int_val()

void json_append_array_int_val ( tJson json,
int  val 
)

void json_append_array_int_val(tJson* json, int val)

配列 [] の要素として 整数 val を追加する.

Definition at line 1262 of file tjson.c.

1263 {
1264  if (json==NULL) return;
1265  if (json->ldat.id==JSON_BRACKET_NODE) {
1266  json = json->next;
1267  if (json==NULL) return;
1268  }
1269  if (json->ldat.id!=JSON_ARRAY_NODE) return;
1270 
1271  Buffer val_buf = make_Buffer(LEN_INT + 1);
1272  copy_i2Buffer(val, &val_buf);
1273  add_tTree_node_bystr(json, JSON_ARRAY_VALUE_NODE, JSON_VALUE_INT, "ARRAY_VALUE", (char*)val_buf.buf, NULL, 0);
1274 
1275  free_Buffer(&val_buf);
1276  return;
1277 }
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
int copy_i2Buffer(int src, Buffer *dst)
整数 srcを文字列に変換して,dstへ copyする.
Definition: buffer.c:664
#define LEN_INT
log 2^64 + '\0' + 1(予備)
Definition: common.h:171
#define JSON_VALUE_INT
属性値:整数 未サポート
Definition: tjson.h:37
tTree * add_tTree_node_bystr(tTree *pp, int id, int lv, const char *key, const char *val, void *ptr, int sz)
ノードを末っ子としてリストに追加.
Definition: ttree.c:202

References add_tTree_node_bystr(), Buffer::buf, copy_i2Buffer(), free_Buffer(), JSON_ARRAY_NODE, JSON_ARRAY_VALUE_NODE, JSON_BRACKET_NODE, JSON_VALUE_INT, LEN_INT, and make_Buffer().

Here is the call graph for this function:

◆ json_append_array_key()

tJson* json_append_array_key ( tJson json,
const char *  key 
)

tJson* json_append_array_key(tJson* json, const char* key)

json ツリー json に 属性名 key を持つ配列ノード "key":[] を追加する.

Returns
追加したノードへのポインタ.失敗した場合は NULL

Definition at line 1120 of file tjson.c.

1121 {
1122  if (key==NULL || json==NULL) return NULL;
1123  if (json->ldat.id==JSON_ANCHOR_NODE) json = json->next;
1124  if (json==NULL) return NULL;
1125 
1126  Buffer buf = make_Buffer_str("{");
1127  if (key[0]!='"') cat_s2Buffer("\"", &buf);
1128  cat_s2Buffer(key, &buf);
1129  if (key[strlen(key)-1]!='"') cat_s2Buffer("\"", &buf);
1130  cat_s2Buffer(":[]}", &buf);
1131 
1132  tJson* jcld = json_parse((char*)buf.buf, 1);
1133  if (jcld!=NULL && jcld->ldat.id==JSON_ANCHOR_NODE) {
1134  jcld = del_json_anchor_node(jcld);
1135  }
1136  free_Buffer(&buf);
1137 
1138  if (jcld!=NULL) {
1139  jcld = json_insert_child(json, jcld);
1140  }
1141  else {
1142  return NULL;
1143  }
1144  if (jcld->ldat.id==JSON_BRACKET_NODE) jcld = jcld->next;
1145 
1146  return jcld;
1147 }
tJson * json_parse(const char *str, int num)
文字列のJSONデータを解釈して,tJsonのツリーを生成する.ANCHOR付き.
Definition: tjson.c:51
tJson * json_insert_child(tJson *parent, tJson *child)
parent に dict または array の child を繋げる.
Definition: tjson.c:1024
#define del_json_anchor_node(t)
JSONデータの ANCHORノードを削除 del_tTree_anchor_node()
Definition: tjson.h:58

References buf, cat_s2Buffer, del_json_anchor_node, free_Buffer(), JSON_ANCHOR_NODE, JSON_BRACKET_NODE, json_insert_child(), json_parse(), and make_Buffer_str.

Here is the call graph for this function:

◆ json_append_array_real_val()

void json_append_array_real_val ( tJson json,
float  val 
)

void json_append_array_real_val(tJson* json, float val)

配列 [] の要素として 実数 val を追加する.

Definition at line 1285 of file tjson.c.

1286 {
1287  if (json==NULL) return;
1288  if (json->ldat.id==JSON_BRACKET_NODE) {
1289  json = json->next;
1290  if (json==NULL) return;
1291  }
1292  if (json->ldat.id!=JSON_ARRAY_NODE) return;
1293 
1294  Buffer val_buf = make_Buffer(LEN_REAL + 1);
1295  copy_r2Buffer(val, &val_buf);
1296  add_tTree_node_bystr(json, JSON_ARRAY_VALUE_NODE, JSON_VALUE_REAL, "ARRAY_VALUE", (char*)val_buf.buf, NULL, 0);
1297 
1298  free_Buffer(&val_buf);
1299  return;
1300 }
int copy_r2Buffer(float src, Buffer *dst)
実数 srcを文字列に変換して,dstへ copyする.
Definition: buffer.c:706
#define LEN_REAL
15*2 + '\0' + 1(予備)
Definition: common.h:170
#define JSON_VALUE_REAL
属性値:実数 未サポート
Definition: tjson.h:38

References add_tTree_node_bystr(), Buffer::buf, copy_r2Buffer(), free_Buffer(), JSON_ARRAY_NODE, JSON_ARRAY_VALUE_NODE, JSON_BRACKET_NODE, JSON_VALUE_REAL, LEN_REAL, and make_Buffer().

Here is the call graph for this function:

◆ json_append_array_str_val()

void json_append_array_str_val ( tJson json,
const char *  val 
)

void json_append_array_str_val(tJson* json, const char* val)

配列 [] の要素として 文字列 val を追加する.

Definition at line 1232 of file tjson.c.

1233 {
1234  if (json==NULL) return;
1235  if (json->ldat.id==JSON_BRACKET_NODE) {
1236  json = json->next;
1237  if (json==NULL) return;
1238  }
1239  if (json->ldat.id!=JSON_ARRAY_NODE) return;
1240 
1241  if (val!=NULL) {
1242  int len = (int)strlen(val);
1243  Buffer val_buf = make_Buffer(len + 4); // \" + \" + \0 + 予備
1244  if (val[0]!='"') cat_s2Buffer("\"", &val_buf);
1245  cat_s2Buffer(val, &val_buf);
1246  if (val[len-1]!='"') cat_s2Buffer("\"", &val_buf);
1247  add_tTree_node_bystr(json, JSON_ARRAY_VALUE_NODE, JSON_VALUE_STR, "ARRAY_VALUE", (char*)val_buf.buf, NULL, 0);
1248  free_Buffer(&val_buf);
1249  }
1250  else {
1251  add_tTree_node_bystr(json, JSON_ARRAY_VALUE_NODE, JSON_VALUE_NULL, "ARRAY_VALUE", NULL, NULL, 0);
1252  }
1253  return;
1254 }

References add_tTree_node_bystr(), Buffer::buf, cat_s2Buffer, free_Buffer(), JSON_ARRAY_NODE, JSON_ARRAY_VALUE_NODE, JSON_BRACKET_NODE, JSON_VALUE_NULL, JSON_VALUE_STR, len, and make_Buffer().

Here is the call graph for this function:

◆ json_append_obj_int_val()

void json_append_obj_int_val ( tJson json,
const char *  key,
int  val 
)

void json_append_obj_int_val(tJson* json, const char* key, int val)

{} の要素として key:val(valは整数)を追加する.

Definition at line 1186 of file tjson.c.

1187 {
1188  if (json==NULL) return;
1189  if (json->ldat.id!=JSON_BRACKET_NODE && json->ldat.lv!=JSON_VALUE_OBJ) {
1190  json = json->next;
1191  if (json!=NULL) return;
1192  if (json->ldat.id!=JSON_BRACKET_NODE && json->ldat.lv!=JSON_VALUE_OBJ) return;
1193  }
1194 
1195  Buffer val_buf = make_Buffer(LEN_INT + 1);
1196  copy_i2Buffer(val, &val_buf);
1197  add_tTree_node_bystr(json, JSON_DATA_NODE, JSON_VALUE_INT, key, (char*)val_buf.buf, NULL, 0);
1198 
1199  free_Buffer(&val_buf);
1200  return;
1201 }

References add_tTree_node_bystr(), Buffer::buf, copy_i2Buffer(), free_Buffer(), JSON_BRACKET_NODE, JSON_DATA_NODE, JSON_VALUE_INT, JSON_VALUE_OBJ, LEN_INT, and make_Buffer().

Here is the call graph for this function:

◆ json_append_obj_key()

tJson* json_append_obj_key ( tJson json,
const char *  key 
)

tJson* json_append_obj_key(tJson* json, const char* key)

json ツリー json に 属性名 key を持つオブジェクトノード "key":{} を追加する.

Returns
追加したノードへのポインタ.失敗した場合は NULL

Definition at line 1083 of file tjson.c.

1084 {
1085  if (key==NULL || json==NULL) return NULL;
1086  if (json->ldat.id==JSON_ANCHOR_NODE) json = json->next;
1087  if (json==NULL) return NULL;
1088 
1089  Buffer buf = make_Buffer_str("{");
1090  if (key[0]!='"') cat_s2Buffer("\"", &buf);
1091  cat_s2Buffer(key, &buf);
1092  if (key[strlen(key)-1]!='"') cat_s2Buffer("\"", &buf);
1093  cat_s2Buffer(":{}}", &buf);
1094 
1095  tJson* jcld = json_parse((char*)buf.buf, 1);
1096  if (jcld!=NULL && jcld->ldat.id==JSON_ANCHOR_NODE) {
1097  jcld = del_json_anchor_node(jcld);
1098  }
1099  free_Buffer(&buf);
1100 
1101  if (jcld!=NULL) {
1102  jcld = json_insert_child(json, jcld);
1103  }
1104  else {
1105  return NULL;
1106  }
1107  if (jcld->ldat.id==JSON_BRACKET_NODE) jcld = jcld->next;
1108 
1109  return jcld;
1110 }

References buf, cat_s2Buffer, del_json_anchor_node, free_Buffer(), JSON_ANCHOR_NODE, JSON_BRACKET_NODE, json_insert_child(), json_parse(), and make_Buffer_str.

Here is the call graph for this function:

◆ json_append_obj_real_val()

void json_append_obj_real_val ( tJson json,
const char *  key,
float  val 
)

void json_append_obj_real_val(tJson* json, const char* key, float val)

{} の要素として key:val(valは実数)を追加する.

Definition at line 1209 of file tjson.c.

1210 {
1211  if (json==NULL) return;
1212  if (json->ldat.id!=JSON_BRACKET_NODE && json->ldat.lv!=JSON_VALUE_OBJ) {
1213  json = json->next;
1214  if (json!=NULL) return;
1215  if (json->ldat.id!=JSON_BRACKET_NODE && json->ldat.lv!=JSON_VALUE_OBJ) return;
1216  }
1217 
1218  Buffer val_buf = make_Buffer(LEN_REAL + 1);
1219  copy_r2Buffer(val, &val_buf);
1220  add_tTree_node_bystr(json, JSON_DATA_NODE, JSON_VALUE_REAL, key, (char*)val_buf.buf, NULL, 0);
1221 
1222  free_Buffer(&val_buf);
1223  return;
1224 }

References add_tTree_node_bystr(), Buffer::buf, copy_r2Buffer(), free_Buffer(), JSON_BRACKET_NODE, JSON_DATA_NODE, JSON_VALUE_OBJ, JSON_VALUE_REAL, LEN_REAL, and make_Buffer().

Here is the call graph for this function:

◆ json_append_obj_str_val()

void json_append_obj_str_val ( tJson json,
const char *  key,
const char *  val 
)

void json_append_obj_str_val(tJson* json, const char* key, const char* val)

{} の要素として key:val(valは文字列)を追加する.

Definition at line 1155 of file tjson.c.

1156 {
1157  if (json==NULL) return;
1158  if (json->ldat.id!=JSON_BRACKET_NODE && json->ldat.lv!=JSON_VALUE_OBJ) {
1159  json = json->next;
1160  if (json!=NULL) return;
1161  if (json->ldat.id!=JSON_BRACKET_NODE && json->ldat.lv!=JSON_VALUE_OBJ) return;
1162  }
1163 
1164  if (val!=NULL) {
1165  int len = (int)strlen(val);
1166  Buffer val_buf = make_Buffer(len + 4); // \" + \" + \0 + 予備
1167  if (val[0]!='"') cat_s2Buffer("\"", &val_buf);
1168  cat_s2Buffer(val, &val_buf);
1169  if (val[len-1]!='"') cat_s2Buffer("\"", &val_buf);
1170  //
1171  add_tTree_node_bystr(json, JSON_DATA_NODE, JSON_VALUE_STR, key, (char*)val_buf.buf, NULL, 0);
1172  free_Buffer(&val_buf);
1173  }
1174  else {
1175  add_tTree_node_bystr(json, JSON_DATA_NODE, JSON_VALUE_NULL, key, NULL, NULL, 0);
1176  }
1177  return;
1178 }

References add_tTree_node_bystr(), Buffer::buf, cat_s2Buffer, free_Buffer(), JSON_BRACKET_NODE, JSON_DATA_NODE, JSON_VALUE_NULL, JSON_VALUE_OBJ, JSON_VALUE_STR, len, and make_Buffer().

Here is the call graph for this function:

◆ json_array_parse()

tJson* json_array_parse ( tJson json,
const char *  str,
int  num 
)

tJson* json_array_parse(tJson* json, const char* str, int num)

JSONデータの 配列ノードの値(配列データ)を処理する.
先頭に姉妹ノードがない場合は json にNULLを指定しても可.
ただし配列なので,先頭は姉妹ノードだらけ.アンカーノードが必要.
その状態で それでもNULLを指定した場合は,この関数外で TOPの JSON_TEMP_NODE を上手く処理すること.

Parameters
jsonJSON ノードデータ.NULLでない場合は,このデータの後に結果が付加される.
NULLでも可.
str配列処理を行うデータ.
num配列処理の残り段数.
Returns
処理された JSON ノードデータ.

Definition at line 401 of file tjson.c.

402 {
403  char* pp = (char*)str;
404  char* pt;
405  if (*pp!='[') return json;
406 
407  if (json==NULL) {
408  json = new_json_node();
409  json->ldat.id = JSON_TEMP_NODE;
410  json->ldat.lv = JSON_VALUE_NULL;
411  }
412  else {
413  json->ldat.id = JSON_ARRAY_NODE;
414  json->ldat.lv = JSON_VALUE_ARRAY;
415  }
416 
417  //
418  int depth = 1;
419  pp++;
420  while (*pp!='\0') {
421  while (*pp==' ') pp++;
422  if (*pp!='\0') while (*pp=='\\') pp += 2;
423 
424  //
425  if (*pp=='[') {
426  pt = skip_char_pair(pp, '[', ']');
427 
428  tJson* node = new_json_node();
429  node->ldat.id = JSON_ARRAY_NODE;
430  node->ldat.lv = JSON_VALUE_ARRAY;
431  add_tTree_node(json, node);
432  //
433  if (json->yngr!=NULL) {
434  int len = (int)(pt - pp) + 1;
435  Buffer temp = set_Buffer(pp, len);
436  json->yngr->ldat.val = pack_Buffer(temp, '\0');
437  json->yngr->ldat.lv = JSON_VALUE_ARRAY;
438  free_Buffer(&temp);
439  }
440  if (num>0 && json->yngr!=NULL) _json_array_parse(json->yngr, num-1);
441 
442  pt++;
443  while(*pt!=',' && *pt!='}' && *pt!='{' && *pt!='[' && *pt!='\0') pt++;
444 
445  depth++;
446  pp = pt + 1;
447  }
448 
449  //
450  else if (*pp==']') {
451  depth--;
452  if (depth==0) break;
453  pp++;
454  }
455 
456  //
457  else if (*pp=='\'' || *pp=='\"') {
458  char ch = *pp;
459  pt = pp + 1;
460  while (*pt!='\0') {
461  while (*pt=='\\') pt += 2;
462  if (*pt!='\0') {
463  if (*pt==ch) break;
464  pt++;
465  }
466  }
467 
468  if (*pt!='\0') {
469  int len = (int)(pt - pp) + 1 ;
470  tJson* node = new_json_node();
471  Buffer temp = set_Buffer(pp, len);
472  node->ldat.key = make_Buffer_bystr("ARRAY_VALUE");
473  node->ldat.val = pack_Buffer(temp, '\0');
474  node->ldat.id = JSON_ARRAY_VALUE_NODE;
475  node->ldat.lv = JSON_VALUE_STR;
476  free_Buffer(&temp);
477  add_tTree_node(json, node);
478 
479  pp = pt + 1;
480  }
481  }
482 
483  //
484  else if (*pp=='{') {
485  pt = skip_char_pair(pp, '{', '}');
486 
487  int len = (int)(pt - pp) + 1 ;
488  tJson* node = new_json_node();
489  Buffer temp = set_Buffer(pp, len);
490  node->ldat.key = make_Buffer_bystr("ARRAY_VALUE");
491  node->ldat.val = pack_Buffer(temp, '\0');
492  node->ldat.id = JSON_ARRAY_VALUE_NODE;
493  node->ldat.lv = JSON_VALUE_OBJ;
494  free_Buffer(&temp);
495 
496  if (num>0) {
497  node = json_parse_prop(node, (char*)node->ldat.val.buf, num-1);
498  add_tTree_node(json, node);
499  del_json_node(&node); // ノードを詰める
500  }
501  else {
502  add_tTree_node(json, node);
503  }
504 
505  pp = pt + 1;
506  }
507 
508  //
509  else if (*pp==',') {
510  pp++;
511  }
512 
513  //
514  else {
515  pt = skip_chars(pp, ",}]");
516 
517  int len = (int)(pt - pp);
518  tJson* node = new_json_node();
519  Buffer temp = set_Buffer(pp, len);
520  node->ldat.key = make_Buffer_bystr("ARRAY_VALUE");
521  node->ldat.val = pack_Buffer(temp, '\0');
522  node->ldat.id = JSON_ARRAY_VALUE_NODE;
523 
524  if (*pp=='\"' || *pp=='\'') node->ldat.lv = JSON_VALUE_STR;
525  else {
526  const char* val = (const char*)node->ldat.val.buf;
527  if (!strcasecmp("true", val) || !strcasecmp("false", val)) node->ldat.lv = JSON_VALUE_BOOL;
528  else {
529  int num = is_number((unsigned char*)val);
530  if (num==1) node->ldat.lv = JSON_VALUE_INT;
531  else if (num==2) node->ldat.lv = JSON_VALUE_REAL;
532  else node->ldat.lv = JSON_VALUE_UNRESOLV;
533  }
534  }
535 
536  free_Buffer(&temp);
537  add_tTree_node(json, node);
538  pp = pt;
539  }
540  }
541 
542  return json;
543 }
Buffer pack_Buffer(Buffer buf, char cc)
文字列の先頭のcc(複数),終わりのcc(複数),TAB, CR, LF を削除
Definition: buffer.c:1134
#define make_Buffer_bystr(str)
set_Buffer()
Definition: buffer.h:57
tJson * json_parse_prop(tJson *json, const char *str, int num)
JSON Main Parser.json が NULL の場合は ANCHOR付き.
Definition: tjson.c:107
tJson * _json_array_parse(tJson *json, int num)
json_parse_prop() の補助関数.配列処理用.
Definition: tjson.c:375
#define new_json_node()
JSONデータのノードを生成 new_tTree_node()
Definition: tjson.h:52
#define JSON_VALUE_UNRESOLV
属性値の種類は未確定.
Definition: tjson.h:35
#define JSON_VALUE_BOOL
属性値:論理値 未サポート
Definition: tjson.h:39
int is_number(unsigned char *str)
数字かどうか判定する(簡易版).整数(1) と小数点付き数字(2) のみ.
Definition: tools.c:1394
char * skip_chars(char *pp, const char *check)
check[]中の何れかの文字までポインタをスキップさせる.ただし クォーテーション内は完全スキップ
Definition: tools.c:948
char * skip_char_pair(char *pp, char pair, char end)
pair と end で閉じるまでポインタをスキップさせる.ただし クォーテーション内は完全スキップ
Definition: tools.c:1022
tTree * add_tTree_node(tTree *pp, tTree *node)
ツリー ppへノード nodeを末っ子として追加.
Definition: ttree.c:97

References _json_array_parse(), add_tTree_node(), del_json_node, free_Buffer(), is_number(), JSON_ARRAY_NODE, JSON_ARRAY_VALUE_NODE, json_parse_prop(), JSON_TEMP_NODE, JSON_VALUE_ARRAY, JSON_VALUE_BOOL, JSON_VALUE_INT, JSON_VALUE_NULL, JSON_VALUE_OBJ, JSON_VALUE_REAL, JSON_VALUE_STR, JSON_VALUE_UNRESOLV, len, make_Buffer_bystr, new_json_node, pack_Buffer(), set_Buffer(), skip_char_pair(), and skip_chars().

Referenced by _json_array_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ json_copy_data()

void json_copy_data ( tJson f_json,
tJson t_json 
)

void json_copy_data(tJson* f_json, tJson* t_json)

JSON ノードの f_json から t_json へ属性名と属性値をコピーする.

Definition at line 984 of file tjson.c.

985 {
986  if (f_json==NULL || t_json==NULL) return;
987  if (f_json->ldat.id==JSON_BRACKET_NODE) {
988  f_json = f_json->next;
989  if (f_json==NULL) return;
990  }
991  if (t_json->ldat.id==JSON_BRACKET_NODE) {
992  t_json = t_json->next;
993  if (t_json==NULL) return;
994  }
995 
996  t_json->ldat.id = f_json->ldat.id;
997  t_json->ldat.lv = f_json->ldat.lv;
998  copy_Buffer(&(f_json->ldat.key), &(t_json->ldat.key));
999  copy_Buffer(&(f_json->ldat.val), &(t_json->ldat.val));
1000 
1001  return;
1002 }
int copy_Buffer(Buffer *src, Buffer *dst)
Buffer型変数 srcから dstへバッファをコピーする.
Definition: buffer.c:315

References copy_Buffer(), and JSON_BRACKET_NODE.

Here is the call graph for this function:

◆ json_copy_val()

void json_copy_val ( tJson f_json,
tJson t_json 
)

void json_copy_val(tJson* f_json, tJson* t_json)

JSON ノードの f_json から t_json へ属性値をコピーする.

Definition at line 960 of file tjson.c.

961 {
962  if (f_json==NULL || t_json==NULL) return;
963  if (f_json->ldat.id==JSON_BRACKET_NODE) {
964  f_json = f_json->next;
965  if (f_json==NULL) return;
966  }
967  if (t_json->ldat.id==JSON_BRACKET_NODE) {
968  t_json = t_json->next;
969  if (t_json==NULL) return;
970  }
971 
972  t_json->ldat.lv = f_json->ldat.lv;
973  copy_Buffer(&(f_json->ldat.val), &(t_json->ldat.val));
974 
975  return;
976 }

References copy_Buffer(), and JSON_BRACKET_NODE.

Here is the call graph for this function:

◆ json_insert_child()

tJson* json_insert_child ( tJson parent,
tJson child 
)

void json_insert_child(tJson* parent, tJson* child)

json ツリー parent に json ツリー child のノードを挿入する.

取り消し 2025/5/13 誤: ANCHORノードは処理しない.ANCHORが有る場合は,これを呼び出す前に処理すること. 正: ANCHORノードは関数内で処理する.

parent が 単独の{ または 属性がOBJECTのノード の場合 child の { は破棄されて,それ以下のノードが parent の子(姉妹)として結合される. child そのものは破棄される.

parent が [ の場合 child はそのまま配列の要素として追加される.

parent がそれ外の場合 何の処理も行われない.

Definition at line 1024 of file tjson.c.

1025 {
1026  if (child!=NULL && child->ldat.id ==JSON_ANCHOR_NODE) child = child->next;
1027  if (parent!=NULL && parent->ldat.id==JSON_ANCHOR_NODE) parent = parent->next;
1028  if (parent==NULL || child ==NULL) return NULL;
1029  if (parent->ldat.id!=JSON_BRACKET_NODE && parent->ldat.lv!=JSON_VALUE_OBJ && parent->ldat.id!=JSON_ARRAY_NODE) return NULL;
1030  if (child->ldat.id !=JSON_BRACKET_NODE) return NULL;
1031 
1032  tJson* ret = NULL;
1033  //if (parent->ldat.id==JSON_BRACKET_NODE) {
1034  if (parent->ldat.id==JSON_BRACKET_NODE || parent->ldat.lv==JSON_VALUE_OBJ) {
1035  tJson* cp = child->next;
1036  while (cp!=NULL) {
1037  add_tTree(parent, cp);
1038  ret = cp;
1039  cp = cp->ysis;
1040  }
1041  clear_tList_data(&child->ldat);
1042  free(child);
1043  }
1044  else if (parent->ldat.id==JSON_ARRAY_NODE) {
1045  add_tTree(parent, child);
1046  ret = child;
1047  }
1048 
1049  return ret;
1050 }
void clear_tList_data(tList_data *ldat)
ノードデータのバッファ部をクリアする.データ自身は削除しない.
Definition: tlist.c:120

References add_tTree(), clear_tList_data(), JSON_ANCHOR_NODE, JSON_ARRAY_NODE, JSON_BRACKET_NODE, and JSON_VALUE_OBJ.

Referenced by json_append_array_key(), json_append_obj_key(), and json_insert_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ json_insert_parse()

tJson* json_insert_parse ( tJson json,
const char *  str 
)

tJson* json_insert_parse(tJson* json, const char* str)

str をパースして json に繋げる.str は { または [ で始まる必要がある.

Definition at line 1058 of file tjson.c.

1059 {
1060  if (str==NULL || json==NULL) return NULL;
1061  if (json->ldat.id==JSON_ANCHOR_NODE) json = json->next;
1062  if (json==NULL) return NULL;
1063 
1064  tJson* jcld = json_parse(str, 99);
1065  if (jcld!=NULL && jcld->ldat.id==JSON_ANCHOR_NODE) {
1066  jcld = del_json_anchor_node(jcld);
1067  }
1068  if (jcld!=NULL) {
1069  jcld = json_insert_child(json, jcld);
1070  }
1071 
1072  return jcld;
1073 }

References del_json_anchor_node, JSON_ANCHOR_NODE, json_insert_child(), and json_parse().

Here is the call graph for this function:

◆ json_inverse_parse()

Buffer json_inverse_parse ( tJson pp,
int  mode 
)

Buffer json_inverse_parse(tJson* pp, int mode)

ppに格納された tJsonデータを mode に従って,元の書式に戻して Bufferに格納する.json_parse() の逆.

Parameters
pptJsonデータが格納されたツリーへのポインタ
modeJSON_ONELINE_FORMAT 改行なしの一行にする.
modeJSON_CRLF_FORMAT ノードの終わりを CR(0x0d), LF(0x0a)で改行する.
modeJSON_INDENT_FORMAT 先頭にインデント(" ")をつけ,ノードごとに改行 CR LF (0x0d,0x0a)する.
Returns
変換したJSONデータを格納した Buffer変数.

Definition at line 616 of file tjson.c.

617 {
618  int cnt;
619  Buffer buf;
620 
621  buf = init_Buffer();
622  if (pp==NULL) return buf;
623  if (pp->ldat.id==JSON_ANCHOR_NODE) pp = pp->next;
624  if (pp==NULL) return buf;
625 
626  cnt = count_tTree(pp);
627  buf = make_Buffer(cnt*LSDATA);
628  if (buf.buf==NULL) return buf;
629 
630  if (pp->ctrl!=TREE_NOSIS_NODE) while (pp->esis!=NULL) pp = pp->esis;
631 
632  if (mode==JSON_CRLF_FORMAT) {
633  _json_to_Buffer(pp, &buf, CRLF, "");
634  }
635  else if (mode==JSON_INDENT_FORMAT) {
636  _json_to_Buffer(pp, &buf, CRLF, " ");
637  }
638  else {
639  _json_to_Buffer(pp, &buf, "", "");
640  }
641 
642  return buf;
643 }
#define CRLF
Definition: common.h:241
#define LSDATA
Definition: common.h:158
#define JSON_CRLF_FORMAT
ノードの終わりを CR(0x0d), LF(0x0a)で改行する.
Definition: tjson.h:45
#define JSON_INDENT_FORMAT
先頭にインデント(TAB)をつけ,ノードごとに改行する.
Definition: tjson.h:46
int count_tTree(tTree *pp)
ツリーの ppノード以降のノードの数を数える.
Definition: ttree.c:1151

References _json_to_Buffer(), buf, count_tTree(), CRLF, init_Buffer(), JSON_ANCHOR_NODE, JSON_CRLF_FORMAT, JSON_INDENT_FORMAT, LSDATA, make_Buffer(), and TREE_NOSIS_NODE.

Referenced by print_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ json_inverse_parse_opt()

Buffer json_inverse_parse_opt ( tJson pp,
const char *  crlf,
const char *  space 
)

Buffer json_inverse_parse_opt(tJson* pp, const char* crlf, const char* space)

ppに格納された tJsonデータを指定にしたっがて元の書式に戻して Bufferに格納する.

Parameters
pptJsonデータが格納されたツリーへのポインタ
crlfjson へ戻す時の改行コード
spaceインデントを付ける場合の空白やTAB
Returns
変換したJSONデータを格納した Buffer変数.

Definition at line 656 of file tjson.c.

657 {
658  int cnt;
659  Buffer buf;
660 
661  buf = init_Buffer();
662  if (pp==NULL) return buf;
663  if (pp->ldat.id==JSON_ANCHOR_NODE) pp = pp->next;
664  if (pp==NULL) return buf;
665 
666  cnt = count_tTree(pp);
667  buf = make_Buffer(cnt*LSDATA);
668  if (buf.buf==NULL) return buf;
669 
670  if (pp->ctrl!=TREE_NOSIS_NODE) while (pp->esis!=NULL) pp = pp->esis;
671  _json_to_Buffer(pp, &buf, crlf, space);
672 
673  return buf;
674 }

References _json_to_Buffer(), buf, count_tTree(), init_Buffer(), JSON_ANCHOR_NODE, LSDATA, make_Buffer(), and TREE_NOSIS_NODE.

Referenced by print_json_opt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ json_parse()

tJson* json_parse ( const char *  str,
int  num 
)

tJson* json_parse(const char* str, int num)

文字列のJSONデータを解釈して,tJsonのツリーを生成する. ツリーのトップは JSON_ANCHOR_NODE となる. シーケンス処理で書いたので,だらだら. あまり複雑なものはパースできない.たぶん.

Parameters
str文字列の JSONデータへのポインタ.
num0 配列を処理しない.高速.
1 配列を処するが,配列の中の JSONデータは処理しない.
2 配列の中の { } を処理する.
N 配列処理 + 再帰処理 の段数.
Returns
JSONデータを格納した tJsonのアンカーへのポインタ.
エラーの場合,next以下のノードにはエラーを起こす直前までの内容が保存される
Return values
stateエラーを起こした場合 stateに JBXL_JSON_PARSED 以外の値(負数)が入る.
tJson* json = json_parse("{\"A\": \"XYZ\"}");

Definition at line 51 of file tjson.c.

52 {
53  int state = JBXL_JSON_DEFAULT_STATE;
54  char* pp = (char*)str;
55 
56  while(*pp!='{' && *pp!='[' && *pp!='\0') pp++;
57  if (*pp=='\0') return NULL;
58  if (*pp=='[') state = JBXL_JSON_ARRAY;
59 
60  tJson* json = new_json_anchor_node(); // アンカー
61 
62  // パース
63  tJson* node = json_parse_prop(json, pp, num);
64  if (node->state<0) return node;
65  if (node->state==JBXL_JSON_PARSE_TERM) return node; // 中途半端な入力
66 
67  // 元に戻ったか?
68  if (json==node) {
69  json->state = JBXL_JSON_PARSED;
70  }
71  else {
72  json->state = JBXL_JSON_NOT_CLOSED;
73  }
74 
75  // JSON rootの数
76  if (json->next!=NULL && state!=JBXL_JSON_ARRAY) {
77  int n = 0;
78  node = json->next;
79  while(node!=NULL) {
80  if (node->ldat.id==JSON_BRACKET_NODE) n++;
81  node = node->ysis;
82  }
83  if (n!=1) json->state = JBXL_JSON_MULTI_ROOT;
84  }
85  else json->state = state;
86 
87  return json;
88 }
#define JBXL_JSON_NOT_CLOSED
JSONデータが閉じていない.原因不明.パースアルゴリズムのミス?
Definition: jbxl_state.h:111
#define JBXL_JSON_ARRAY
JSONの配列
Definition: jbxl_state.h:110
#define JBXL_JSON_MULTI_ROOT
JSONは複数のルート(TOP)を持っている.(パース済み)
Definition: jbxl_state.h:106
#define JBXL_JSON_PARSED
JSONパース済み
Definition: jbxl_state.h:105
#define JBXL_JSON_DEFAULT_STATE
JSONデータの初期状態
Definition: jbxl_state.h:115
#define new_json_anchor_node()
JSONデータの ANCHORノードを生成 new_tTree_anchor_node()
Definition: tjson.h:56

References JBXL_JSON_ARRAY, JBXL_JSON_DEFAULT_STATE, JBXL_JSON_MULTI_ROOT, JBXL_JSON_NOT_CLOSED, JBXL_JSON_PARSE_TERM, JBXL_JSON_PARSED, JSON_BRACKET_NODE, json_parse_prop(), and new_json_anchor_node.

Referenced by json_append_array_key(), json_append_obj_key(), json_insert_parse(), and json_parse_file().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ json_parse_file()

tJson* json_parse_file ( const char *  fn,
int  num 
)

tJson* json_parse_file(const char* fn, int num)

ファイルから読み込んでパースする.

Parameters
fn読み込むファイル名
num0 配列を処理しない.高速.
1 配列を処するが,配列の中の JSONデータは処理しない.
2 配列の中の { } を処理する.
N 配列処理 + 再帰処理 の段数.
Returns
JSONデータを格納した tJsonのアンカーへのポインタ

Definition at line 868 of file tjson.c.

869 {
870  tJson* json = NULL;
871  Buffer buf;
872 
873  buf = read_Buffer_file(fn);
874  if (buf.buf!=NULL) {
875  json = json_parse((char*)(buf.buf), num);
876  free_Buffer(&buf);
877  }
878 
879  return json;
880 }
Buffer read_Buffer_file(const char *fn)
ファイル fn の内容を Buffer型変数に読み込む.
Definition: buffer.c:1467

References buf, free_Buffer(), json_parse(), and read_Buffer_file().

Here is the call graph for this function:

◆ json_parse_prop()

tJson* json_parse_prop ( tJson json,
const char *  str,
int  num 
)

tJson* json_parse_prop(tJson* json, const char* str, int num)

JSON Main パーサ.
先頭に姉妹ノードがない場合は json にNULLを指定しても可.
処理に json->ctrl を使用(分割シーケンス処理用.プログラム中で書き換えられる).

Parameters
jsonJSONデータへのポインタ.
NULLでない場合は,このデータの後に結果が付加される.NULLの場合はアンカー付き.
strパースする文字列.
num0 配列を処理しない.高速.
1 配列を処するが,配列の中の JSONデータは処理しない.
2 配列の中の { } を処理する.
N 配列処理 + 再帰処理 の段数.
Returns
JSONデータを格納したポインタ.完全にパースできれば,トップを指している筈.

Definition at line 107 of file tjson.c.

108 {
109  char* pp = (char*)str;
110  char* pt = NULL;
111  tJson* node = NULL;
112  tJson* trgt = NULL;
113  int valflg = OFF;
114 
115  if (json==NULL) {
116  json = new_json_anchor_node();
117  }
118 
119  while (*pp!='\0') {
120  //
121  if (*pp=='{') {
122  //PRINT_MESG("open { \n");
123  pp++;
124  //
125  if (json->ctrl!=JBXL_JSON_NODE_OPENED) {
126  if (valflg==OFF || json->depth<0) {
127  node = new_json_node();
128  node->ldat.id = JSON_BRACKET_NODE;
129  node->ldat.lv = JSON_VALUE_OBJ;
130  json = add_tTree_node(json, node);
131  }
132  else {
133  json = json->yngr;
134  json->ldat.lv = JSON_VALUE_OBJ;
135  }
136  valflg = OFF;
137  }
138  json->ctrl = JBXL_NONE;
139 
140  // 次の \", \', {, } を見つける
141  pt = pp;
142  //while (*pt!='\0' && *pt!='\'' && *pt!='\"' && *pt!='{' && *pt!='}') pt++;
143  while(*pt!='\0') {
144  while(*pt=='\\') pt += 2;
145  if (*pt!='\0') {
146  if (*pt=='\'' || *pt=='\"' || *pt=='{' || *pt=='}') break;
147  pt++;
148  }
149  }
150  if (*pt=='\0') {
151  json = _json_parse_term(json, NULL, NULL, "{");
152  json->ctrl = JBXL_JSON_NODE_OPENED;
153  return json;
154  }
155 
156  pp = pt;
157  if (*pp=='\"' || *pp=='\'') {
158  char ch = '\"';
159  if (*pp=='\'') ch = '\'';
160  //
161  pt = pp + 1;
162  while(*pt!='\0') {
163  while(*pt=='\\') pt += 2;
164  if (*pt!='\0') {
165  if (*pt==ch) break;
166  pt++;
167  }
168  }
169  if (*pt=='\0') {
170  json = _json_parse_term(json, pp, pt, "{");
171  json->ctrl = JBXL_JSON_NODE_OPENED;
172  return json;
173  }
174 
175  int len = (int)(pt - pp) - 1 ;
176  node = new_json_node();
177  node->ldat.key = set_Buffer(pp + 1, len);
178  node->ldat.id = JSON_DATA_NODE;
179  node->ldat.lv = JSON_VALUE_NULL;
180  trgt = add_tTree_node(json, node);
181 
182  pt = pt + 1;
183  while(*pt!=',' && *pt!=':' && *pt!='}' && *pt!='\0') pt++;
184  if (*pt=='\0') {
185  json->state = JBXL_JSON_PARSE_TERM;
186  return json;
187  }
188  pp = pt;
189  }
190  }
191 
192  //
193  else if (*pp=='[') {
194  //PRINT_MESG("open [ \n");
195  pt = skip_char_pair(pp, '[', ']');
196  if (*pt=='\0') {
197  json = _json_parse_term(json, pp, pt, "[");
198  return json;
199  }
200  if (valflg==OFF || json->depth<0) { // アンカーのみ
201  node = new_json_node();
202  node->ldat.id = JSON_ARRAY_NODE;
203  node->ldat.lv = JSON_VALUE_ARRAY;
204  add_tTree_node(json, node);
205  }
206  if (json->yngr!=NULL) {
207  int len = (int)(pt - pp) + 1;
208  Buffer temp = set_Buffer(pp, len);
209  json->yngr->ldat.val = pack_Buffer(temp, '\0');
210  json->yngr->ldat.lv = JSON_VALUE_ARRAY;
211  free_Buffer(&temp);
212  }
213  valflg = OFF;
214 
215  if (num>0 && json->yngr!=NULL) _json_array_parse(json->yngr, num-1);
216 
217  pt++;
218  while(*pt!=',' && *pt!='}' && *pt!='{' && *pt!='[' && *pt!='\0') pt++;
219  if (*pt=='\0') {
220  if (json->depth>0) json->state = JBXL_JSON_PARSE_TERM;
221  return json;
222  }
223  //
224  pp = pt;
225  }
226 
227  //
228  else if (*pp==',') {
229  //PRINT_MESG("next , \n");
230  pt = pp + 1;
231  // 次の \", \', {, } を見つける
232  //while (*pt!='\0' && *pt!='\'' && *pt!='\"' && *pt!='{' && *pt!='}' && *pt!='[') pt++;
233  while(*pt!='\0') {
234  while(*pt=='\\') pt += 2;
235  if (*pt!='\0') {
236  if (*pt=='\'' || *pt=='\"' || *pt=='{' || *pt=='}' || *pt=='[') break;
237  pt++;
238  }
239  }
240  if (*pt=='\0') {
241  json = _json_parse_term(json, NULL, NULL, ",");
242  return json;
243  }
244 
245  pp = pt;
246  if (*pp=='\"' || *pp=='\'') {
247  char ch = '\"';
248  if (*pt=='\'') ch = '\'';
249  //
250  pt = pp + 1;
251  while(*pt!='\0') {
252  while(*pt=='\\') pt += 2;
253  if (*pt!='\0') {
254  if (*pt==ch) break;
255  pt++;
256  }
257  }
258  if (*pt=='\0') {
259  json = _json_parse_term(json, pp, pt, ",");
260  return json;
261  }
262 
263  int len = (int)(pt - pp) - 1 ;
264  node = new_json_node();
265  node->ldat.key = set_Buffer(pp + 1, len);
266  node->ldat.id = JSON_DATA_NODE;
267  node->ldat.lv = JSON_VALUE_NULL;
268  trgt = add_tTree_node(json, node);
269 
270  pt = pt + 1;
271  while(*pt!=',' && *pt!=':' && *pt!='}' && *pt!='\0') pt++;
272  if (*pt=='\0') {
273  json->state = JBXL_JSON_PARSE_TERM;
274  return json;
275  }
276  pp = pt;
277  }
278  }
279 
280  //
281  else if (*pp==':') {
282  //PRINT_MESG("next : \n");
283  pt = pp + 1;
284  while (*pt==' ') pt++;
285  if (*pt=='\0') {
286  json = _json_parse_term(json, NULL, NULL, ":");
287  return json;
288  }
289  pp = pt;
290 
291  if (*pp!='{' && *pp!='[') {
292  while(*pt==' ') pt++;
293  if (*pt!='\0') while (*pt=='\\') pt += 2;
294  //
295  if (*pp=='\'' || *pp=='\"') {
296  pt = skip_string_end(pt);
297  if (*pt!='\0') pt++;
298  }
299  while (*pt!=',' && *pt!='{' && *pt!='}' && *pt!='\0') pt++;
300 
301  if (*pt=='\0') {
302  json = _json_parse_term(json, pp, pt, ":");
303  return json;
304  }
305  pt--;
306  while (*pt==' ' || *pt==0x0a || *pt==0x0d) pt--;
307 
308  int len = (int)(pt - pp) + 1 ;
309  Buffer temp = set_Buffer(pp, len);
310  if (trgt==NULL) trgt = json->yngr;
311  trgt->ldat.val = pack_Buffer(temp, '\0');
312  free_Buffer(&temp);
313  //
314  if (*pp=='\"' || *pp=='\'') trgt->ldat.lv = JSON_VALUE_STR;
315  else {
316  char* val = (char*)trgt->ldat.val.buf;
317  if (!strcasecmp("true", val) || !strcasecmp("false", val)) trgt->ldat.lv = JSON_VALUE_BOOL;
318  else {
319  int num = is_number((unsigned char*)val);
320  if (num==1) trgt->ldat.lv = JSON_VALUE_INT;
321  else if (num==2) trgt->ldat.lv = JSON_VALUE_REAL;
322  else trgt->ldat.lv = JSON_VALUE_UNRESOLV;
323  }
324  }
325 
326  pt++;
327  while (*pt==' ') pt++;
328  pp = pt;
329  }
330  else {
331  valflg = ON; // ':{' or ':['
332  }
333  }
334 
335  //
336  else if (*pp=='}') {
337  //PRINT_MESG("close } \n");
338  if (json->prev!=NULL) json = json->prev;
339  //
340  pt = pp = pp + 1;
341  while (*pt!=',' && *pt!='}' && *pt!='{' && *pt!='\0') pt++;
342  if (*pt=='\0' && json->depth>0) {
343  json->state = JBXL_JSON_PARSE_TERM;
344  return json;
345  }
346  pp = pt;
347  }
348 
349  //
350  else {
351  pp++;
352  }
353  }
354 
355  if (json->ldat.id==JSON_TEMP_NODE) {
356  tJson* temp = json->next;
357  del_json_node(&json);
358  json = temp;
359  }
360 
361  json->state = JBXL_JSON_PARSED;
362  return json;
363 }
#define OFF
Definition: common.h:231
#define ON
Definition: common.h:230
#define JBXL_JSON_NODE_OPENED
JSONノードは開いている
Definition: jbxl_state.h:107
#define JBXL_NONE
情報無し
Definition: jbxl_state.h:33
tJson * _json_parse_term(tJson *json, const char *st, const char *ed, const char *com)
json_parse_prop() の補助関数.断片的な入力データ用.
Definition: tjson.c:551
char * skip_string_end(char *pp)
次の文字列を一つスキップする.最期のクォーテーションの位置を返す.
Definition: tools.c:1060

References _json_array_parse(), _json_parse_term(), add_tTree_node(), free_Buffer(), is_number(), JBXL_JSON_NODE_OPENED, JBXL_JSON_PARSE_TERM, JBXL_NONE, JSON_ARRAY_NODE, JSON_BRACKET_NODE, JSON_DATA_NODE, JSON_VALUE_ARRAY, JSON_VALUE_BOOL, JSON_VALUE_INT, JSON_VALUE_NULL, JSON_VALUE_OBJ, JSON_VALUE_REAL, JSON_VALUE_STR, JSON_VALUE_UNRESOLV, len, new_json_anchor_node, new_json_node, OFF, ON, pack_Buffer(), set_Buffer(), skip_char_pair(), and skip_string_end().

Referenced by json_array_parse(), json_parse(), and json_parse_seq().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ json_parse_seq()

tJson* json_parse_seq ( tJson json,
const char *  str,
int  num 
)

tJson* json_parse_seq(tJson* json, const char* str, int num)

断片化した JSONデータを読み込んで処理する.
処理途中の戻り値は色々な場所を指すが,最期までパースできれば,戻り値はトップに戻る.

tJson* json;
json = json_parse_seq(NULL, pp1, 99);
json = json_parse_seq(next, pp2, 99);
json = json_parse_seq(next, pp3, 99);
tJson * json_parse_seq(tJson *json, const char *str, int num)
断片化した JSONデータを読み込んで処理する.
Definition: tjson.c:581

Definition at line 581 of file tjson.c.

582 {
583  if (json==NULL) {
584  json = json_parse_prop(NULL, str, num);
585  return json;
586  }
587 
588  Buffer buf = dup_Buffer(json->ldat.val);
589  free_Buffer(&(json->ldat.val));
590  cat_s2Buffer((char*)str, &buf);
591 
592  json->state = JBXL_JSON_DEFAULT_STATE;
593  json = json_parse_prop(json, (char*)buf.buf, num);
594  free_Buffer(&buf);
595 
596  return json;
597 }
Buffer dup_Buffer(Buffer buf)
Buffer型変数のコピーをつくる.
Definition: buffer.c:211

References buf, cat_s2Buffer, dup_Buffer(), free_Buffer(), JBXL_JSON_DEFAULT_STATE, and json_parse_prop().

Here is the call graph for this function:

◆ json_set_int_val()

void json_set_int_val ( tJson json,
int  val 
)

void json_set_int_val(tJson* json, int val)

json ノードに整数の属性値(value)を設定する.

Definition at line 922 of file tjson.c.

923 {
924  if (json==NULL) return;
925  if (json->ldat.id==JSON_BRACKET_NODE) {
926  json = json->next;
927  if (json==NULL) return;
928  }
929 
930  copy_i2Buffer(val, &(json->ldat.val));
931  json->ldat.lv = JSON_VALUE_INT;
932  return;
933 }

References copy_i2Buffer(), JSON_BRACKET_NODE, and JSON_VALUE_INT.

Here is the call graph for this function:

◆ json_set_real_val()

void json_set_real_val ( tJson json,
float  val 
)

void json_set_real_val(tJson* json, float val)

json ノードに実数(float) の属性値(value)を設定する.

Definition at line 941 of file tjson.c.

942 {
943  if (json==NULL) return;
944  if (json->ldat.id==JSON_BRACKET_NODE) {
945  json = json->next;
946  if (json==NULL) return;
947  }
948 
949  copy_r2Buffer(val, &(json->ldat.val));
950  json->ldat.lv = JSON_VALUE_REAL;
951  return;
952 }

References copy_r2Buffer(), JSON_BRACKET_NODE, and JSON_VALUE_REAL.

Here is the call graph for this function:

◆ json_set_str_val()

void json_set_str_val ( tJson json,
const char *  val 
)

void json_set_str_val(tJson* json, const char* val)

json ノードに文字列の属性値(value)を設定する.

Definition at line 888 of file tjson.c.

889 {
890  if (json==NULL || val==NULL) return;
891  if (json->ldat.id==JSON_BRACKET_NODE) {
892  json = json->next;
893  if (json==NULL) return;
894  }
895 
896  Buffer buf = init_Buffer();
897  if (val[0]!='"') {
898  buf = make_Buffer((int)strlen(val) + 3); // " + " + \0
899  copy_s2Buffer("\"", &buf);
900  cat_s2Buffer(val, &buf);
901  }
902  else {
903  buf = make_Buffer_bystr(val);
904  }
905  if (buf.buf[buf.vldsz-1]!='"') {
906  cat_s2Buffer("\"", &buf);
907  }
908 
909  copy_Buffer(&buf, &(json->ldat.val));
910  json->ldat.lv = JSON_VALUE_STR;
911  free_Buffer(&buf);
912 
913  return;
914 }
#define copy_s2Buffer(src, dst)
copy_b2Buffer()
Definition: buffer.h:108

References buf, cat_s2Buffer, copy_Buffer(), copy_s2Buffer, free_Buffer(), init_Buffer(), JSON_BRACKET_NODE, JSON_VALUE_STR, make_Buffer(), and make_Buffer_bystr.

Here is the call graph for this function:

◆ print_json()

void print_json ( FILE *  fp,
tJson json,
int  mode 
)

void print_json(FILE* fp, tJson* json, int mode)

tJsonデータを modeに従って,fp に出力する.

Parameters
fp出力先のファイルポインタ
jsontJsonデータが格納されたツリーへのポインタ
modeJSON_ONELINE_FORMAT 改行なしの一行にする.
modeJSON_CRLF_FORMAT ノードの終わりを CR LF(0x0d, 0x0a) で改行する.
modeJSON_INDENT_FORMAT 先頭にインデント(TAB 0x09)をつけ,ノードごとに改行 CR LF (0x0d, 0x0a)する.

Definition at line 818 of file tjson.c.

819 {
820  Buffer buf = json_inverse_parse(json, mode);
821  if (buf.buf!=NULL) {
822  fprintf(fp, "%s", buf.buf);
823  free_Buffer(&buf);
824  }
825 
826  return;
827 }
Buffer json_inverse_parse(tJson *pp, int mode)
tJsonデータをmodeに従って元の書式に戻して Bufferに格納する.
Definition: tjson.c:616

References buf, free_Buffer(), and json_inverse_parse().

Here is the call graph for this function:

◆ print_json_opt()

void print_json_opt ( FILE *  fp,
tJson json,
const char *  crlf,
const char *  space 
)

void print_json_opt(FILE* fp, tJson* json, const char* crlf, const char* space)

tJsonデータを fp に出力する.

Parameters
fp出力先のファイルポインタ
jsontJsonデータが格納されたツリーへのポインタ
crlfjson へ戻す時の改行コード
spaceインデントを付ける場合の空白やTAB

Definition at line 840 of file tjson.c.

841 {
842  Buffer buf = json_inverse_parse_opt(json, crlf, space);
843  if (buf.buf!=NULL) {
844  fprintf(fp, "%s", buf.buf);
845  free_Buffer(&buf);
846  }
847 
848  return;
849 }
Buffer json_inverse_parse_opt(tJson *pp, const char *crlf, const char *space)
tJsonデータを指定に従って元の書式に戻して Bufferに格納する.
Definition: tjson.c:656

References buf, free_Buffer(), and json_inverse_parse_opt().

Here is the call graph for this function:

◆ search_all_node_strval_json()

tList* search_all_node_strval_json ( tJson pp,
const char *  name,
const char *  val 
)

tList* search_all_node_strval_json(tJson* pp, const char* name, const char* val)

指定した条件に会う全てのノードへのポインタを,リスト(list->altp)に格納して返す.
検索条件は,属性名 name, 属性値 val ("name": "val") を持つノード.

Parameters
pp検索する JSONデータ.
name属性名
val属性値
Returns
検索結果を altp に格納した リスト.ldat.id は通し番号で,0から始まる.altp==NULL ならそこで終わり.

Definition at line 1662 of file tjson.c.

1663 {
1664  if (pp!=NULL && pp->ldat.id==JSON_ANCHOR_NODE) pp = pp->next;
1665  if (pp==NULL) return NULL;
1666 
1667  tList* list = new_json_node();
1668  _search_all_node_strval_json(list, pp, name, val);
1669 
1670  return list;
1671 }

References _search_all_node_strval_json(), JSON_ANCHOR_NODE, and new_json_node.

Here is the call graph for this function:

◆ search_double_key_json()

tJson* search_double_key_json ( tJson pp,
const char *  key1,
const char *  key2,
int  needval 
)

tJson* search_double_key_json(tJson* pp, const char* key1, const char* key2, int needval)

key1 -> key2 の親子関係を持つ,key2ノードのポインタを返す.

Parameters
pp探索を開始するノード.
key1探索するノード名.
key2探索するノード名.
needvalTRUEの時,ky2 ノードが値(属性値)を持っていない場合は無視する."", '' の場合も無視する.
Returns
見つかったノードへのポインタ.見つからない場合は,NULL

Definition at line 1529 of file tjson.c.

1530 {
1531  if (pp==NULL || key1==NULL || key2==NULL) return NULL;
1532 
1533  pp = search_key_json_obj(pp, key1, 1);
1534  if (pp==NULL) return NULL;
1535 
1536  if (pp->next!=NULL) {
1537  pp = search_key_json(pp, key2, needval, 1);
1538  }
1539  else return NULL;
1540 
1541  return pp;
1542 }
tJson * search_key_json_obj(tJson *pp, const char *key, int nn)
名前(属性名)が key である nn番目のオブジェクトノード(JSON_VALUE_OBJ)へのポインタを返す.ex.) "key":{}
Definition: tjson.c:1497

References search_key_json(), and search_key_json_obj().

Referenced by get_double_key_json_val().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_key_child_json()

tJson* search_key_child_json ( tJson pp,
const char *  key,
int  needval 
)

tJson* search_key_child_json(tJson* pp, const char* key, int needval)

pp が指すノードの子(の姉妹)で,名前(属性名)が key であるノードへのポインタを返す. 探索対象は探索を開始した子の姉妹ノードのみ. needval が TRUE の場合は,値(属性値)を持っている場合のみカウントする.

Parameters
pp探索を開始するノード.
key探索するノード名.
needvalTRUE の場合,ノードが値(属性値)を持っていない場合は無視する."", '' の場合も無視する.
Returns
見つかったノードへのポインタ.見つからない場合は NULL

Definition at line 1447 of file tjson.c.

1448 {
1449  if (pp!=NULL && pp->ldat.id==JSON_ANCHOR_NODE) pp = pp->next;
1450  if (pp==NULL || pp->next==NULL) return NULL;
1451 
1452  tJson* json = search_key_sister_json(pp->next, key, needval);
1453 
1454  return json;
1455 }

References JSON_ANCHOR_NODE, and search_key_sister_json().

Here is the call graph for this function:

◆ search_key_json()

tJson* search_key_json ( tJson pp,
const char *  key,
int  needval,
int  nn 
)

tJson* search_key_json(tJson* pp, const char* key, int needval, int nn)

pp が指すノード以下で,名前(属性名)が key である nn番目のノードへのポインタを返す.
needval が TRUE の場合は,値(属性値)を持っている場合のみカウントする. pp の姉妹ノードは探索しない.

Parameters
pp探索を開始するノード.ppがオブジェクト要素(JSON_VALUE_OBJ)なら,次のノードから探索する.
key探索するノード名.
needvalTRUE の場合,ノードが値(属性値)を持っていない場合は無視する."", '' の場合も無視する.
nn一致するノード内,何番目を返すか指定する.nn<=0 は nn==1 とみなす.
Returns
見つかったノードへのポインタ.見つからない場合は,NULL

Definition at line 1383 of file tjson.c.

1384 {
1385  if (pp==NULL || key==NULL) return NULL;
1386  if (nn<=0) nn = 1;
1387 
1388  // 開始ノードのチェック
1389  if (!(pp->ldat.lv==JSON_VALUE_OBJ && needval)){
1390  nn = _json_check_node_bykey(pp, key, needval, nn);
1391  }
1392  // 子ノード
1393  if (nn>0 && pp->next!=NULL) {
1394  pp = _search_key_json(pp->next, key, needval, &nn);
1395  }
1396  else return NULL;
1397 
1398  return pp;
1399 }

References _json_check_node_bykey(), _search_key_json(), and JSON_VALUE_OBJ.

Referenced by get_key_json_val(), and search_double_key_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_key_json_obj()

tJson* search_key_json_obj ( tJson pp,
const char *  key,
int  nn 
)

tJson* search_key_json_obj(tJson* pp, const char* key, int nn)

pp が指すノード以下で,名前(属性名)が key である nn番目のオブジェクトノード(JSON_VALUE_OBJ)へのポインタを返す. pp の姉妹ノードは探索しない. search_key_json() よりは少し早い.たぶん.

Parameters
pp探索を開始するノード.
key探索するノード名.
nn一致するノード内,何番目を返すか指定する.nn<=0 は nn==1 とみなす.
Returns
見つかったオブジェクトノードへのポインタ.見つからない場合は,NULL

Definition at line 1497 of file tjson.c.

1498 {
1499  if (pp==NULL || key==NULL) return NULL;
1500  if (nn<=0) nn = 1;
1501 
1502  // 開始ノードのチェック
1503  if (pp->ldat.lv==JSON_VALUE_OBJ) {
1504  nn = _json_check_node_bykey(pp, key, FALSE, nn);
1505  }
1506  if (nn==0) return pp;
1507 
1508  // 子ノード
1509  if (pp->next!=NULL) {
1510  pp = _search_key_json_obj(pp->next, key, &nn);
1511  }
1512  else return NULL;
1513 
1514  return pp;
1515 }

References _json_check_node_bykey(), _search_key_json_obj(), FALSE, and JSON_VALUE_OBJ.

Referenced by search_double_key_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_key_sister_json()

tJson* search_key_sister_json ( tJson pp,
const char *  key,
int  needval 
)

tJson* search_key_sister_json(tJson* pp, const char* key, int needval)

pp が指すノードの姉妹で,名前(属性名)が key であるノードへのポインタを返す. 探索対象は探索を開始した姉妹ノードのみ. needval が TRUE の場合は,値(属性値)を持っている場合のみカウントする.

Parameters
pp探索を開始するノード.
key探索するノード名.
needvalTRUE の場合,ノードが値(属性値)を持っていない場合は無視する."", '' の場合も無視する.
Returns
見つかったノードへのポインタ.見つからない場合は,NULL

Definition at line 1470 of file tjson.c.

1471 {
1472  if (pp==NULL || key==NULL) return NULL;
1473  while(pp->esis!=NULL) pp = pp->esis;
1474 
1475  while(pp!=NULL) {
1476  int nn = _json_check_node_bykey(pp, key, needval, 1);
1477  if (nn==0) return pp;
1478  pp = pp->ysis;
1479  }
1480 
1481  return NULL;
1482 }

References _json_check_node_bykey().

Referenced by get_key_sister_json_val(), and search_key_child_json().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_sister_json()

tJson* search_sister_json ( tJson pp,
int  nn 
)

tJson* search_sister_json(tJson* pp, int nn)

nn個先の sister ノードを返す.正数の場合は younger sister,負数の場合は elder sister を検索する.

Parameters
pp探索を開始するノード.
nn何個先の sister かを指定する.正数の場合は younger sister,負数の場合は elder sister.
Returns
sister ノードへのポインタ.存在しない場合は NULL

Definition at line 1412 of file tjson.c.

1413 {
1414  if (pp==NULL) return NULL;
1415 
1416  if (nn>0) {
1417  int i = 0;
1418  while (pp!=NULL && i<nn) {
1419  pp = pp->ysis;
1420  i++;
1421  }
1422  }
1423  else if (nn<0) {
1424  nn = -nn;
1425  int i = 0;
1426  while (pp!=NULL && i<nn) {
1427  pp = pp->esis;
1428  i++;
1429  }
1430  }
1431  return pp;
1432 }

◆ search_top_bracket_json()

tJson* search_top_bracket_json ( tJson pp,
int  nn 
)

tJson* search_top_bracket_json(tJson* pp, int nn)

ツリーが複数のルート(TOP)を持つ場合(state==JBXL_JSON_MULTI_ROOT),指定された順番のTOPへのポインタを返す.

Parameters
nn何番目のTOPを返すか指定する.nn<=0 は nn==1 とみなす.
Returns
見つかったノードへのポインタ.見つからない場合は,NULL

Definition at line 1343 of file tjson.c.

1344 {
1345  if (pp==NULL) return NULL;
1346  if (nn<=0) nn = 1;
1347 
1348  while (pp->prev!=NULL) pp = pp->prev;
1349 
1350  if (pp->ldat.id==JSON_ANCHOR_NODE) {
1351  pp = pp->next;
1352  }
1353  if (pp->ldat.id==JSON_BRACKET_NODE) {
1354  while(pp->esis!=NULL) pp = pp->esis;
1355  }
1356  else {
1357  return NULL;
1358  }
1359 
1360  int i = 1;
1361  while (i<nn && pp!=NULL) {
1362  pp = pp->ysis;
1363  i++;
1364  }
1365 
1366  return pp;
1367 }

References JSON_ANCHOR_NODE, and JSON_BRACKET_NODE.