Scribunto: Allow strings and other primitive values for jsonEncode / jsonDecode [#329]

pull/620/head
gnosygnu 5 years ago
parent 8412119902
commit f1c8fb3404

@ -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)

@ -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
*/

@ -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);
}
}

Loading…
Cancel
Save