#!/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
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() {
- local struct="$(DB2 new)" value json_document="$json_document"
+ local struct="$(DB2 "" new)" value json_document="$json_document"
json_space
case $json_document in
}
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
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
}