X-Git-Url: http://git.plutz.net/?a=blobdiff_plain;f=json.sh;h=12afdc4d676b94b705b0c165fee2512c80891cb9;hb=HEAD;hp=43026bed6bae6a5f9197b61cb2d75f2fd13eb278;hpb=0a8a8519620984650a4354db3f3447891cc74aac;p=cgilite diff --git a/json.sh b/json.sh index 43026be..12afdc4 100755 --- a/json.sh +++ b/json.sh @@ -1,11 +1,11 @@ #!/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; } +# debug(){ [ $# -gt 0 ] && printf '%s\n' "$@" >&2 || tee -a /dev/stderr; } json_except() { printf '%s\n' "$@" >&2; @@ -91,61 +91,11 @@ json_number() { return 1 fi - printf '%s %s\n' "num:${number%.000000}" "$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="${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" + printf '%s %s\n' "${number%.000000}" "$json_document" } json_array() { - local struct="$(DB2 new)" value json_document="$json_document" + local struct="$(DB2 "" new)" value json_document="$json_document" json_space case $json_document in @@ -191,7 +141,7 @@ json_array() { } json_object() { - local struct="$(DB2 new)" key value json_document="$json_document" + local struct="$(DB2 "" new)" key value json_document="$json_document" json_space case $json_document in @@ -239,14 +189,64 @@ 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 + json_value |UNSTRING } json_get() { - local json="$1" jpath="${2#.}" id idx + local json="$1" jpath="${2#.}" key idx json_type='' case $json in @@ -258,11 +258,10 @@ json_get() { json_type="boolean";; null) json_type="null";; esac - json="${json#???:}" case $jpath in "") - printf %s\\n "$json" + printf %s\\n "${json#???:}" return 0 ;; "["[0-9]*"]"*) @@ -270,30 +269,92 @@ json_get() { jpath="${jpath#"["*"]"}" ;; "['"*"']"*) - id="${jpath%%"']"*}" id="${id#"['"}" + key="${jpath%%"']"*}" key="${key#"['"}" jpath="${jpath#"['"*"']"}" ;; - *) id="${jpath%%[".["]*}" - jpath="${jpath#"$id"}" + "$"*) + jpath="${jpath#?}" + ;; + *) key="${jpath%%[".["]*}" + jpath="${jpath#"$key"}" ;; esac - if [ "$id" -a "$json_type" = object ]; then - # if ! json="$(DB2 "$(UNSTRING "$json")" get "$id")"; then - if ! json="$(DB2 "$json" get "$id")"; then - debug "No key: \"$id\"" + 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 "$(UNSTRING "$json")" get @ "$(( idx + 1 ))")"; then - # if ! json="$(DB2 "$json" get @ "$(( idx + 1 ))")"; then - debug "No array index: \"$idx\"" + if ! json="$(DB2 "${json#arr:}" get @ "$(( idx + 1 ))")"; then + debug "Array index not found: \"$idx\"" return 1 fi - else - debug "Value type missmatch" + 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_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 +}