/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012 gnosygnu@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.langs.jsons; import gplx.*; import gplx.langs.*; import gplx.core.primitives.*; public class Json_doc { private final byte[][] tmp_qry_bry = new byte[1][]; public void Ctor(byte[] src, Json_grp new_root) { this.src = src; this.root_grp = new_root; switch (root_grp.Tid()) { case Json_itm_.Tid__nde: this.root_ary = null; this.root_nde = (Json_nde)root_grp; break; case Json_itm_.Tid__ary: this.root_nde = null; this.root_ary = (Json_ary)root_grp; break; default: throw Err_.new_unhandled(root_grp.Tid()); } } public byte[] Src() {return src;} private byte[] src; public Json_grp Root_grp() {return root_grp;} private Json_grp root_grp; public Json_nde Root_nde() {return root_nde;} private Json_nde root_nde; public Json_ary Root_ary() {return root_ary;} private Json_ary root_ary; public Bry_bfr Bfr() {return bfr;} private final Bry_bfr bfr = Bry_bfr_.New(); public Gfo_number_parser Utl_num_parser() {return utl_num_parser;} private final Gfo_number_parser utl_num_parser = new Gfo_number_parser(); public byte[] Tmp_u8_bry() {return tmp_u8_bry;} private final byte[] tmp_u8_bry = new byte[6]; // tmp bry[] for decoding sequences like \u0008 public byte[] Get_val_as_bry_or(byte[] qry_bry, byte[] or) {tmp_qry_bry[0] = qry_bry; return Get_val_as_bry_or(tmp_qry_bry, or);} public byte[] Get_val_as_bry_or(byte[][] qry_bry, byte[] or) { Json_itm nde = Find_nde(root_nde, qry_bry, qry_bry.length - 1, 0); return nde == null || nde.Tid() != Json_itm_.Tid__str ? or : nde.Data_bry(); } public String Get_val_as_str_or(byte[] qry_bry, String or) {tmp_qry_bry[0] = qry_bry; return Get_val_as_str_or(tmp_qry_bry, or);} public String Get_val_as_str_or(byte[][] qry_bry, String or) { Json_itm nde = Find_nde(root_nde, qry_bry, qry_bry.length - 1, 0); return nde == null || nde.Tid() != Json_itm_.Tid__str ? or : (String)nde.Data(); } public Json_grp Get_grp(byte[] qry_bry) { tmp_qry_bry[0] = qry_bry; Json_itm rv = Find_nde(root_nde, tmp_qry_bry, 0, 0); if (rv == null) return null; return (Json_grp)rv; } public Json_grp Get_grp_many(String... qry_ary) {return Get_grp_many(Bry_.Ary(qry_ary));} public Json_grp Get_grp_many(byte[]... qry_bry) { Json_itm rv = Find_nde(root_nde, qry_bry, qry_bry.length - 1, 0); if (rv == null) return null; return (Json_grp)rv; } public Json_itm Find_nde(byte[] key) { tmp_qry_bry[0] = key; return Find_nde(root_nde, tmp_qry_bry, 0, 0); } private Json_itm Find_nde(Json_nde owner, byte[][] paths, int paths_last, int paths_idx) { byte[] path = paths[paths_idx]; int subs_len = owner.Len(); for (int i = 0; i < subs_len; i++) { Json_kv itm = Json_kv.cast(owner.Get_at(i)); if (itm == null) continue; // ignore simple props, arrays, ndes if (!itm.Key_eq(path)) continue; if (paths_idx == paths_last) return itm.Val(); Json_nde sub_nde = Json_nde.cast(itm.Val()); if (sub_nde == null) return null; // match, but has not a nde; exit return Find_nde(sub_nde, paths, paths_last, paths_idx + 1); } return null; } public static String Make_str_by_apos(String... ary) {return String_.Replace(String_.Concat_lines_nl_skip_last(ary), "'", "\"");} public static String[] Make_str_ary_by_apos(String... ary) { int len = ary.length; for (int i = 0; i < len; ++i) { String itm = ary[i]; if (String_.Has(itm, "'")) ary[i] = String_.Replace(itm, "'", "\""); } return ary; } }