X-Git-Url: http://git.plutz.net/?a=blobdiff_plain;f=json.sh;h=f43f8ec3c6aabe0633ab9cf45e78755db910a0f3;hb=0591b0842c75fd078d19e488f5e4a8d047052551;hp=99e1e746140af0d635080941e04d089d28043af5;hpb=b8a42461bbd21d42576c58ae807f25ac354edfb8;p=cgilite diff --git a/json.sh b/json.sh index 99e1e74..f43f8ec 100755 --- a/json.sh +++ b/json.sh @@ -1,10 +1,12 @@ #!/bin/sh -# [ -n "$include_json" ] && return 0 -# include_json="$0" +[ -n "$include_json" ] && return 0 +include_json="$0" . "${_EXEC:-.}/cgilite/db23.sh" +# debug(){ [ $# -gt 0 ] && printf '%s\n' "$@" >&2 || tee -a /dev/stderr; } + json_except() { printf '%s\n' "$@" >&2; printf 'Exc: %s\n' "$json_document" >&2 @@ -89,49 +91,7 @@ json_number() { return 1 fi - printf '%s %s\n' "num:${number%.000000}" "$json_document" -} - -json_value() { - local value json_document="$json_document" - - json_space - case $json_document in - \"*) - value="$(json_string)" || return 1 - json_document="${value#* }" - value="str:${value%% *}" - ;; - [+-.0-9]*) - value="$(json_number)" || return 1 - json_document="${value#* }" - value="${value%% *}" - ;; - "{"*) - value="$(json_object)" || return 1 - json_document="${value#* }" - value="obj:${value%% *}" - ;; - "["*) - value="$(json_array)" || return 1 - json_document="${value#* }" - value="arr:${value%% *}" - ;; - null*) - json_document="${json_document#null}" - value="null" - ;; - true*) - json_document="${json_document#true}" - value="true" - ;; - false*) - json_document="${json_document#false}" - value="false" - ;; - esac - - printf "%s %s\n" "$value" "$json_document" + printf '%s %s\n' "${number%.000000}" "$json_document" } json_array() { @@ -229,8 +189,172 @@ json_object() { printf "%s %s\n" "$(STRING "$struct")" "$json_document" } +json_value() { + local value json_document="$json_document" + json_type="" + + json_space + case $json_document in + \"*) + value="$(json_string)" || return 1 + json_document="${value#* }" + value="str:${value%% *}" + json_type=string + ;; + [+-.0-9]*) + value="$(json_number)" || return 1 + json_document="${value#* }" + value="num:${value%% *}" + json_type=number + ;; + "{"*) + value="$(json_object)" || return 1 + json_document="${value#* }" + value="obj:${value%% *}" + json_type=object + ;; + "["*) + value="$(json_array)" || return 1 + json_document="${value#* }" + value="arr:${value%% *}" + json_type=array + ;; + null*) + json_document="${json_document#null}" + value="null" + json_type=null + ;; + true*) + json_document="${json_document#true}" + value="true" + json_type=boolean + ;; + false*) + json_document="${json_document#false}" + value="false" + json_type=boolean + ;; + esac + + printf "%s %s\n" "$value" "$json_document" +} + json_load() { - local json_document="$1" + local json_document="$1" json + + json_value |UNSTRING +} + +json_get() { + local json="$1" jpath="${2#.}" key idx + json_type='' + + case $json in + str:*) json_type="string";; + arr:*) json_type="array";; + obj:*) json_type="object";; + num:*) json_type="number";; + true|false) + json_type="boolean";; + null) json_type="null";; + esac + + case $jpath in + "") + printf %s\\n "${json#???:}" + return 0 + ;; + "["[0-9]*"]"*) + idx="${jpath%%"]"*}" idx="${idx#"["}" + jpath="${jpath#"["*"]"}" + ;; + "['"*"']"*) + key="${jpath%%"']"*}" key="${key#"['"}" + jpath="${jpath#"['"*"']"}" + ;; + "$"*) + jpath="${jpath#?}" + ;; + *) key="${jpath%%[".["]*}" + jpath="${jpath#"$key"}" + ;; + esac + + if [ "$key" -a "$json_type" = object ]; then + if ! json="$(DB2 "${json#obj:}" get "$key")"; then + debug "Key not found: \"$key\"" + return 1 + fi + elif [ "$idx" -a "$json_type" = array ]; then + if ! json="$(DB2 "${json#arr:}" get @ "$(( idx + 1 ))")"; then + debug "Array index not found: \"$idx\"" + return 1 + fi + elif [ "$key" ]; then + debug "Cannot select key (\"$key\") from value of type \"$json_type\"" + return 1 + elif [ "$idx" ]; then + debug "Cannot select index ($idx) from value of type \"$json_type\"" + return 1 + fi + json_get "$json" "$jpath" + return $? +} + +json_dump_string() { + local in="$1" out='' + while [ "$in" ]; do case $in in + \\*) out="${out}\\\\"; in="${in#\\}" ;; + "$BR"*) out="${out}\\n"; in="${in#${BR}}" ;; + "$CR"*) out="${out}\\r"; in="${in#${CR}}" ;; + " "*) out="${out}\\t"; in="${in# }" ;; + \"*) out="${out}\\\""; in="${in#\"}" ;; + *) out="${out}${in%%[\\${CR}${BR} \"]*}"; in="${in#"${in%%[\\${BR}${CR} \"]*}"}" ;; + esac; done + printf '"%s"' "${out}" +} - json_value +json_dump_array() { + local json="$1" value out='' + + for value in $(DB2 "$json" iterate @); do + out="${out},$(json_dump "$(UNSTRING "$value")")" + done + printf '[%s]' "${out#,}" +} + +json_dump_object() { + local json="$1" key value out='' + + while read -r key value; do + out="${out},$(json_dump_string "$(UNSTRING "$key")"):$(json_dump "$(UNSTRING "$value")")" + done <<-EOF + ${json} + EOF + printf '{%s}' "${out#,}" +} + +json_dump() { + local json="$1" + + case $json in + str:*) + json_dump_string "${json#str:}" + ;; + arr:*) + json_dump_array "${json#arr:}" + ;; + obj:*) + json_dump_object "${json#obj:}" + ;; + num:*) + printf "${json#num:}" + ;; + true|false|null) + printf %s\\n "$json" + ;; + *) + json_dump_string "${json}" + ;; + esac }