]> git.plutz.net Git - cgilite/blob - json.sh
read json data into recursive DB2 structure
[cgilite] / json.sh
1 #!/bin/sh
2
3 # [ -n "$include_json" ] && return 0
4 # include_json="$0"
5
6 . "${_EXEC:-.}/cgilite/db23.sh"
7
8 json_except() {
9   printf '%s\n' "$@" >&2;
10   printf 'Exc: %s\n' "$json_document" >&2
11 }
12
13 json_space() {
14   while true; do case "$json_document" in
15     [" ${BR}${CR}       "]*) json_document="${json_document#?}";;
16     *) break ;;
17   esac; done
18 }
19
20 json_string() {
21   local string json_document="$json_document" end=0
22
23   json_space
24   case $json_document in
25     \"*) json_document="${json_document#?}"
26       ;;
27     *) json_except "Expected string specifyer starting with (\")"
28       return 1
29       ;;
30   esac
31   while [ "$json_document" ]; do case $json_document in
32     \\?*)
33       string="${string}${json_document%"${json_document#??}"}"
34       json_document="${json_document#??}"
35       ;;
36     \"*)
37       json_document="${json_document#?}"
38       end=1
39       break
40       ;;
41     *) 
42       string="${string}${json_document%"${json_document#?}"}"
43       json_document="${json_document#?}"
44       ;;
45   esac; done
46
47   if [ $end -eq 0 ]; then
48     json_except "Document ended mid-string"
49     return 1
50   fi
51
52   printf "%s    %s\n" "$(STRING "$string")" "$json_document"
53 }
54
55 json_key() {
56   local key json_document="$json_document"
57
58   json_space
59   case $json_document in
60     \"*)
61       key="$(json_string)" || return 1
62       json_document="${key#*    }"
63       key="${key%%      *}"
64       ;;
65     *) json_except "Expected key specifyer starting with '\"'"
66       return 1
67       ;;
68   esac
69   json_space
70   case $json_document in
71     :*) json_document="${json_document#?}"
72       ;;
73     *) json_except "Expected value separator \":\""
74       return 1
75       ;;
76   esac
77
78   printf '%s    %s\n' "$key" "$json_document"
79 }
80
81 json_number() {
82   local number json_document="$json_document"
83
84   json_space
85   number="${json_document%%["   ${BR}${CR} ,}]"]*}"
86   json_document="${json_document#"$number"}"
87   if ! number="$(printf %f "$number")"; then
88     json_except "Invalid number format"
89     return 1
90   fi
91
92   printf '%s    %s\n' "num:${number%.000000}" "$json_document"
93 }
94
95 json_value() {
96   local value json_document="$json_document"
97
98   json_space
99   case $json_document in
100     \"*)
101       value="$(json_string)" || return 1
102       json_document="${value#*  }"
103       value="str:${value%%      *}"
104       ;;
105     [+-.0-9]*)
106       value="$(json_number)" || return 1
107       json_document="${value#*  }"
108       value="${value%%  *}"
109       ;;
110     "{"*)
111       value="$(json_object)" || return 1
112       json_document="${value#*  }"
113       value="obj:${value%%      *}"
114       ;;
115     "["*)
116       value="$(json_array)" || return 1
117       json_document="${value#*  }"
118       value="arr:${value%%      *}"
119       ;;
120     null*)
121       json_document="${json_document#null}"
122       value="null"
123       ;;
124     true*)
125       json_document="${json_document#true}"
126       value="true"
127       ;;
128     false*)
129       json_document="${json_document#false}"
130       value="false"
131       ;;
132   esac
133
134   printf "%s    %s\n" "$value" "$json_document"
135 }
136
137 json_array() {
138   local struct="$(DB2 new)" value json_document="$json_document"
139
140   json_space
141   case $json_document in
142     "["*) json_document="${json_document#?}"
143       ;;
144     *) json_except "Expected array starting with \"[\""
145       return 1
146       ;;
147   esac
148
149   json_space
150   case $json_document in
151     "]"*)
152       printf "%s        %s\n" "" "${json_document#?}"
153       return 0
154       ;;
155   esac
156
157   while :; do
158     json_space
159
160     value="$(json_value)" || return 1
161     json_document="${value#*    }"
162     value="$(UNSTRING "${value%%        *}")"
163
164        struct="$(DB2 "$struct" append "@" "$value")" \
165     || struct="$(DB2 "$struct" set    "@" "$value")"
166
167     json_space
168     case $json_document in
169       ,*) json_document="${json_document#?}"
170         ;;
171       "]"*) json_document="${json_document#?}"
172         break
173         ;;
174       *) json_except "Unexpected character mid-array"
175         return 1
176         ;;
177     esac
178   done
179
180   printf "%s    %s\n" "$(STRING "$struct")" "$json_document"
181 }
182
183 json_object() {
184   local struct="$(DB2 new)" key value json_document="$json_document"
185
186   json_space
187   case $json_document in
188     "{"*) json_document="${json_document#?}"
189       ;;
190     *) json_except "Expected object starting with \"{\""
191       return 1
192       ;;
193   esac
194
195   json_space
196   case $json_document in
197     "}"*)
198       printf "%s        %s\n" "" "${json_document#?}"
199       return 0
200       ;;
201   esac
202
203   while :; do
204     json_space
205
206     key="$(json_key)" || return 1
207     json_document="${key#*      }"
208     key="$(UNSTRING "${key%%    *}")"
209
210     value="$(json_value)" || return 1
211     json_document="${value#*    }"
212     value="$(UNSTRING "${value%%        *}")"
213
214     struct="$(DB2 "$struct" set "$key" "$value")"
215
216     json_space
217     case $json_document in
218       ,*) json_document="${json_document#?}"
219         ;;
220       "}"*) json_document="${json_document#?}"
221         break
222         ;;
223       *) json_except "Unexpected character mid-object"
224         return 1
225         ;;
226     esac
227   done
228
229   printf "%s    %s\n" "$(STRING "$struct")" "$json_document"
230 }
231
232 json_load() {
233   local json_document="$1"
234
235   json_value
236 }