;============================================================ ; iron_json_net.hsp — JSON (.NET System.Text.Json 版) ; ; System.Text.Json.JsonDocument を使った堅牢な JSON 読み書き。 ; 既存 iron_json (hspjson.dll) と比較して: ; + JSON-Text 標準 (RFC 8259) に厳密準拠 ; + large number 精度保持 / unicode escape 完全対応 ; + LINQ 的な深掘りが 1 行 ; hsp3net 専用。 ; ; API: ; jsonn_parse "...json text..." → stat=0 OK ; jsonn_str "path.to.key", var_out → refstr / var_out ; jsonn_int "path.to.key" → stat=int ; jsonn_dbl "path.to.key" → refdval=double ; jsonn_len "path.to.array" → stat=len ; jsonn_type "path.to.key" → stat 0=null 1=obj 2=arr 3=str 4=num 5=bool ; jsonn_to_string → refstr (roundtrip) ; jsonn_pretty → refstr (indented) ; ; パス形式: "a.b.c" / "arr[0].x" ; ; 依存アセンブリ: System.Text.Json.dll (.NET Framework 4.7.2+ or ; System.Text.Json NuGet を GAC に入れた .NET Fw 4.6.1+) ; 未導入環境なら iron_json (hspjson) を使うこと。 ;============================================================ #ifndef __iron_json_net_hsp__ #define __iron_json_net_hsp__ #module iron_json_net dim _jsn_cs_loaded, 1 #deffunc _jsn_load_cs if _jsn_cs_loaded : return sdim _cs, 16384 _cs = {" using System; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; public class HspJsonNet { static JsonNode root = null; public static string Parse(string text) { try { root = JsonNode.Parse(text); return "0"; } catch (Exception e) { return "-1\t" + e.Message; } } public static string GetStr(string path) { var n = Navigate(path); if (n == null) return ""; if (n is JsonValue v) { if (v.TryGetValue(out var s)) return s; return v.ToString(); } return n.ToJsonString(); } public static string GetInt(string path) { var n = Navigate(path); if (n == null) return "0"; if (n is JsonValue v) { if (v.TryGetValue(out var l)) return l.ToString(); if (v.TryGetValue(out var d)) return ((long)d).ToString(); } return "0"; } public static string GetDbl(string path) { var n = Navigate(path); if (n == null) return "0"; if (n is JsonValue v) { if (v.TryGetValue(out var d)) return d.ToString(System.Globalization.CultureInfo.InvariantCulture); } return "0"; } public static string GetLen(string path) { var n = Navigate(path); if (n == null) return "-1"; if (n is JsonArray a) return a.Count.ToString(); if (n is JsonObject o) return o.Count.ToString(); return "-1"; } public static string GetType(string path) { var n = Navigate(path); if (n == null) return "0"; if (n is JsonObject) return "1"; if (n is JsonArray) return "2"; if (n is JsonValue v) { if (v.TryGetValue(out _)) return "3"; if (v.TryGetValue(out _)) return "4"; if (v.TryGetValue(out _)) return "5"; } return "0"; } public static string ToText() { if (root == null) return ""; return root.ToJsonString(); } public static string ToPretty() { if (root == null) return ""; return root.ToJsonString(new JsonSerializerOptions { WriteIndented = true }); } // ---- 書き込み系 ---- public static string NewObject() { root = new JsonObject(); return "0"; } public static string NewArray() { root = new JsonArray(); return "0"; } public static string SetStr(string path, string value) { return Put(path, JsonValue.Create(value)); } public static string SetInt(string path, long value) { return Put(path, JsonValue.Create(value)); } public static string SetDbl(string path, double value) { return Put(path, JsonValue.Create(value)); } public static string SetBool(string path, int value) { return Put(path, JsonValue.Create(value != 0)); } public static string SetNull(string path) { return Put(path, null); } public static string ArrAppend(string path, string json_fragment) { var parent = Navigate(path); if (!(parent is JsonArray arr)) return "-1"; JsonNode node = string.IsNullOrEmpty(json_fragment) ? null : JsonNode.Parse(json_fragment); arr.Add(node); return "0"; } public static string Remove(string path) { if (string.IsNullOrEmpty(path)) { root = null; return "0"; } // parent までナビし最後のキー/添字で削除 int lastDot = path.LastIndexOf('.'); int lastBr = path.LastIndexOf('['); int tail = lastDot > lastBr ? lastDot : lastBr; if (tail < 0) { if (root is JsonObject o) { o.Remove(path); return "0"; } return "-1"; } var parent = Navigate(path.Substring(0, tail)); if (parent == null) return "-1"; string key = path.Substring(tail); if (key.StartsWith(".")) key = key.Substring(1); if (key.StartsWith("[") && key.EndsWith("]")) { int idx = int.Parse(key.Substring(1, key.Length - 2)); if (parent is JsonArray a && idx >= 0 && idx < a.Count) { a.RemoveAt(idx); return "0"; } return "-1"; } if (parent is JsonObject o2) { o2.Remove(key); return "0"; } return "-1"; } static string Put(string path, JsonNode value) { if (root == null) root = new JsonObject(); if (string.IsNullOrEmpty(path)) return "-1"; int lastDot = path.LastIndexOf('.'); int lastBr = path.LastIndexOf('['); int tail = lastDot > lastBr ? lastDot : lastBr; if (tail < 0) { if (root is JsonObject o) { o[path] = value == null ? null : value.DeepClone(); return "0"; } return "-1"; } var parent = Navigate(path.Substring(0, tail)); if (parent == null) return "-1"; string key = path.Substring(tail); if (key.StartsWith(".")) key = key.Substring(1); JsonNode vv = value == null ? null : value.DeepClone(); if (key.StartsWith("[") && key.EndsWith("]")) { int idx = int.Parse(key.Substring(1, key.Length - 2)); if (parent is JsonArray a) { while (a.Count <= idx) a.Add(null); a[idx] = vv; return "0"; } return "-1"; } if (parent is JsonObject o2) { o2[key] = vv; return "0"; } return "-1"; } static JsonNode Navigate(string path) { if (root == null) return null; if (string.IsNullOrEmpty(path)) return root; var cur = root; int i = 0; while (i < path.Length) { int dot = path.IndexOf('.', i); int br = path.IndexOf('[', i); int end; if (dot < 0 && br < 0) end = path.Length; else if (dot < 0) end = br; else if (br < 0) end = dot; else end = dot < br ? dot : br; string name = path.Substring(i, end - i); if (name.Length > 0) { if (cur is JsonObject o) { cur = o[name]; if (cur == null) return null; } else return null; } if (end < path.Length && path[end] == '[') { int rb = path.IndexOf(']', end); if (rb < 0) return null; int idx = int.Parse(path.Substring(end + 1, rb - end - 1)); if (cur is JsonArray a) { if (idx < 0 || idx >= a.Count) return null; cur = a[idx]; } else return null; i = rb + 1; if (i < path.Length && path[i] == '.') i++; } else { i = end + 1; } } return cur; } } "} loadnet _cs, 3 _jsn_cs_loaded = 1 return #deffunc jsonn_parse str text, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "Parse", _r, text return int("" + _r) #defcfunc jsonn_str str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "GetStr", _r, path return "" + _r #defcfunc jsonn_int str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "GetInt", _r, path return int("" + _r) #defcfunc jsonn_dbl str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "GetDbl", _r, path return double("" + _r) #defcfunc jsonn_len str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "GetLen", _r, path return int("" + _r) #defcfunc jsonn_type str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "GetType", _r, path return int("" + _r) #defcfunc jsonn_to_string \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "ToText", _r return "" + _r #defcfunc jsonn_pretty \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "ToPretty", _r return "" + _r ;------------------------------------------------------------ ; 書き込み系 ;------------------------------------------------------------ #deffunc jsonn_new_object \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "NewObject", _r return 0 #deffunc jsonn_new_array \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "NewArray", _r return 0 #deffunc jsonn_set_str str path, str value, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "SetStr", _r, path, value return int("" + _r) #deffunc jsonn_set_int str path, int value, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "SetInt", _r, path, value return int("" + _r) #deffunc jsonn_set_dbl str path, double value, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "SetDbl", _r, path, value return int("" + _r) #deffunc jsonn_set_bool str path, int value, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "SetBool", _r, path, value return int("" + _r) #deffunc jsonn_set_null str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "SetNull", _r, path return int("" + _r) #deffunc jsonn_arr_append str path, str json_fragment, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "ArrAppend", _r, path, json_fragment return int("" + _r) #deffunc jsonn_remove str path, \ local _h, local _r _jsn_load_cs newnet _h, "HspJsonNet" mcall _h, "Remove", _r, path return int("" + _r) #global #endif