From: Paul Hänsch <paul@plutz.net>
Date: Sat, 24 Feb 2024 11:54:22 +0000 (+0100)
Subject: read json data into recursive DB2 structure
X-Git-Url: https://git.plutz.net/?a=commitdiff_plain;h=b8a42461bbd21d42576c58ae807f25ac354edfb8;p=cgilite

read json data into recursive DB2 structure
---

diff --git a/json.sh b/json.sh
new file mode 100755
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
+}