]> git.plutz.net Git - cgilite/commitdiff
read json data into recursive DB2 structure
authorPaul Hänsch <paul@plutz.net>
Sat, 24 Feb 2024 11:54:22 +0000 (12:54 +0100)
committerPaul Hänsch <paul@plutz.net>
Sat, 24 Feb 2024 11:54:22 +0000 (12:54 +0100)
json.sh [new file with mode: 0755]

diff --git a/json.sh b/json.sh
new file mode 100755 (executable)
index 0000000..99e1e74
--- /dev/null
+++ b/json.sh
@@ -0,0 +1,236 @@
+#!/bin/sh
+
+# [ -n "$include_json" ] && return 0
+# include_json="$0"
+
+. "${_EXEC:-.}/cgilite/db23.sh"
+
+json_except() {
+  printf '%s\n' "$@" >&2;
+  printf 'Exc: %s\n' "$json_document" >&2
+}
+
+json_space() {
+  while true; do case "$json_document" in
+    [" ${BR}${CR}      "]*) json_document="${json_document#?}";;
+    *) break ;;
+  esac; done
+}
+
+json_string() {
+  local string json_document="$json_document" end=0
+
+  json_space
+  case $json_document in
+    \"*) json_document="${json_document#?}"
+      ;;
+    *) json_except "Expected string specifyer starting with (\")"
+      return 1
+      ;;
+  esac
+  while [ "$json_document" ]; do case $json_document in
+    \\?*)
+      string="${string}${json_document%"${json_document#??}"}"
+      json_document="${json_document#??}"
+      ;;
+    \"*)
+      json_document="${json_document#?}"
+      end=1
+      break
+      ;;
+    *) 
+      string="${string}${json_document%"${json_document#?}"}"
+      json_document="${json_document#?}"
+      ;;
+  esac; done
+
+  if [ $end -eq 0 ]; then
+    json_except "Document ended mid-string"
+    return 1
+  fi
+
+  printf "%s   %s\n" "$(STRING "$string")" "$json_document"
+}
+
+json_key() {
+  local key json_document="$json_document"
+
+  json_space
+  case $json_document in
+    \"*)
+      key="$(json_string)" || return 1
+      json_document="${key#*   }"
+      key="${key%%     *}"
+      ;;
+    *) json_except "Expected key specifyer starting with '\"'"
+      return 1
+      ;;
+  esac
+  json_space
+  case $json_document in
+    :*) json_document="${json_document#?}"
+      ;;
+    *) json_except "Expected value separator \":\""
+      return 1
+      ;;
+  esac
+
+  printf '%s   %s\n' "$key" "$json_document"
+}
+
+json_number() {
+  local number json_document="$json_document"
+
+  json_space
+  number="${json_document%%["  ${BR}${CR} ,}]"]*}"
+  json_document="${json_document#"$number"}"
+  if ! number="$(printf %f "$number")"; then
+    json_except "Invalid number format"
+    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"
+}
+
+json_array() {
+  local struct="$(DB2 new)" value json_document="$json_document"
+
+  json_space
+  case $json_document in
+    "["*) json_document="${json_document#?}"
+      ;;
+    *) json_except "Expected array starting with \"[\""
+      return 1
+      ;;
+  esac
+
+  json_space
+  case $json_document in
+    "]"*)
+      printf "%s       %s\n" "" "${json_document#?}"
+      return 0
+      ;;
+  esac
+
+  while :; do
+    json_space
+
+    value="$(json_value)" || return 1
+    json_document="${value#*   }"
+    value="$(UNSTRING "${value%%       *}")"
+
+       struct="$(DB2 "$struct" append "@" "$value")" \
+    || struct="$(DB2 "$struct" set    "@" "$value")"
+
+    json_space
+    case $json_document in
+      ,*) json_document="${json_document#?}"
+        ;;
+      "]"*) json_document="${json_document#?}"
+        break
+        ;;
+      *) json_except "Unexpected character mid-array"
+        return 1
+        ;;
+    esac
+  done
+
+  printf "%s   %s\n" "$(STRING "$struct")" "$json_document"
+}
+
+json_object() {
+  local struct="$(DB2 new)" key value json_document="$json_document"
+
+  json_space
+  case $json_document in
+    "{"*) json_document="${json_document#?}"
+      ;;
+    *) json_except "Expected object starting with \"{\""
+      return 1
+      ;;
+  esac
+
+  json_space
+  case $json_document in
+    "}"*)
+      printf "%s       %s\n" "" "${json_document#?}"
+      return 0
+      ;;
+  esac
+
+  while :; do
+    json_space
+
+    key="$(json_key)" || return 1
+    json_document="${key#*     }"
+    key="$(UNSTRING "${key%%   *}")"
+
+    value="$(json_value)" || return 1
+    json_document="${value#*   }"
+    value="$(UNSTRING "${value%%       *}")"
+
+    struct="$(DB2 "$struct" set "$key" "$value")"
+
+    json_space
+    case $json_document in
+      ,*) json_document="${json_document#?}"
+        ;;
+      "}"*) json_document="${json_document#?}"
+        break
+        ;;
+      *) json_except "Unexpected character mid-object"
+        return 1
+        ;;
+    esac
+  done
+
+  printf "%s   %s\n" "$(STRING "$struct")" "$json_document"
+}
+
+json_load() {
+  local json_document="$1"
+
+  json_value
+}