diff --git a/400_xowa/src/gplx/xowa/htmls/core/Xow_hdump_mgr__save.java b/400_xowa/src/gplx/xowa/htmls/core/Xow_hdump_mgr__save.java
index 3a0430063..5ef7b7616 100644
--- a/400_xowa/src/gplx/xowa/htmls/core/Xow_hdump_mgr__save.java
+++ b/400_xowa/src/gplx/xowa/htmls/core/Xow_hdump_mgr__save.java
@@ -19,7 +19,6 @@ import gplx.core.ios.*; import gplx.core.primitives.*; import gplx.xowa.wikis.da
import gplx.xowa.addons.wikis.pages.syncs.core.parsers.*;
public class Xow_hdump_mgr__save {
private final Xow_wiki wiki; private final Xoh_hzip_mgr hzip_mgr; private final Io_stream_zip_mgr zip_mgr;
- private final Xosync_hdoc_parser plain_parser = new Xosync_hdoc_parser();
private final Xoh_page tmp_hpg; private final Xoh_hzip_bfr tmp_bfr = Xoh_hzip_bfr.New_txt(32); private Bool_obj_ref html_db_is_new = Bool_obj_ref.n_();
private int dflt_zip_tid, dflt_hzip_tid;
public Xow_hdump_mgr__save(Xow_wiki wiki, Xoh_hzip_mgr hzip_mgr, Io_stream_zip_mgr zip_mgr, Xoh_page tmp_hpg) {
@@ -52,11 +51,14 @@ public class Xow_hdump_mgr__save {
private byte[] Write(Xoh_hzip_bfr bfr, Xow_wiki wiki, Xoae_page page, Xoh_page hpg, Xoh_hzip_mgr hzip_mgr, Io_stream_zip_mgr zip_mgr, int zip_tid, int hzip_tid, byte[] src) {
switch (hzip_tid) {
case Xoh_hzip_dict_.Hzip__none:
- src = plain_parser.Parse_hdoc(wiki.Domain_itm(), page.Url_bry_safe(), hpg.Hdump_mgr().Imgs(), src);
break;
case Xoh_hzip_dict_.Hzip__v1:
src = hzip_mgr.Encode_as_bry((Xoh_hzip_bfr)bfr.Clear(), wiki, hpg, src);
break;
+ // TOMBSTONE: not used; Xosync_update_mgr calls save directly; unsure if this should be restored for parallelism
+ // case Xoh_hzip_dict_.Hzip__plain:
+ // src = plain_parser.Parse_hdoc(wiki.Domain_itm(), page.Url_bry_safe(), hpg.Hdump_mgr().Imgs(), src);
+ // break;
}
src_as_hzip = src;
if (zip_tid > gplx.core.ios.streams.Io_stream_tid_.Tid__raw)
diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java
index 08cd713e6..5c6b53bd8 100644
--- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java
+++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text.java
@@ -66,6 +66,24 @@ public class Scrib_lib_text implements Scrib_lib {
public boolean JsonEncode(Scrib_proc_args args, Scrib_proc_rslt rslt) {
Object itm = args.Pull_obj(0);
+ // check if json is primitive, and return that; see NOTE below; PAGE:en.w:Template:Format_TemplateData ISSUE#:301; DATE:2019-01-13
+ int itm_type_id = Type_ids_.To_id_by_obj(itm);
+ switch (itm_type_id) {
+ case Type_ids_.Id__bool:
+ case Type_ids_.Id__byte:
+ case Type_ids_.Id__short:
+ case Type_ids_.Id__int:
+ case Type_ids_.Id__long:
+ case Type_ids_.Id__float:
+ case Type_ids_.Id__double:
+ case Type_ids_.Id__char:
+ case Type_ids_.Id__str:
+ case Type_ids_.Id__bry:
+ case Type_ids_.Id__date:
+ case Type_ids_.Id__decimal:
+ return rslt.Init_obj(itm);
+ }
+
// try to determine if node or array; EX: {a:1, b:2} vs [a:1, b:2]
Keyval[] itm_as_nde = null;
Object itm_as_ary = null;
@@ -113,6 +131,45 @@ public class Scrib_lib_text implements Scrib_lib {
public boolean JsonDecode(Scrib_proc_args args, Scrib_proc_rslt rslt) {
// init
byte[] json = args.Pull_bry(0);
+
+ // check if json is primitive, and return that; see NOTE below; PAGE:en.w:Template:Format_TemplateData ISSUE#:301; DATE:2019-01-13
+ int json_len = json.length;
+ boolean is_json_like = false;
+ boolean is_numeric = true;
+ for (int i = 0; i < json_len; i++) {
+ byte json_byte = json[i];
+ switch (json_byte) {
+ case Byte_ascii.Brack_bgn:
+ case Byte_ascii.Brack_end:
+ case Byte_ascii.Curly_bgn:
+ case Byte_ascii.Curly_end:
+ is_json_like = true;
+ is_numeric = false;
+ i = json_len;
+ break;
+ case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
+ case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
+ break;
+ default:
+ is_numeric = false;
+ break;
+ }
+ }
+ if (!is_json_like) {
+ if (is_numeric) {
+ return rslt.Init_obj(Bry_.To_int(json));
+ }
+ else {
+ if (Bry_.Eq(json, Bool_.True_bry))
+ return rslt.Init_obj(true);
+ else if (Bry_.Eq(json, Bool_.False_bry))
+ return rslt.Init_obj(false);
+ else {
+ return rslt.Init_obj(json);
+ }
+ }
+ }
+
int flags = args.Cast_int_or(1, 0);
int opts = Scrib_lib_text__json_util.Opt__force_assoc;
if (Bitmask_.Has_int(flags, Scrib_lib_text__json_util.Flag__try_fixing))
@@ -156,3 +213,16 @@ public class Scrib_lib_text implements Scrib_lib {
return String_.new_u8(msg_mgr.Val_by_key_obj(Bry_.new_u8(msg_key)));
}
}
+/*
+jsonDecode
+
+NOTE: this code is adhoc; MW calls PHP's jsonDecode
+jsonDecode has very liberal rules for decoding which seems to include
+* auto-converting bools and ints from strings
+* throwing syntax errors if text looks like JSON but is not
+
+This code emulates some of the above rules
+
+REF: http://php.net/manual/en/function.json-decode.php
+REF: https://doc.wikimedia.org/mediawiki-core/master/php/FormatJson_8php_source.html
+*/
diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java
index b99fcaa2e..7e33a7262 100644
--- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java
+++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_text_json_tst.java
@@ -14,7 +14,8 @@ GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.xtns.scribunto.libs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
-import org.junit.*; import gplx.langs.jsons.*;
+import org.junit.*; import gplx.core.tests.*;
+import gplx.langs.jsons.*;
public class Scrib_lib_text_json_tst {
private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib_text lib;
private Scrib_lib_json_fxt json_fxt = new Scrib_lib_json_fxt();
@@ -296,6 +297,12 @@ public class Scrib_lib_text_json_tst {
Tfds.Eq(kv_ary[0].Key_as_obj(), 1);
Tfds.Eq(((Keyval[])kv_ary[0].Val())[0].Key_as_obj(), 11);
}
+ @Test public void Primitives() { // NOTE: based on MW; ISSUE#:329; DATE:2019-01-13
+ json_fxt.Test_json_roundtrip_primitive(fxt, lib, "abc", "abc");
+ json_fxt.Test_json_roundtrip_primitive(fxt, lib, true, "true");
+ json_fxt.Test_json_roundtrip_primitive(fxt, lib, false, "false");
+ json_fxt.Test_json_roundtrip_primitive(fxt, lib, 123, "123");
+ }
}
class Scrib_lib_json_fxt {
private final Json_wtr wtr = new Json_wtr();
@@ -303,6 +310,12 @@ class Scrib_lib_json_fxt {
Test_json_decode(fxt, lib, Scrib_lib_text__json_util.Flag__none, json, obj);
Test_json_encode(fxt, lib, Scrib_lib_text__json_util.Flag__none, obj, json);
}
+ public void Test_json_roundtrip_primitive(Scrib_invoke_func_fxt fxt, Scrib_lib_text lib, Object obj, String expd_encoded) {
+ Object actl_encoded = fxt.Test_scrib_proc_rv_as_obj(lib, Scrib_lib_text.Invk_jsonEncode, Object_.Ary(obj, Scrib_lib_text__json_util.Flag__none));
+ Gftest.Eq__str(Object_.Xto_str_loose_or(actl_encoded, "failed"), expd_encoded);
+ Object actl_decoded = fxt.Test_scrib_proc_rv_as_obj(lib, Scrib_lib_text.Invk_jsonDecode, Object_.Ary(expd_encoded, Scrib_lib_text__json_util.Flag__none));
+ Gftest.Eq__str(Object_.Xto_str_loose_or(obj, "failed"), Object_.Xto_str_loose_or(actl_decoded, "failed"));
+ }
public Object Test_json_decode(Scrib_invoke_func_fxt fxt, Scrib_lib_text lib, int flag, String raw, Object expd) {
Object actl = fxt.Test_scrib_proc_rv_as_obj(lib, Scrib_lib_text.Invk_jsonDecode, Object_.Ary(raw, flag));
Tfds.Eq_str_lines(To_str(expd), To_str(actl), raw);
@@ -314,8 +327,11 @@ class Scrib_lib_json_fxt {
private String To_str(Object o) {
if (o == null) return "<< NULL >>";
Class> type = o.getClass();
- if (Type_.Eq(type, Keyval[].class)) return Kv_ary_utl.Ary_to_str(wtr, (Keyval[])o);
- else if (Type_.Is_array(type)) return Array_.To_str_nested_obj(o);
- else return Object_.Xto_str_strict_or_null(o);
+ if (Type_.Eq(type, Keyval[].class))
+ return Kv_ary_utl.Ary_to_str(wtr, (Keyval[])o);
+ else if (Type_.Is_array(type))
+ return Array_.To_str_nested_obj(o);
+ else
+ return Object_.Xto_str_strict_or_null(o);
}
}