mirror of
https://github.com/gnosygnu/xowa.git
synced 2025-06-13 12:54:14 +00:00
Compare commits
170 Commits
v4.6.5.191
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
2a4abd8f75 | ||
|
17a3b4e7b3 | ||
|
659bca3660 | ||
|
8684783139 | ||
|
7e53c8462d | ||
|
559503786b | ||
|
e117823e60 | ||
|
ff0f92b950 | ||
|
4187dc4a76 | ||
|
1a6a203cfd | ||
|
814e85ea70 | ||
|
0ef5058cfd | ||
|
aeef520228 | ||
|
4a7bd19056 | ||
|
7d357540c7 | ||
|
b1c52aa2b2 | ||
|
845253af79 | ||
|
541f5f6524 | ||
|
067e62dd03 | ||
|
19a315b8cd | ||
|
5c3d6a173b | ||
|
c801e3a20b | ||
|
59d8a42b22 | ||
|
567e03dc1d | ||
|
7550894dda | ||
|
caad4145d5 | ||
|
de841f8ff2 | ||
|
5f2e9c7514 | ||
|
d3896bf547 | ||
|
316c6c6a58 | ||
|
72051f4ce9 | ||
|
f19228c886 | ||
|
1b6324938c | ||
|
9b4ea48753 | ||
|
6ed7659b4d | ||
|
1eea3682ca | ||
|
4f87d1a195 | ||
|
ea9b592cfd | ||
|
3c9fd50ddc | ||
|
619d2f9844 | ||
|
bdae819908 | ||
|
f122a8d8a3 | ||
|
174e93cbfa | ||
|
0aced904a5 | ||
|
dc374fa7fc | ||
|
95e833d70c | ||
|
afed865c84 | ||
|
7b6b3ed09a | ||
|
a0c0b5b2fd | ||
|
062d308128 | ||
|
ad607d952c | ||
|
6592eaf8de | ||
|
45adc036a2 | ||
|
6b2e120fc1 | ||
|
7c0a8c5064 | ||
|
35475d631c | ||
|
efe415d3a3 | ||
|
97b1055b4e | ||
|
b51d224f09 | ||
|
b87e4d07cb | ||
|
b4516f5060 | ||
|
49e18a2255 | ||
|
026288f809 | ||
|
1103674d88 | ||
|
27756f8056 | ||
|
398a1c854a | ||
|
35f2027b20 | ||
|
be072de8d9 | ||
|
f760fd9cd0 | ||
|
3d5ec47aa8 | ||
|
53762288d7 | ||
|
7a0247417d | ||
|
0cdfa0992c | ||
|
dc66b926d3 | ||
|
8c7c9f88ff | ||
|
94b757682a | ||
|
1ebc9d3488 | ||
|
654810d56c | ||
|
b551c1875b | ||
|
ba1d4e0b7c | ||
|
a2fe75f402 | ||
|
a6331f5c89 | ||
|
43866163b9 | ||
|
49f8d4b000 | ||
|
994d405a26 | ||
|
04c499ce3e | ||
|
ebe82bea6a | ||
|
a9367eaca8 | ||
|
ee68162a4a | ||
|
6663b769d5 | ||
|
2dab6a90be | ||
|
b0e02979ac | ||
|
f9cf49c160 | ||
|
0d917bccc7 | ||
|
d1345bf724 | ||
|
3d74406a3e | ||
|
a6b128422e | ||
|
0c3cb1ba3d | ||
|
105446f5ca | ||
|
db73b4302d | ||
|
bd71db3ed6 | ||
|
a4b5f5de5d | ||
|
ecbcf1e707 | ||
|
7b00918941 | ||
|
8807dcfbeb | ||
|
a6ac592212 | ||
|
b05e3cd188 | ||
|
9c8650a4d9 | ||
|
73a56ffab3 | ||
|
e9e5724a2a | ||
|
c3c9d4ad1e | ||
|
5a35f3b05b | ||
|
7ad1291768 | ||
|
17d7a7ebed | ||
|
9809dfd6c7 | ||
|
b56673c56e | ||
|
8629292960 | ||
|
bc30fd8526 | ||
|
c47820b1a9 | ||
|
292726bd13 | ||
|
23eefef91a | ||
|
89d0ba1271 | ||
|
b2a6f7bbf1 | ||
|
ed010f76a8 | ||
|
bc65e9fa61 | ||
|
db01707032 | ||
|
7b3d6e5271 | ||
|
c3d524c493 | ||
|
f33f9c4ae9 | ||
|
02f9b9dae3 | ||
|
891cf53228 | ||
|
f73164d55e | ||
|
3355d03c44 | ||
|
bae9ba9e7a | ||
|
a5cbc4ede9 | ||
|
da87b17902 | ||
|
bfce37f0ba | ||
|
3e9bc6d93a | ||
|
775bff3bac | ||
|
bc2beba148 | ||
|
af337493af | ||
|
ca8afe657e | ||
|
57ad8e459a | ||
|
763c7b52b7 | ||
|
9cb60f2540 | ||
|
c6bca54d90 | ||
|
374de22699 | ||
|
2dee585fc1 | ||
|
898701131d | ||
|
c1b8911a7d | ||
|
f384d40e56 | ||
|
278d55cd62 | ||
|
11447820f2 | ||
|
5e2ce08abb | ||
|
5aec368f8d | ||
|
5f1d9c6f15 | ||
|
e0de779e1d | ||
|
bc5947507f | ||
|
7e2f832c33 | ||
|
357c725798 | ||
|
694c3bb133 | ||
|
3285a3c87d | ||
|
520a73537f | ||
|
9d8ab5d206 | ||
|
d49eda32a8 | ||
|
eca943d7a6 | ||
|
a7114ecb5a | ||
|
ad5613265d | ||
|
734206fbd6 | ||
|
605038d8c6 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.iml
|
||||
**/.idea/**
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -14,9 +14,10 @@ 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;
|
||||
import java.lang.*;
|
||||
import gplx.core.brys.*; import gplx.core.primitives.*; import gplx.core.ios.*;
|
||||
import gplx.langs.htmls.entitys.*;
|
||||
|
||||
import gplx.core.primitives.Int_obj_ref;
|
||||
import gplx.langs.htmls.entitys.Gfh_entity_;
|
||||
|
||||
public class Bry_ {
|
||||
public static final String Cls_val_name = "byte[]";
|
||||
public static final byte[] Empty = new byte[0];
|
||||
@ -475,6 +476,19 @@ public class Bry_ {
|
||||
else
|
||||
return Bry_.Mid(src, txt_bgn, txt_end);
|
||||
}
|
||||
public static byte[] Trim_bgn(byte[] v, byte trim, int bgn) {
|
||||
boolean trimmed = false;
|
||||
int len = v.length;
|
||||
int pos = bgn;
|
||||
for (; pos < len; pos++) {
|
||||
if (v[pos] == trim) {
|
||||
trimmed = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return trimmed ? Bry_.Mid(v, pos, len) : v;
|
||||
}
|
||||
public static byte[] Trim_end(byte[] v, byte trim, int end) {
|
||||
boolean trimmed = false;
|
||||
int pos = end - 1; // NOTE: -1 b/c callers will always be passing pos + 1; EX: src, src_len
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -14,7 +14,11 @@ 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;
|
||||
import org.junit.*; import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.tests.*;
|
||||
|
||||
import gplx.core.primitives.Int_obj_ref;
|
||||
import gplx.core.tests.Gftest;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Bry__tst {
|
||||
private final Bry__fxt fxt = new Bry__fxt();
|
||||
@Test public void new_ascii_() {
|
||||
@ -256,6 +260,12 @@ public class Bry__tst {
|
||||
void Tst_match_bwd_any(String src, int src_end, int src_bgn, String find, boolean expd) {
|
||||
Tfds.Eq(expd, Bry_.Match_bwd_any(Bry_.new_a7(src), src_end, src_bgn, Bry_.new_a7(find)));
|
||||
}
|
||||
@Test public void Trim_bgn() {
|
||||
fxt.Test_trim_bgn(" a" , Byte_ascii.Space, "a"); // trim.one
|
||||
fxt.Test_trim_bgn(" a" , Byte_ascii.Space, "a"); // trim.many
|
||||
fxt.Test_trim_bgn("a" , Byte_ascii.Space, "a"); // trim.none
|
||||
fxt.Test_trim_bgn("" , Byte_ascii.Space, ""); // empty
|
||||
}
|
||||
@Test public void Trim_end() {
|
||||
fxt.Test_trim_end("a " , Byte_ascii.Space, "a"); // trim.one
|
||||
fxt.Test_trim_end("a " , Byte_ascii.Space, "a"); // trim.many
|
||||
@ -288,6 +298,10 @@ class Bry__fxt {
|
||||
byte[] raw_bry = Bry_.new_a7(raw);
|
||||
Tfds.Eq(expd, String_.new_u8(Bry_.Trim_end(raw_bry, trim, raw_bry.length)));
|
||||
}
|
||||
public void Test_trim_bgn(String raw, byte trim, String expd) {
|
||||
byte[] raw_bry = Bry_.new_a7(raw);
|
||||
Tfds.Eq(expd, String_.new_u8(Bry_.Trim_bgn(raw_bry, trim, 0)));
|
||||
}
|
||||
public void Test_new_u8(String raw, byte[] expd) {Tfds.Eq_ary(expd, Bry_.new_u8(raw));}
|
||||
public void Test_new_a7(String raw, byte[] expd) {Tfds.Eq_ary(expd, Bry_.new_a7(raw));}
|
||||
public void Test_add(String s, byte b, String expd) {Tfds.Eq_str(expd, String_.new_u8(Bry_.Add(Bry_.new_u8(s), b)));}
|
||||
|
@ -56,13 +56,14 @@ public class Char_ {
|
||||
if (itm == match) return true;
|
||||
return false;
|
||||
}
|
||||
public static int To_int_or(char c, int or) {
|
||||
public static int To_digit_or(char c, int or) {
|
||||
switch (c) {
|
||||
case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4;
|
||||
case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9;
|
||||
default: return or;
|
||||
}
|
||||
}
|
||||
public static int To_int(char c) {return (int)c;}
|
||||
public static String To_str(char[] ary, int pos, int length) {return new String(ary, pos, length);}
|
||||
public static String To_str(int b) {return To_str((char)b);}
|
||||
public static String To_str(char c) {return String.valueOf(c);}
|
||||
|
@ -85,6 +85,9 @@ public class DateAdp implements CompareAble, Gfo_invk {
|
||||
: Timezone_offset_test
|
||||
;
|
||||
}
|
||||
public String Timezone_id() {
|
||||
return "UTC"; // under.getTimeZone().getID(); // NOTE: timezone is always UTC, unless over-ridden by tests
|
||||
}
|
||||
public DateAdp XtoUtc() {
|
||||
java.util.Date date = under.getTime();
|
||||
java.util.TimeZone tz = under.getTimeZone();
|
||||
@ -109,6 +112,7 @@ public class DateAdp implements CompareAble, Gfo_invk {
|
||||
long dst_adj = dst ? 3600000 : 0;
|
||||
return (under.getTimeInMillis() + offsetFromUTC + dst_adj) / 1000;
|
||||
}
|
||||
|
||||
public int WeekOfYear() {return under.get(Calendar.WEEK_OF_YEAR);}
|
||||
public int Frac() {return under.get(Calendar.MILLISECOND);}
|
||||
public DateAdp Add_frac(int val) {return CloneAndAdd(Calendar.MILLISECOND, val);}
|
||||
@ -147,5 +151,17 @@ public class DateAdp implements CompareAble, Gfo_invk {
|
||||
this.under = new GregorianCalendar(year, month - Month_base0adj, day, hour, minute, second);
|
||||
under.set(Calendar.MILLISECOND, frac);
|
||||
}
|
||||
protected DateAdp(int year, int month, int day, int hour, int minute, int second, int frac, TimeZone timeZone) {
|
||||
this.under = new GregorianCalendar(timeZone);
|
||||
under.set(year, month - Month_base0adj, day, hour, minute, second);
|
||||
under.set(Calendar.MILLISECOND, frac);
|
||||
}
|
||||
public void SetTzOffset(int offset) {
|
||||
java.util.Date date = under.getTime();
|
||||
long msFromEpochGmt = date.getTime();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(msFromEpochGmt - offset*1000);
|
||||
under = cal;
|
||||
}
|
||||
public static final int Month_base0adj = 1;
|
||||
}
|
||||
|
@ -66,11 +66,13 @@ public class DateAdp_ implements Gfo_invk {
|
||||
public static DateAdp dateTime_obj_(Object v) {return new DateAdp((GregorianCalendar)v);}
|
||||
public static final DateAdp_ Gfs = new DateAdp_();
|
||||
|
||||
public static int DaysInMonth(DateAdp date) {
|
||||
int rv = DaysInMonth_ary[date.Month() - Int_.Base1];
|
||||
if (rv == 28 && IsLeapYear(date.Year())) rv = 29;
|
||||
public static int DaysInMonth(DateAdp date) {return DaysInMonth(date.Month(), date.Year());}
|
||||
public static int DaysInMonth(int month, int year) {
|
||||
int rv = DaysInMonth_ary[month - Int_.Base1];
|
||||
if (rv == 28 && IsLeapYear(year)) rv = 29;
|
||||
return rv;
|
||||
} static int [] DaysInMonth_ary = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
}
|
||||
private static int [] DaysInMonth_ary = {31,28,31,30,31,30,31,31,30,31,30,31};
|
||||
public static boolean IsLeapYear(int year) {
|
||||
if (year % 4 != 0) return false;
|
||||
else if (year % 400 == 0) return true;
|
||||
@ -114,10 +116,29 @@ public class DateAdp_ implements Gfo_invk {
|
||||
c.setTimeInMillis(v);
|
||||
return new DateAdp(c);
|
||||
}
|
||||
public static final int SegIdx_year = 0, SegIdx_month = 1, SegIdx_day = 2, SegIdx_hour = 3, SegIdx_minute = 4, SegIdx_second = 5, SegIdx_frac = 6, SegIdx_dayOfWeek = 7, SegIdx_weekOfYear = 8, SegIdx_dayOfYear = 9, SegIdx__max = 10;
|
||||
public static DateAdp New_w_tz(int y, int m, int d, int h, int i, int s, int us, String tz_id) {
|
||||
TimeZone tz = String_.Eq(tz_id, "UTC") ? TIME_ZONE__UTC : TimeZone.getTimeZone(tz_id);
|
||||
return new DateAdp(y, m, d, h, i, s, us/1000, tz);
|
||||
}
|
||||
private static TimeZone TIME_ZONE__UTC = TimeZone.getTimeZone("UTC");
|
||||
public static final int
|
||||
SegIdx_year = 0, SegIdx_month = 1, SegIdx_day = 2, SegIdx_hour = 3, SegIdx_minute = 4, SegIdx_second = 5
|
||||
, SegIdx_frac = 6, SegIdx_dayOfWeek = 7, SegIdx_weekOfYear = 8, SegIdx_dayOfYear = 9, SegIdx_tz = 10, SegIdx__max = 11;
|
||||
public static String Xto_str_fmt_or(DateAdp v, String fmt, String or) {
|
||||
return v == null ? or : v.XtoStr_fmt(fmt);
|
||||
}
|
||||
public static DateAdp FirstDayofYear(int year) {
|
||||
return new DateAdp(year, 1, 1, 0, 0, 0, 0);
|
||||
}
|
||||
public static DateAdp DateByDayofYear(int year, int day) {
|
||||
return new DateAdp(year, 1, day, 0, 0, 0, 0);
|
||||
}
|
||||
public static DateAdp DateByBits(int y, int m, int d, int h, int i, int s, int us, int tz_ofs, byte[] tz_abbr) {
|
||||
DateAdp dte = new DateAdp(y, m, d, h, i, s, us/1000);
|
||||
if (tz_ofs != 0)
|
||||
dte.SetTzOffset(tz_ofs);
|
||||
return dte;
|
||||
}
|
||||
public static final String
|
||||
Fmt_iso8561_date_time = "yyyy-MM-dd HH:mm:ss"
|
||||
, Fmt__yyyyMMdd = "yyyyMMdd";
|
||||
|
@ -60,6 +60,9 @@ public class DateAdp__tst {
|
||||
@Test public void XtoUtc() {
|
||||
fxt.Test__to_utc("2012-01-01 00:00", "2012-01-01 05:00"); //4=Wed
|
||||
}
|
||||
@Test public void Timezone_id() {
|
||||
fxt.Test__timezone_id("2015-12-26T10:03:53Z", "UTC");
|
||||
}
|
||||
}
|
||||
class DateAdp__fxt {
|
||||
public void Test__parse_gplx(String raw, String expd) {
|
||||
@ -83,4 +86,7 @@ class DateAdp__fxt {
|
||||
public void Test__to_utc(String raw, String expd) {
|
||||
Tfds.Eq(expd, DateAdp_.parse_gplx(raw).XtoUtc().XtoStr_fmt_yyyy_MM_dd_HH_mm());
|
||||
}
|
||||
public void Test__timezone_id(String raw, String expd) {
|
||||
Gftest.Eq__str(expd, DateAdp_.parse_gplx(raw).XtoUtc().Timezone_id());
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
public class Decimal_adp implements CompareAble {
|
||||
public int compareTo(Object obj) {Decimal_adp comp = (Decimal_adp)obj; return under.compareTo(comp.under);}
|
||||
public Decimal_adp Floor() {return Decimal_adp_.int_(this.To_int());}
|
||||
protected Decimal_adp(BigDecimal v) {this.under = v;} private final BigDecimal under;
|
||||
protected Decimal_adp(int v) {this.under = new BigDecimal(v);}
|
||||
public Object Under() {return under;}
|
||||
@ -79,6 +80,9 @@ public class Decimal_adp implements CompareAble {
|
||||
}
|
||||
return new Decimal_adp(new_val);
|
||||
}
|
||||
public Decimal_adp Round_to_default_precision() {
|
||||
return new Decimal_adp(under.round(Decimal_adp_.Gplx_rounding_context));
|
||||
}
|
||||
public boolean Comp_gte(Decimal_adp v) {return under.doubleValue() >= v.under.doubleValue();}
|
||||
public boolean Comp_gte(int v) {return under.doubleValue() >= v;}
|
||||
public boolean Comp_lte(Decimal_adp v) {return under.doubleValue() <= v.under.doubleValue();}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2021 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -14,10 +14,15 @@ 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;
|
||||
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Decimal_adp_ {
|
||||
public static final String Cls_val_name = "decimal";
|
||||
public static final Class<?> Cls_ref_type = Decimal_adp.class;
|
||||
@ -53,17 +58,34 @@ public class Decimal_adp_ {
|
||||
return Decimal_adp_.float_(Float_.Div(dividend, divisor) * 100).To_str(fmt) + "%";
|
||||
}
|
||||
public static Decimal_adp divide_safe_(long lhs, long rhs) {return rhs == 0 ? Zero : divide_(lhs, rhs);}
|
||||
public static Decimal_adp divide_(long lhs, long rhs) {
return new Decimal_adp(new BigDecimal(lhs).divide(new BigDecimal(rhs), Gplx_rounding_context));
}
public static Decimal_adp int_(int v) {return new Decimal_adp(new BigDecimal(v));}
public static Decimal_adp long_(long v) {return new Decimal_adp(new BigDecimal(v));}
|
||||
public static Decimal_adp float_(float v) {return new Decimal_adp(new BigDecimal(v));}
public static Decimal_adp double_(double v) {return new Decimal_adp(new BigDecimal(v));}
|
||||
public static Decimal_adp divide_(long lhs, long rhs) {
|
||||
return new Decimal_adp(new BigDecimal(lhs).divide(new BigDecimal(rhs), Gplx_rounding_context));
|
||||
}
|
||||
public static Decimal_adp int_(int v) {return new Decimal_adp(new BigDecimal(v));}
|
||||
public static Decimal_adp long_(long v) {return new Decimal_adp(new BigDecimal(v));}
|
||||
public static Decimal_adp float_(float v) {return new Decimal_adp(new BigDecimal(v));}
|
||||
public static Decimal_adp double_(double v) {return new Decimal_adp(new BigDecimal(v));}
|
||||
public static Decimal_adp double_thru_str_(double v) {return new Decimal_adp(BigDecimal.valueOf(v));}
|
||||
public static Decimal_adp db_(Object v) {return new Decimal_adp((BigDecimal)v);}
public static Decimal_adp parse(String raw) {
|
||||
public static Decimal_adp db_(Object v) {return new Decimal_adp((BigDecimal)v);}
|
||||
public static Decimal_adp parse(String raw) {
|
||||
try {
|
||||
DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(Locale.US); // always parse as US format; EX:".9" should not be ",9" in german; DATE:2016-01-31
|
||||
nf.setParseBigDecimal(true);
|
||||
// 2020-08-27|ISSUE#:565|Parse 'e' as 'E'; PAGE:en.w:Huntington_Plaza
|
||||
if (raw.contains("e")) {
|
||||
raw = raw.replace("e", "E");
|
||||
}
|
||||
// 2021-02-13|ISSUE#:838|Parse '.' as '0.'; PAGE:en.w:2019_FIVB_Volleyball_Women%27s_Challenger_Cup#Pool_A
|
||||
if (raw.startsWith(".")) {
|
||||
raw = "0" + raw;
|
||||
}
|
||||
BigDecimal bd = (BigDecimal)nf.parse(raw);
|
||||
return new Decimal_adp(bd);
|
||||
} catch (ParseException e) {
|
||||
throw Err_.new_("Decimal_adp_", "parse to decimal failed", "raw", raw);
|
||||
}
|
||||
}
public static Decimal_adp pow_10_(int v) {return new Decimal_adp(new BigDecimal(1).scaleByPowerOfTen(v));}
|
||||
public static final MathContext RoundDownContext = new MathContext(0, RoundingMode.DOWN);
public static final MathContext Gplx_rounding_context = new MathContext(14, RoundingMode.HALF_UP); // changed from 28 to 14; DATE:2015-07-31
}
|
||||
}
|
||||
public static Decimal_adp pow_10_(int v) {return new Decimal_adp(new BigDecimal(1).scaleByPowerOfTen(v));}
|
||||
public static final MathContext RoundDownContext = new MathContext(0, RoundingMode.DOWN);
|
||||
public static final MathContext Gplx_rounding_context = new MathContext(14, RoundingMode.HALF_UP); // changed from 28 to 14; DATE:2015-07-31
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2021 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -14,7 +14,9 @@ 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;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
public class Decimal_adp__tst {
|
||||
private final Decimal_adp__fxt fxt = new Decimal_adp__fxt();
|
||||
@Test public void divide_() {
|
||||
@ -37,6 +39,11 @@ public class Decimal_adp__tst {
|
||||
fxt.Test_parse("1", "1");
|
||||
fxt.Test_parse("1.2", "1.2");
|
||||
fxt.Test_parse("0.1", "0.1");
|
||||
fxt.Test_parse("1.2E1", "12");
|
||||
fxt.Test_parse("1.2e1", "12"); // 2020-08-27|ISSUE#:565|Parse 'e' as 'E'; PAGE:en.w:Huntington_Plaza
|
||||
}
|
||||
@Test public void parse_dot() {
|
||||
fxt.Test_parse(".", "0"); // 2021-02-13|ISSUE#:838|Parse '.' as '0.'; PAGE:en.w:2019_FIVB_Volleyball_Women%27s_Challenger_Cup#Pool_A
|
||||
}
|
||||
@Test public void Truncate_decimal() {
|
||||
fxt.Test_truncate_decimal("1", "1");
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -14,6 +14,7 @@ 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;
|
||||
|
||||
public class Double_ {
|
||||
public static final String Cls_val_name = "double";
|
||||
public static final Class<?> Cls_ref_type = Double.class;
|
||||
@ -42,7 +43,9 @@ public class Double_ {
|
||||
int v_as_int = (int)v;
|
||||
return v == v_as_int
|
||||
? Int_.To_str(v_as_int) // convert to int, and call print String to eliminate any trailing decimal places
|
||||
: Float_.To_str((float)v); // calling ((float)v).toString is better at removing trailing 0s than String.format("%g", v). note that .net .toString() handles it better; EX:2449.600000000000d; DATE:2014-07-29
|
||||
// DATE:2014-07-29; calling ((float)v).toString is better at removing trailing 0s than String.format("%g", v). note that .net .toString() handles it better; EX:2449.600000000000d
|
||||
// DATE:2020-08-12; calling ToStrByPrintF b/c better at removing trailing 0s; ISSUE#:697;
|
||||
: gplx.objects.primitives.Double_.ToStrByPrintF(v);
|
||||
}
|
||||
public static int Compare(double lhs, double rhs) {
|
||||
if (lhs == rhs) return CompareAble_.Same;
|
||||
|
@ -16,6 +16,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
package gplx;
|
||||
import gplx.core.strings.*; import gplx.core.consoles.*; import gplx.core.brys.fmtrs.*;
|
||||
public class Gfo_usr_dlg__log_base implements Gfo_usr_dlg__log {
|
||||
private final Object thread_lock = new Object();
|
||||
private int archive_dirs_max = 8;
|
||||
private Io_url log_dir, err_fil;
|
||||
private final Ordered_hash queued_list = Ordered_hash_.New();
|
||||
@ -85,8 +86,13 @@ public class Gfo_usr_dlg__log_base implements Gfo_usr_dlg__log {
|
||||
}
|
||||
catch (Exception e) {Err_.Noop(e);} // java.lang.StringBuilder can throw exceptions in some situations when called on a different thread; ignore errors
|
||||
} private String_bldr sb = String_bldr_.new_thread(); // NOTE: use java.lang.StringBuffer to try to avoid random exceptions when called on a different thread
|
||||
private String Bld_msg(String s) {return sb.Add(Datetime_now.Get_force().XtoUtc().XtoStr_fmt_yyyyMMdd_HHmmss_fff()).Add(" ").Add(s).Add_char_nl().To_str_and_clear();}
|
||||
private String Bld_msg(String s) {
|
||||
synchronized (thread_lock) { // THREAD:synchronized neded b/c multiple threads can still mutate the same sb; ISSUE#:646; DATE:2020-03-16
|
||||
return sb.Add(Datetime_now.Get_force().XtoUtc().XtoStr_fmt_yyyyMMdd_HHmmss_fff()).Add(" ").Add(s).Add_char_nl().To_str_and_clear();
|
||||
}
|
||||
}
|
||||
private void Log_msg(Io_url url, String txt) {
|
||||
synchronized (thread_lock) { // THREAD:synchronized neded b/c queued_list can be accessible by multiple threads; ISSUE#:646; DATE:2020-01-09
|
||||
if (queue_enabled) {
|
||||
String url_raw = url == null ? "mem" : url.Raw();
|
||||
Usr_log_fil fil = (Usr_log_fil)queued_list.Get_by(url_raw);
|
||||
@ -101,6 +107,7 @@ public class Gfo_usr_dlg__log_base implements Gfo_usr_dlg__log {
|
||||
Io_mgr.Instance.AppendFilStr(url, txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, "enabled_")) enabled = m.ReadYn("v");
|
||||
else if (ctx.Match(k, "archive_dirs_max_")) archive_dirs_max = m.ReadInt("v");
|
||||
|
@ -21,6 +21,7 @@ public interface Hash_adp extends gplx.core.lists.EnumerAble {
|
||||
Object Get_by_or_fail(Object key);
|
||||
void Add(Object key, Object val);
|
||||
Hash_adp Add_and_more(Object key, Object val);
|
||||
Hash_adp Add_many_as_key_and_val(Object... ary);
|
||||
void Add_as_key_and_val(Object val);
|
||||
boolean Add_if_dupe_use_1st(Object key, Object val);
|
||||
void Add_if_dupe_use_nth(Object key, Object val);
|
||||
|
@ -27,6 +27,7 @@ class Hash_adp_noop implements Hash_adp {
|
||||
public Object Get_by_or_fail(Object key) {throw Err_.new_missing_key(Object_.Xto_str_strict_or_null_mark(key));}
|
||||
public void Add(Object key, Object val) {}
|
||||
public Hash_adp Add_and_more(Object key, Object val) {return this;}
|
||||
public Hash_adp Add_many_as_key_and_val(Object... ary) {return this;}
|
||||
public void Add_as_key_and_val(Object val) {}
|
||||
public void Add_if_dupe_use_nth(Object key, Object val) {}
|
||||
public boolean Add_if_dupe_use_1st(Object key, Object val) {return false;}
|
||||
|
@ -28,6 +28,7 @@ public class Int_ {
|
||||
, Null = Int_.Min_value
|
||||
, Base1 = 1 // for super 1 lists / arrays; EX: PHP; [a, b, c]; [1] => a
|
||||
, Offset_1 = 1 // common symbol for + 1 after current pos; EX: String_.Mid(lhs + Offset_1, rhs)
|
||||
, Zero = 0
|
||||
;
|
||||
|
||||
public static int Cast(Object obj) {
|
||||
|
@ -24,7 +24,9 @@ public class Io_url__tst {
|
||||
class Io_url__fxt {
|
||||
public void Clear() {Io_mgr.Instance.InitEngine_mem();}
|
||||
public void Test__New__http_or_null(boolean os_is_wnt, String raw, String expd) {
|
||||
int curTid = Op_sys.Cur().Tid();
|
||||
Op_sys.Cur_(os_is_wnt ? Op_sys.Tid_wnt : Op_sys.Tid_lnx);
|
||||
Gftest.Eq__obj_or_null(expd, Io_url_.New__http_or_null(raw));
|
||||
Op_sys.Cur_(curTid);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class Long_ {
|
||||
if (raw == null || rawLen == 0) return or;
|
||||
long rv = 0, factor = 1; int tmp = 0;
|
||||
for (int i = rawLen; i > 0; i--) {
|
||||
tmp = Char_.To_int_or(String_.CharAt(raw, i - 1), Int_.Min_value);
|
||||
tmp = Char_.To_digit_or(String_.CharAt(raw, i - 1), Int_.Min_value);
|
||||
if (tmp == Int_.Min_value) return or;
|
||||
rv += (tmp * factor);
|
||||
factor *= 10;
|
||||
|
@ -16,6 +16,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
package gplx;
|
||||
public class Math_ {
|
||||
public static double Pow(double val, double exponent) {return java.lang.Math.pow(val, exponent);}
|
||||
public static int Pow_int(int val, int exponent) {return (int)java.lang.Math.pow(val, exponent);}
|
||||
public static double Pi = java.lang.Math.PI;
|
||||
public static double E = java.lang.Math.E;
|
||||
public static int Ceil_as_int(double v) {return (int)Ceil(v);}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -14,6 +14,7 @@ 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;
|
||||
|
||||
public class Type_ {//RF:2017-10-08
|
||||
public static Class<?> Type_by_obj(Object o) {return o.getClass();}
|
||||
public static Class<?> Type_by_primitive(Object o) {
|
||||
@ -45,6 +46,11 @@ public class Type_ {//RF:2017-10-08
|
||||
return type.getName();
|
||||
}
|
||||
|
||||
public static String SimpleName_by_obj(Object obj) {return obj == null ? String_.Null_mark : SimpleName(Type_by_obj(obj));}
|
||||
public static String SimpleName(Class<?> type) {
|
||||
return type.getSimpleName();
|
||||
}
|
||||
|
||||
public static boolean Is_array(Class<?> t) {
|
||||
return t.isArray();
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ public class Bitmask_ {
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static int Set_or_add(int val, int flag) {
|
||||
return val == 0 ? flag : val | flag;
|
||||
}
|
||||
public static boolean Has_byte(byte val, byte find) {return find == (val & find);}
|
||||
public static byte Add_byte(byte flag, byte itm) {return (byte)(flag | itm);}
|
||||
}
|
||||
|
@ -20,6 +20,11 @@ public abstract class Hash_adp_base implements Hash_adp {
|
||||
public Object Get_by_or_fail(Object key) {return Get_by_or_fail_base(key);}
|
||||
public void Add(Object key, Object val) {Add_base(key, val);}
|
||||
public Hash_adp Add_and_more(Object key, Object val) {Add_base(key, val); return this;}
|
||||
public Hash_adp Add_many_as_key_and_val(Object... ary) {
|
||||
for (Object itm : ary)
|
||||
Add_base(itm, itm);
|
||||
return this;
|
||||
}
|
||||
public void Add_as_key_and_val(Object val) {Add_base(val, val);}
|
||||
public void Add_if_dupe_use_nth(Object key, Object val) {
|
||||
Object existing = Fetch_base(key); if (existing != null) Del(key); // overwrite if exists
|
||||
|
@ -22,6 +22,11 @@ public class Sorted_hash implements Hash_adp {
|
||||
public Object Get_by_or_fail(Object key) {return Get_by_or_fail_base(key);}
|
||||
public void Add(Object key, Object val) {Add_base(key, val);}
|
||||
public Hash_adp Add_and_more(Object key, Object val) {Add_base(key, val); return this;}
|
||||
public Hash_adp Add_many_as_key_and_val(Object... ary) {
|
||||
for (Object itm : ary)
|
||||
Add_base(itm, itm);
|
||||
return this;
|
||||
}
|
||||
public void Add_as_key_and_val(Object val) {Add_base(val, val);}
|
||||
public void Add_if_dupe_use_nth(Object key, Object val) {
|
||||
Object existing = Fetch_base(key); if (existing != null) Del(key); // overwrite if exists
|
||||
|
25
100_core/src/gplx/core/primitives/ObjectWrapperRef.java
Normal file
25
100_core/src/gplx/core/primitives/ObjectWrapperRef.java
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.core.primitives;
|
||||
|
||||
import gplx.Object_;
|
||||
|
||||
public class ObjectWrapperRef {
|
||||
public ObjectWrapperRef() {}
|
||||
public Object Val() {return val;} public ObjectWrapperRef Val_(Object v) {val = v; return this;} private Object val;
|
||||
public ObjectWrapperRef Val_null_() {return Val_(null);}
|
||||
@Override public String toString() {return Object_.Xto_str_strict_or_null(val);}
|
||||
}
|
@ -37,7 +37,9 @@ public interface String_bldr {
|
||||
String_bldr Add(char c);
|
||||
String_bldr Add(int i);
|
||||
String_bldr Add_obj(Object o);
|
||||
String_bldr Add_mid(char[] ary, int bgn, int count);
|
||||
String_bldr Add_mid(String str, int bgn, int end);
|
||||
String_bldr Add_mid_len(char[] ary, int bgn, int count);
|
||||
String_bldr Add_mid_len(String str, int bgn, int count);
|
||||
String_bldr Add_at(int idx, String s);
|
||||
String_bldr Del(int bgn, int len);
|
||||
}
|
||||
@ -82,7 +84,9 @@ abstract class String_bldr_base implements String_bldr {
|
||||
public abstract String_bldr Add(String s);
|
||||
public abstract String_bldr Add(char c);
|
||||
public abstract String_bldr Add(int i);
|
||||
public abstract String_bldr Add_mid(char[] ary, int bgn, int count);
|
||||
public abstract String_bldr Add_mid(String str, int bgn, int end);
|
||||
public abstract String_bldr Add_mid_len(char[] ary, int bgn, int count);
|
||||
public abstract String_bldr Add_mid_len(String str, int bgn, int count);
|
||||
public abstract String_bldr Add_obj(Object o);
|
||||
public abstract String_bldr Del(int bgn, int len);
|
||||
}
|
||||
@ -95,7 +99,9 @@ class String_bldr_thread_single extends String_bldr_base {
|
||||
@Override public String_bldr Add(String s) {sb.append(s); return this;}
|
||||
@Override public String_bldr Add(char c) {sb.append(c); return this;}
|
||||
@Override public String_bldr Add(int i) {sb.append(i); return this;}
|
||||
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
|
||||
@Override public String_bldr Add_mid(String str, int bgn, int end) {sb.append(str, bgn, end); return this;}
|
||||
@Override public String_bldr Add_mid_len(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
|
||||
@Override public String_bldr Add_mid_len(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
|
||||
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
|
||||
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
|
||||
}
|
||||
@ -108,7 +114,9 @@ class String_bldr_thread_multiple extends String_bldr_base {
|
||||
@Override public String_bldr Add(String s) {sb.append(s); return this;}
|
||||
@Override public String_bldr Add(char c) {sb.append(c); return this;}
|
||||
@Override public String_bldr Add(int i) {sb.append(i); return this;}
|
||||
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
|
||||
@Override public String_bldr Add_mid(String str, int bgn, int end) {sb.append(str, bgn, end); return this;}
|
||||
@Override public String_bldr Add_mid_len(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
|
||||
@Override public String_bldr Add_mid_len(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
|
||||
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
|
||||
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
|
||||
}
|
||||
|
17
100_core/src/gplx/core/tests/GfoTestMethod.java
Normal file
17
100_core/src/gplx/core/tests/GfoTestMethod.java
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.core.tests;
|
||||
public @interface GfoTestMethod {}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -112,6 +112,7 @@ public class Gftest {
|
||||
bfr.Add(Bry__line_end);
|
||||
throw Err_.new_wo_type(bfr.To_str_and_clear());
|
||||
}
|
||||
public static void Eq__bool_n(boolean actl) {Eq__bool(Bool_.N, actl, null);}
|
||||
public static void Eq__bool_y(boolean actl) {Eq__bool(Bool_.Y, actl, null);}
|
||||
public static void Eq__bool_y(boolean actl, String msg_fmt, Object... msg_args) {Eq__bool(Bool_.Y, actl, msg_fmt, msg_args);}
|
||||
public static void Eq__bool(boolean expd, boolean actl) {Eq__bool(expd, actl, null);}
|
||||
|
@ -22,6 +22,11 @@ public class Base64Converter {
|
||||
for(int i=0; i< ALPHABET.length; i++){
|
||||
toInt[ALPHABET[i]]= i;
|
||||
}
|
||||
}
|
||||
public static char GetIndexChar(int i) {return ALPHABET[i];}
|
||||
public static int GetIndexInt(char c) {
|
||||
if (toInt == null) Init();
|
||||
return toInt[c];
|
||||
}
|
||||
public static String EncodeString(String orig) {return Encode(Bry_.new_u8(orig));}
|
||||
public static String Encode(byte[] buf){
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,17 @@ The terms of each license can be found in the source code repository:
|
||||
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.core.threads; import gplx.*; import gplx.core.*;
|
||||
import java.lang.*;
|
||||
package gplx.core.threads;
|
||||
|
||||
import gplx.Cancelable;
|
||||
import gplx.Cancelable_;
|
||||
import gplx.Err_;
|
||||
import gplx.GfoMsg;
|
||||
import gplx.GfoMsg_;
|
||||
import gplx.Gfo_invk;
|
||||
import gplx.Gfo_invk_;
|
||||
import gplx.Gfo_log_;
|
||||
|
||||
public class Thread_adp implements Runnable {
|
||||
private final String thread_name; private final Cancelable cxl; private final boolean cxlable;
|
||||
private final Gfo_invk invk_itm; private final String invk_cmd; private final GfoMsg invk_msg;
|
||||
@ -28,6 +37,7 @@ public class Thread_adp implements Runnable {
|
||||
public boolean Thread__cancelable() {return cxlable;}
|
||||
public boolean Thread__is_alive() {return thread == null ? false : thread.isAlive();}
|
||||
public void Thread__interrupt() {thread.interrupt();}
|
||||
public void Thread__stop() {thread.stop();}
|
||||
public void run() {
|
||||
try {
|
||||
Gfo_invk_.Invk_by_msg(invk_itm, invk_cmd, invk_msg);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,7 +13,15 @@ The terms of each license can be found in the source code repository:
|
||||
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.core.threads; import gplx.*; import gplx.core.*;
|
||||
package gplx.core.threads;
|
||||
|
||||
import gplx.Cancelable;
|
||||
import gplx.Cancelable_;
|
||||
import gplx.Err_;
|
||||
import gplx.GfoMsg;
|
||||
import gplx.GfoMsg_;
|
||||
import gplx.Gfo_invk;
|
||||
|
||||
public class Thread_adp_ {
|
||||
public static void Sleep(int milliseconds) {
|
||||
try {
|
||||
|
78
100_core/src/gplx/core/tooling/asserts/TestAssert.java
Normal file
78
100_core/src/gplx/core/tooling/asserts/TestAssert.java
Normal file
@ -0,0 +1,78 @@
|
||||
package gplx.core.tooling.asserts;
|
||||
|
||||
import gplx.core.tests.Gftest;
|
||||
import gplx.core.tooling.dataCollectors.GfoDataCollectorGrp;
|
||||
import gplx.core.tooling.dataCollectors.GfoDataCollectorMgr;
|
||||
import gplx.langs.java.util.List_;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TestAssert {
|
||||
void Test(GfoDataCollectorGrp actlItm);
|
||||
void NotePrepend(String s);
|
||||
static void Test(String note, GfoDataCollectorMgr mgr, TestAssert.Grp[] itms) {
|
||||
for (TestAssert.Grp itm : itms) {
|
||||
itm.NotePrepend(note);
|
||||
itm.Test(mgr.GetGrp(itm.Key()));
|
||||
}
|
||||
}
|
||||
class Grp implements TestAssert {
|
||||
private String key;
|
||||
private TestAssert[] rules;
|
||||
public Grp(String key, TestAssert... rules) {
|
||||
this.key = key;
|
||||
this.rules = rules;
|
||||
}
|
||||
public String Key() {return key;}
|
||||
public void NotePrepend(String s) {
|
||||
note = s;
|
||||
for (TestAssert rule : rules) {
|
||||
rule.NotePrepend(s);
|
||||
}
|
||||
} private String note;
|
||||
public void Test(GfoDataCollectorGrp grp) {
|
||||
for (TestAssert rule : rules) {
|
||||
rule.Test(grp);
|
||||
}
|
||||
}
|
||||
}
|
||||
class StringEq implements TestAssert {
|
||||
private String key;
|
||||
private String expdVal;
|
||||
public StringEq(String key, String expd) {
|
||||
this.key = key;
|
||||
this.expdVal = expd;
|
||||
}
|
||||
public void NotePrepend(String s) {note = s + "." + key;} private String note;
|
||||
public void Test(GfoDataCollectorGrp grp) {
|
||||
String actlVal = (String)grp.Get(key);
|
||||
Gftest.Eq__str(expdVal, actlVal, note);
|
||||
}
|
||||
}
|
||||
class StringHas implements TestAssert {
|
||||
private String key;
|
||||
private String expdVal;
|
||||
public StringHas(String key, String expd) {
|
||||
this.key = key;
|
||||
this.expdVal = expd;
|
||||
}
|
||||
public void NotePrepend(String s) {note = s + "." + key;} private String note;
|
||||
public void Test(GfoDataCollectorGrp grp) {
|
||||
String actlVal = (String)grp.Get(key);
|
||||
Gftest.Eq__bool_y(actlVal.contains(expdVal), note);
|
||||
}
|
||||
}
|
||||
class ListEq implements TestAssert {
|
||||
private String key;
|
||||
private List<?> expdList;
|
||||
public ListEq(String key, Object... expd) {
|
||||
this.key = key;
|
||||
this.expdList = List_.NewByAry(expd);
|
||||
}
|
||||
public void NotePrepend(String s) {note = s + "." + key;} private String note;
|
||||
public void Test(GfoDataCollectorGrp grp) {
|
||||
List<?> actlList = (List<?>)grp.Get(key);
|
||||
Gftest.Eq__ary(expdList.toArray(), actlList.toArray(), note);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package gplx.core.tooling.dataCollectors;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class GfoDataCollectorGrp {
|
||||
private final String key;
|
||||
private final LinkedHashMap<String, Object> hash = new LinkedHashMap<>();
|
||||
public GfoDataCollectorGrp(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
public String Key() {return key;}
|
||||
public GfoDataCollectorGrp Add(String dataKey, String dataVal) {
|
||||
hash.put(dataKey, dataVal);
|
||||
return this;
|
||||
}
|
||||
public GfoDataCollectorGrp Add(String dataKey, List<?> dataVal) {
|
||||
hash.put(dataKey, dataVal);
|
||||
return this;
|
||||
}
|
||||
public Object Get(String dataKey) {
|
||||
return hash.get(dataKey);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package gplx.core.tooling.dataCollectors;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class GfoDataCollectorMgr {
|
||||
private final LinkedHashMap<String, GfoDataCollectorGrp> hash = new LinkedHashMap<>();
|
||||
public GfoDataCollectorGrp GetGrp(String grpKey) {return hash.get(grpKey);}
|
||||
public GfoDataCollectorGrp AddGrp(String grpKey) {
|
||||
GfoDataCollectorGrp grp = new GfoDataCollectorGrp(grpKey);
|
||||
hash.put(grpKey, grp);
|
||||
return grp;
|
||||
}
|
||||
}
|
13
100_core/src/gplx/langs/java/util/List_.java
Normal file
13
100_core/src/gplx/langs/java/util/List_.java
Normal file
@ -0,0 +1,13 @@
|
||||
package gplx.langs.java.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class List_ {
|
||||
public static List<Object> NewByAry(Object[] ary) {
|
||||
List<Object> rv = new ArrayList<>();
|
||||
for (Object o : ary)
|
||||
rv.add(o);
|
||||
return rv;
|
||||
}
|
||||
}
|
@ -17,7 +17,10 @@ package gplx.langs.regxs; import gplx.*; import gplx.langs.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
public class Regx_adp {
|
||||
@gplx.Internal protected Regx_adp(String regx) {Pattern_(regx);}
|
||||
public Regx_adp(String regx, int flags) {
|
||||
this.flags = flags;
|
||||
Pattern_(regx);
|
||||
}
|
||||
public String Pattern() {return pattern;} public Regx_adp Pattern_(String val) {pattern = val; Under_sync(); return this;} private String pattern;
|
||||
public boolean Pattern_is_invalid() {return pattern_is_invalid;} private boolean pattern_is_invalid = false;
|
||||
public Exception Pattern_is_invalid_exception() {return pattern_is_invalid_exception;} private Exception pattern_is_invalid_exception = null;
|
||||
@ -38,14 +41,15 @@ public class Regx_adp {
|
||||
}
|
||||
return (Regx_match[])rv.To_ary(Regx_match.class);
|
||||
}
|
||||
private int flags = FLAG__DOTALL | FLAG__UNICODE_CHARACTER_CLASS;// JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
|
||||
private Pattern under;
|
||||
public Pattern Under() {return under;}
|
||||
private void Under_sync() {
|
||||
try {under = Pattern.compile(pattern, Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);} // JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
|
||||
try {under = Pattern.compile(pattern, flags);}
|
||||
catch (Exception e) { // NOTE: if invalid, then default to empty pattern (which should return nothing); EX:d:〆る generates [^]; DATE:2013-10-20
|
||||
pattern_is_invalid = true;
|
||||
pattern_is_invalid_exception = e;
|
||||
under = Pattern.compile("", Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);
|
||||
under = Pattern.compile("", flags);
|
||||
}
|
||||
}
|
||||
public Regx_match Match(String input, int bgn) {
|
||||
@ -56,11 +60,29 @@ public class Regx_adp {
|
||||
Regx_group[] ary = Regx_group.Ary_empty;
|
||||
int groups_len = match.groupCount();
|
||||
if (success && groups_len > 0) {
|
||||
// NOTE: by convention, there are n groups, but groups.count is n - 1 and groups[0] is entire match (not 1st group); see TEST: DATE:2019-12-28
|
||||
groups_len++;
|
||||
ary = new Regx_group[groups_len];
|
||||
for (int i = 0; i < groups_len; i++)
|
||||
ary[i] = new Regx_group(true, match.start(i + 1), match.end(i + 1), match.group(i + 1));
|
||||
for (int i = 0; i < groups_len; i++) {
|
||||
int match_start = match.start(i);
|
||||
ary[i] = new Regx_group(match_start != -1, match_start, match.end(i), match.group(i));
|
||||
}
|
||||
}
|
||||
return new Regx_match(success, match_bgn, match_end, ary);
|
||||
}
|
||||
public String ReplaceAll(String input, String replace) {return under.matcher(input).replaceAll(replace);}
|
||||
// https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
|
||||
public static final int
|
||||
FLAG__NONE = 0
|
||||
, FLAG__UNIX_LINES = Pattern.UNIX_LINES
|
||||
, FLAG__CASE_INSENSITIVE = Pattern.CASE_INSENSITIVE
|
||||
, FLAG__COMMENTS = Pattern.COMMENTS
|
||||
, FLAG__MULTILINE = Pattern.MULTILINE
|
||||
, FLAG__LITERAL = Pattern.LITERAL
|
||||
, FLAG__DOTALL = Pattern.DOTALL
|
||||
, FLAG__UNICODE_CASE = Pattern.UNICODE_CASE
|
||||
, FLAG__CANON_EQ = Pattern.CANON_EQ
|
||||
, FLAG__UNICODE_CHARACTER_CLASS = Pattern.UNICODE_CHARACTER_CLASS
|
||||
;
|
||||
public static final int FLAG__DEFAULT = FLAG__DOTALL | FLAG__UNICODE_CHARACTER_CLASS;// JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.langs.regxs; import gplx.*; import gplx.langs.*;
|
||||
public class Regx_adp_ {
|
||||
public static Regx_adp new_(String pattern) {return new Regx_adp(pattern);}
|
||||
public static Regx_adp new_(String pattern) {return new Regx_adp(pattern, Regx_adp.FLAG__DEFAULT);}
|
||||
public static List_adp Find_all(String src, String pat) {
|
||||
int src_len = String_.Len(src);
|
||||
Regx_adp regx = Regx_adp_.new_(pat);
|
||||
@ -34,7 +34,7 @@ public class Regx_adp_ {
|
||||
return regx.ReplaceAll(raw, replace);
|
||||
}
|
||||
public static boolean Match(String input, String pattern) {
|
||||
Regx_adp rv = new Regx_adp(pattern);
|
||||
Regx_adp rv = new Regx_adp(pattern, Regx_adp.FLAG__DEFAULT);
|
||||
return rv.Match(input, 0).Rslt();
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,9 @@ public class Regx_adp__tst implements TfdsEqListItmStr {
|
||||
tst_Matches("b", "a b c b a b b", matches_(2, 6, 10, 12)); // BUGFIX: multiple entries did not work b/c of += instead of +
|
||||
}
|
||||
@Test public void Groups() {
|
||||
tst_Groups("abc def ghi dz", "(d\\p{L}+)", "def", "dz");
|
||||
tst_Groups("abc def ghi dz", "(d\\p{L}+)", "def", "def", "dz", "dz");
|
||||
tst_Groups("abc def", "(de)(g?)", "de", "de", ""); // NOTE: (g?) doesn't capture anything, but still add a group for it; DATE:2019-12-28
|
||||
tst_Groups("-123.456", "^-?(([0-9]+)(?:\\.([0-9]+))?)", "-123.456", "123.456", "123", "456"); // NOTE: -123.456 captured even though it's not part of a group; DATE:2019-12-28
|
||||
}
|
||||
Regx_match[] matches_(int... bgnAry) {
|
||||
int aryLen = Array_.Len(bgnAry);
|
||||
|
@ -26,6 +26,7 @@ public class Regx_match {
|
||||
public int Find_bgn() {return find_bgn;} private final int find_bgn;
|
||||
public int Find_end() {return find_end;} private final int find_end;
|
||||
public int Find_len() {return find_end - find_bgn;}
|
||||
public String Find_str(String s) {return String_.Mid(s, find_bgn, find_end);}
|
||||
public Regx_group[] Groups() {return groups;} private final Regx_group[] groups;
|
||||
|
||||
public static final Regx_match[] Ary_empty = new Regx_match[0];
|
||||
|
@ -22,6 +22,11 @@ public class XmlAtrList {
|
||||
Node xatr = list.getNamedItem(key);
|
||||
return (xatr == null) ? or : xatr.getNodeValue();
|
||||
}
|
||||
public XmlAtr Get_by(String key) {
|
||||
Node xatr = list.getNamedItem(key);
|
||||
if (xatr == null) throw Err_.new_missing_key(key);
|
||||
return new XmlAtr(xatr);
|
||||
}
|
||||
public XmlAtr Fetch(String key) {
|
||||
Node xatr = list.getNamedItem(key); if (xatr == null) throw Err_.new_missing_key(key);
|
||||
return new XmlAtr(xatr);
|
||||
|
@ -29,15 +29,45 @@ import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
public class XmlDoc_ {
|
||||
public static XmlNdeList Select_tags(XmlNde cur, String tag) {
|
||||
XmlNdeList_cls_list rv = new XmlNdeList_cls_list(4); // NOTE: pass in an initial amount; do not pass 0
|
||||
Select_tags(rv, cur, tag);
|
||||
return rv;
|
||||
}
|
||||
private static void Select_tags(XmlNdeList_cls_list rv, XmlNde cur, String tag) {
|
||||
if (String_.Eq(cur.Name(), tag)) {
|
||||
rv.Add(cur);
|
||||
}
|
||||
XmlNdeList sub_ndes = cur.SubNdes();
|
||||
int sub_ndes_len = sub_ndes.Count();
|
||||
for (int i = 0; i < sub_ndes_len; i++) {
|
||||
XmlNde sub_nde = sub_ndes.Get_at(i);
|
||||
Select_tags(rv, sub_nde, tag);
|
||||
}
|
||||
}
|
||||
public static XmlDoc parse(String raw) {return new XmlDoc(doc_(raw));}
|
||||
static Document doc_(String raw) {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder bldr = null;
|
||||
try {bldr = factory.newDocumentBuilder();}
|
||||
catch (ParserConfigurationException e) {throw Err_.new_exc(e, "xml", "failed to create newDocumentBuilder");}
|
||||
try {
|
||||
// NOTE: disable DTD validation else errors for "ldmlSupplemental.dtd" in plurals.xml; DATE:2020-01-01
|
||||
// REF:https://stackoverflow.com/questions/24744175/non-validating-documentbuilder-trying-to-read-dtd-file
|
||||
// REF:https://stackoverflow.com/questions/6204827/xml-parsing-too-slow
|
||||
factory.setNamespaceAware(false);
|
||||
factory.setValidating(false);
|
||||
factory.setFeature("http://xml.org/sax/features/namespaces", false);
|
||||
factory.setFeature("http://xml.org/sax/features/validation", false);
|
||||
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
|
||||
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
bldr = factory.newDocumentBuilder();
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
throw Err_.new_exc(e, "xml", "failed to create newDocumentBuilder");
|
||||
}
|
||||
StringReader reader = new StringReader(raw);
|
||||
InputSource source = new InputSource(reader);
|
||||
Document doc = null;
|
||||
@ -47,5 +77,4 @@ public class XmlDoc_ {
|
||||
return doc;
|
||||
}
|
||||
public static final String Err_XmlException = "gplx.xmls.XmlException";
|
||||
}
|
||||
//#}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class GfmlLxr_group implements GfmlLxr {
|
||||
public GfmlTkn MakeTkn(CharStream stream, int hookLength) {
|
||||
while (stream.AtMid()) {
|
||||
if (!ignoreOutput)
|
||||
sb.Add_mid(stream.Ary(), stream.Pos(), hookLength);
|
||||
sb.Add_mid_len(stream.Ary(), stream.Pos(), hookLength);
|
||||
stream.MoveNextBy(hookLength);
|
||||
|
||||
String found = String_.cast(trie.FindMatch(stream));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,19 +13,49 @@ The terms of each license can be found in the source code repository:
|
||||
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.dbs; import gplx.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.engines.*; import gplx.dbs.qrys.*; import gplx.dbs.sys.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
|
||||
package gplx.dbs;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Double_;
|
||||
import gplx.Err_;
|
||||
import gplx.Gfo_log_;
|
||||
import gplx.Gfo_usr_dlg;
|
||||
import gplx.Gfo_usr_dlg_;
|
||||
import gplx.Int_;
|
||||
import gplx.Io_url;
|
||||
import gplx.List_adp;
|
||||
import gplx.List_adp_;
|
||||
import gplx.Rls_able;
|
||||
import gplx.String_;
|
||||
import gplx.core.stores.DataRdr;
|
||||
import gplx.core.stores.DataRdr_;
|
||||
import gplx.dbs.conn_props.Db_conn_props_mgr;
|
||||
import gplx.dbs.engines.Db_engine;
|
||||
import gplx.dbs.metas.Dbmeta_idx_fld;
|
||||
import gplx.dbs.metas.Dbmeta_tbl_mgr;
|
||||
import gplx.dbs.qrys.Db_qry__select_in_tbl;
|
||||
import gplx.dbs.qrys.Db_qry_delete;
|
||||
import gplx.dbs.qrys.Db_qry_insert;
|
||||
import gplx.dbs.qrys.Db_qry_sql;
|
||||
import gplx.dbs.qrys.Db_qry_update;
|
||||
import gplx.dbs.qrys.bats.Db_batch_mgr;
|
||||
import gplx.dbs.sys.Db_sys_mgr;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
public class Db_conn {
|
||||
private final List_adp rls_list = List_adp_.New();
|
||||
public Db_conn(Db_engine engine) {
|
||||
this.engine = engine;
|
||||
this.sys_mgr = new Db_sys_mgr(this);
|
||||
this.wkrMgr = new SqlWkrMgr(this);
|
||||
engine.CtorConn(wkrMgr);
|
||||
}
|
||||
public Db_conn_info Conn_info() {return engine.Conn_info();}
|
||||
public Db_conn_props_mgr Props() {return engine.Props();}
|
||||
public Db_batch_mgr Batch_mgr() {return engine.Batch_mgr();}
|
||||
public Db_engine Engine() {return engine;} private final Db_engine engine;
|
||||
public Db_sys_mgr Sys_mgr() {return sys_mgr;} private final Db_sys_mgr sys_mgr; // autonum and other functions
|
||||
public SqlWkrMgr WkrMgr() {return wkrMgr;} private final SqlWkrMgr wkrMgr;
|
||||
public boolean Eq(Db_conn comp) {return String_.Eq(engine.Conn_info().Db_api(), comp.Conn_info().Db_api());}
|
||||
public void Txn_bgn(String name) {engine.Txn_bgn(name);}
|
||||
public void Txn_end() {engine.Txn_end();}
|
||||
|
@ -28,6 +28,7 @@ public class Db_crt_ {
|
||||
public static Criteria_fld New_between (String key, Comparable lo, Comparable hi) {return Criteria_fld.new_(key, Criteria_.between_(lo, hi));}
|
||||
public static Criteria_fld New_in (String key, Object... vals) {return Criteria_fld.new_(key, Criteria_.in_(vals));}
|
||||
public static Criteria_fld New_like (String key, String pattern) {return Criteria_fld.new_(key, Criteria_.like_(pattern));}
|
||||
public static Criteria_fld New_like_not (String key, String pattern) {return Criteria_fld.new_(key, Criteria_.Not(Criteria_.like_(pattern)));}
|
||||
|
||||
public static Criteria eq_many_(String... ary) {
|
||||
Criteria rv = null;
|
||||
|
@ -29,6 +29,7 @@ public class Dbmeta_fld_list {
|
||||
public String Add_int_pkey_autonum(String name) {return Add(Dbmeta_fld_itm.new_int(name).Primary_y_().Autonum_y_());}
|
||||
public String Add_int_autonum(String name) {return Add(Dbmeta_fld_itm.new_int(name).Autonum_y_());}
|
||||
public String Add_int_dflt(String name, int dflt) {return Add(Dbmeta_fld_itm.new_int(name).Default_(dflt));}
|
||||
public String Add_int_null(String name) {return Add(Dbmeta_fld_itm.new_int(name).Nullable_y_());}
|
||||
public String Add_long(String name) {return Add(Dbmeta_fld_itm.new_long(name));}
|
||||
public String Add_float(String name) {return Add(Dbmeta_fld_itm.new_float(name));}
|
||||
public String Add_double(String name) {return Add(Dbmeta_fld_itm.new_double(name));}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,14 +13,32 @@ The terms of each license can be found in the source code repository:
|
||||
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.dbs.engines; import gplx.*; import gplx.dbs.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
|
||||
package gplx.dbs.engines;
|
||||
|
||||
import gplx.Gfo_usr_dlg;
|
||||
import gplx.Io_url;
|
||||
import gplx.core.stores.DataRdr;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_conn_info;
|
||||
import gplx.dbs.Db_qry;
|
||||
import gplx.dbs.Db_rdr;
|
||||
import gplx.dbs.Db_stmt;
|
||||
import gplx.dbs.Dbmeta_fld_itm;
|
||||
import gplx.dbs.Dbmeta_idx_itm;
|
||||
import gplx.dbs.Dbmeta_tbl_itm;
|
||||
import gplx.dbs.conn_props.Db_conn_props_mgr;
|
||||
import gplx.dbs.metas.Dbmeta_tbl_mgr;
|
||||
import gplx.dbs.qrys.bats.Db_batch_mgr;
|
||||
import gplx.dbs.sqls.Sql_qry_wtr;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
public interface Db_engine {
|
||||
String Tid();
|
||||
Db_conn_info Conn_info();
|
||||
Db_conn_props_mgr Props();
|
||||
Db_batch_mgr Batch_mgr();
|
||||
Sql_qry_wtr Sql_wtr();
|
||||
void CtorConn(SqlWkrMgr wkrMgr);
|
||||
Db_engine New_clone(Db_conn_info conn_info);
|
||||
void Conn_open();
|
||||
void Conn_term();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -15,6 +15,8 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.dbs.engines.mems; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
public class Mem_engine implements Db_engine {
|
||||
private final Hash_adp tbl_hash = Hash_adp_.New();
|
||||
Mem_engine(Db_conn_info conn_info) {
|
||||
@ -27,6 +29,7 @@ public class Mem_engine implements Db_engine {
|
||||
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
|
||||
public Mem_exec_select Qry_runner() {return qry_runner;} private Mem_exec_select qry_runner;
|
||||
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.New__basic();
|
||||
@Override public void CtorConn(SqlWkrMgr wkrMgr) {}
|
||||
public Db_engine New_clone(Db_conn_info conn_info) {return new Mem_engine(conn_info);}
|
||||
public Db_stmt Stmt_by_qry(Db_qry qry) {return new Mem_stmt(this, qry);}
|
||||
public Mem_tbl Tbls__get(String name) {return (Mem_tbl)tbl_hash.Get_by(name);}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -15,10 +15,13 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.dbs.engines.mysql; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
import java.sql.*;
|
||||
public class Mysql_engine extends Db_engine_sql_base {
|
||||
@Override public String Tid() {return Mysql_conn_info.Tid_const;}
|
||||
@Override public Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.New__mysql();}
|
||||
@Override public void CtorConn(SqlWkrMgr wkrMgr) {}
|
||||
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
|
||||
Mysql_engine rv = new Mysql_engine();
|
||||
rv.Ctor(connectInfo);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -15,12 +15,15 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.dbs.engines.noops; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.sqls.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.bats.*;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
public class Noop_engine implements Db_engine {
|
||||
public String Tid() {return Noop_conn_info.Tid_const;}
|
||||
public Db_conn_info Conn_info() {return Db_conn_info_.Null;}
|
||||
public Db_conn_props_mgr Props() {return props;} private final Db_conn_props_mgr props = new Db_conn_props_mgr();
|
||||
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
|
||||
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.New__basic();
|
||||
@Override public void CtorConn(SqlWkrMgr wkrMgr) {}
|
||||
public void Conn_open() {}
|
||||
public void Conn_term() {}
|
||||
public Db_engine New_clone(Db_conn_info url) {return this;}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -15,10 +15,15 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.dbs.engines.postgres; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.engines.*; import gplx.dbs.sqls.*; import gplx.dbs.metas.*;
|
||||
import java.sql.*;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
public class Postgres_engine extends Db_engine_sql_base {
|
||||
@Override public String Tid() {return Postgres_conn_info.Tid_const;}
|
||||
@Override public Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.New__mysql();}
|
||||
@Override public void CtorConn(SqlWkrMgr wkrMgr) {}
|
||||
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
|
||||
Postgres_engine rv = new Postgres_engine();
|
||||
rv.Ctor(connectInfo);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -21,6 +21,8 @@ import gplx.core.consoles.Console_adp_;
|
||||
import gplx.core.consoles.Console_adp__sys;
|
||||
import gplx.core.ios.IoItmFil;
|
||||
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
import gplx.dbs.wkrs.randoms.SqliteRandomWkr;
|
||||
import org.sqlite.SQLiteConnection;
|
||||
public class Sqlite_engine extends Db_engine_sql_base {
|
||||
private final Sqlite_txn_mgr txn_mgr; private final Sqlite_schema_mgr schema_mgr;
|
||||
@ -30,6 +32,10 @@ public class Sqlite_engine extends Db_engine_sql_base {
|
||||
}
|
||||
@Override public String Tid() {return Sqlite_conn_info.Key_const;}
|
||||
@Override public gplx.dbs.sqls.Sql_qry_wtr Sql_wtr() {return Sql_qry_wtr_.New__sqlite();}
|
||||
public void CtorConn(SqlWkrMgr wkrMgr) {
|
||||
wkrMgr.Set(new SqliteRandomWkr());
|
||||
}
|
||||
|
||||
@Override public Db_engine New_clone(Db_conn_info connectInfo) {
|
||||
Sqlite_engine rv = new Sqlite_engine();
|
||||
rv.Ctor(connectInfo);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -15,6 +15,8 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
*/
|
||||
package gplx.dbs.engines.tdbs; import gplx.*; import gplx.dbs.*; import gplx.dbs.engines.*;
|
||||
import gplx.core.stores.*; import gplx.dbs.metas.*; import gplx.dbs.conn_props.*; import gplx.dbs.qrys.*; import gplx.dbs.sqls.*; import gplx.dbs.qrys.bats.*;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
public class TdbEngine implements Db_engine {
|
||||
public String Tid() {return Tdb_conn_info.Tid_const;}
|
||||
public Db_conn_info Conn_info() {return conn_info;} private Db_conn_info conn_info;
|
||||
@ -22,6 +24,7 @@ public class TdbEngine implements Db_engine {
|
||||
public Db_batch_mgr Batch_mgr() {return batch_mgr;} private final Db_batch_mgr batch_mgr = new Db_batch_mgr();
|
||||
public Sql_qry_wtr Sql_wtr() {return sql_wtr;} private final Sql_qry_wtr sql_wtr = Sql_qry_wtr_.New__basic();
|
||||
public TdbDatabase Db() {return db;} TdbDatabase db;
|
||||
@Override public void CtorConn(SqlWkrMgr wkrMgr) {}
|
||||
public void Conn_open() {
|
||||
Tdb_conn_info tdb_url = (Tdb_conn_info)conn_info;
|
||||
String url_str = tdb_url.Server();
|
||||
|
20
140_dbs/src/gplx/dbs/wkrs/SqlWkr.java
Normal file
20
140_dbs/src/gplx/dbs/wkrs/SqlWkr.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.dbs.wkrs;
|
||||
|
||||
public interface SqlWkr {
|
||||
String Key();
|
||||
}
|
43
140_dbs/src/gplx/dbs/wkrs/SqlWkrMgr.java
Normal file
43
140_dbs/src/gplx/dbs/wkrs/SqlWkrMgr.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.dbs.wkrs;
|
||||
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.wkrs.randoms.SqlRandomWkr;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SqlWkrMgr {
|
||||
private final Map<String, SqlWkr> map = new HashMap<>();
|
||||
private final Db_conn conn;
|
||||
public SqlWkrMgr(Db_conn conn) {
|
||||
this.conn = conn;
|
||||
}
|
||||
public SqlWkr Get(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
public void Set(SqlWkr wkr) {
|
||||
map.put(wkr.Key(), wkr);
|
||||
}
|
||||
|
||||
public Object ExecRandomObj(String select, String from, String where) {
|
||||
SqlRandomWkr wkr = (SqlRandomWkr)map.get(SqlWkrMgr.WKR_RANDOM);
|
||||
return wkr.SelectRandomRow(conn, select, from, where)[0];
|
||||
}
|
||||
|
||||
public static final String WKR_RANDOM = "random";
|
||||
}
|
23
140_dbs/src/gplx/dbs/wkrs/randoms/SqlRandomWkr.java
Normal file
23
140_dbs/src/gplx/dbs/wkrs/randoms/SqlRandomWkr.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.dbs.wkrs.randoms;
|
||||
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.wkrs.SqlWkr;
|
||||
|
||||
public interface SqlRandomWkr extends SqlWkr {
|
||||
Object[] SelectRandomRow(Db_conn conn, String select, String from, String where);
|
||||
}
|
60
140_dbs/src/gplx/dbs/wkrs/randoms/SqliteRandomWkr.java
Normal file
60
140_dbs/src/gplx/dbs/wkrs/randoms/SqliteRandomWkr.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.dbs.wkrs.randoms;
|
||||
|
||||
import gplx.RandomAdp_;
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.Db_rdr;
|
||||
import gplx.dbs.Db_rdr_;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
public class SqliteRandomWkr implements SqlRandomWkr {
|
||||
@Override public String Key() {return SqlWkrMgr.WKR_RANDOM;}
|
||||
|
||||
// NOTE: selects only 1 random row to simplify method signature
|
||||
// * uses COUNT, LIMIT, OFFSET, so should also work for MySQL
|
||||
// * to return many rows, look at https://stackoverflow.com/questions/4114940/select-random-rows-in-sqlite
|
||||
// EX: SELECT * FROM table WHERE id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT x)
|
||||
// Also, note that SQLite does not support TYPE_FORWARD_ONLY so can't jump back and forth thru ResultSet
|
||||
@Override public Object[] SelectRandomRow(Db_conn conn, String select, String from, String where) {
|
||||
Db_rdr rdr = Db_rdr_.Empty;
|
||||
try {
|
||||
String sqlSuffix = ("FROM " + from + " WHERE " + where);
|
||||
|
||||
// get rowCount of resultSet
|
||||
rdr = conn.Stmt_sql("SELECT COUNT(*) AS RowCount " + sqlSuffix).Exec_select__rls_auto();
|
||||
int rowCount = rdr.Read_int("RowCount");
|
||||
|
||||
// get random row
|
||||
int random = RandomAdp_.new_().Next(rowCount);
|
||||
rdr = conn.Stmt_sql("SELECT " + select + " " + sqlSuffix + " LIMIT 1 OFFSET " + random).Exec_select__rls_auto();
|
||||
|
||||
// return result
|
||||
int fldsLen = rdr.Fld_len();
|
||||
Object[] rv = new Object[fldsLen];
|
||||
for (int i = 0; i < fldsLen; i++) {
|
||||
rv[i] = rdr.Read_at(i);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
catch (Exception exc) { // for debugging; should log
|
||||
throw exc;
|
||||
}
|
||||
finally {
|
||||
rdr.Rls();
|
||||
}
|
||||
}
|
||||
}
|
51
140_dbs/src/gplx/dbs/wkrs/randoms/TestRandomWkr.java
Normal file
51
140_dbs/src/gplx/dbs/wkrs/randoms/TestRandomWkr.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.dbs.wkrs.randoms;
|
||||
|
||||
import gplx.dbs.Db_conn;
|
||||
import gplx.dbs.wkrs.SqlWkrMgr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TestRandomWkr implements SqlRandomWkr {
|
||||
private final List<Object[]> list = new ArrayList<>();
|
||||
private int index = 0;
|
||||
public void AddRow(Object... ary) {
|
||||
list.add(ary);
|
||||
}
|
||||
public void Clear() {
|
||||
list.clear();
|
||||
index = 0;
|
||||
}
|
||||
public String SelectRandomRowSelect() {return selectRandomRowSelect;} private String selectRandomRowSelect;
|
||||
public String SelectRandomRowFrom() {return selectRandomRowFrom;} private String selectRandomRowFrom;
|
||||
public String SelectRandomRowWhere() {return selectRandomRowWhere;} private String selectRandomRowWhere;
|
||||
|
||||
@Override public String Key() {return SqlWkrMgr.WKR_RANDOM;}
|
||||
@Override public Object[] SelectRandomRow(Db_conn conn, String select, String from, String where) {
|
||||
this.selectRandomRowSelect = select;
|
||||
this.selectRandomRowFrom = from;
|
||||
this.selectRandomRowWhere = where;
|
||||
return list.get(index++);
|
||||
}
|
||||
|
||||
public static TestRandomWkr New(Db_conn conn) {
|
||||
TestRandomWkr wkr = new TestRandomWkr();
|
||||
conn.WkrMgr().Set(wkr);
|
||||
return wkr;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2021 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,10 +13,31 @@ The terms of each license can be found in the source code repository:
|
||||
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.gfui.kits.swts; import gplx.*; import gplx.gfui.*; import gplx.gfui.kits.*;
|
||||
package gplx.gfui.kits.swts;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Err_;
|
||||
import gplx.GfoMsg;
|
||||
import gplx.Gfo_evt_itm;
|
||||
import gplx.Gfo_evt_mgr;
|
||||
import gplx.Gfo_evt_mgr_;
|
||||
import gplx.Gfo_evt_mgr_owner;
|
||||
import gplx.Gfo_invk;
|
||||
import gplx.Gfo_invk_;
|
||||
import gplx.GfsCtx;
|
||||
import gplx.Int_;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Io_url;
|
||||
import gplx.Keyval_hash;
|
||||
import gplx.Long_;
|
||||
import gplx.Object_;
|
||||
import gplx.String_;
|
||||
import gplx.Type_;
|
||||
import gplx.UsrDlg_;
|
||||
import gplx.core.envs.System_;
|
||||
import gplx.core.primitives.*;
|
||||
import gplx.core.threads.Thread_adp_;
|
||||
import gplx.gfui.controls.elems.GfuiElem;
|
||||
import gplx.gfui.controls.gxws.GxwCbkHost;
|
||||
import gplx.gfui.controls.gxws.GxwCore_base;
|
||||
@ -24,27 +45,32 @@ import gplx.gfui.controls.gxws.GxwElem;
|
||||
import gplx.gfui.controls.gxws.Gxw_html;
|
||||
import gplx.gfui.controls.gxws.Gxw_html_load_tid_;
|
||||
import gplx.gfui.controls.standards.Gfui_html;
|
||||
import gplx.gfui.controls.standards.Gfui_tab_mgr;
|
||||
import gplx.gfui.draws.ColorAdp;
|
||||
import gplx.gfui.draws.ColorAdp_;
|
||||
import gplx.gfui.ipts.*;
|
||||
import gplx.gfui.ipts.IptEvtDataMouse;
|
||||
import gplx.gfui.ipts.IptMouseBtn;
|
||||
import gplx.gfui.ipts.IptMouseBtn_;
|
||||
import gplx.gfui.ipts.IptMouseWheel_;
|
||||
import gplx.gfui.kits.core.Swt_kit;
|
||||
|
||||
import java.security.acl.Owner;
|
||||
import gplx.*;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.browser.*;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.*;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
import java.security.acl.Owner;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.browser.*;
|
||||
import org.eclipse.swt.events.*;
|
||||
import org.eclipse.swt.graphics.*;
|
||||
import org.eclipse.swt.widgets.*;
|
||||
import org.eclipse.swt.browser.Browser;
|
||||
import org.eclipse.swt.browser.BrowserFunction;
|
||||
import org.eclipse.swt.browser.LocationEvent;
|
||||
import org.eclipse.swt.browser.LocationListener;
|
||||
import org.eclipse.swt.browser.ProgressEvent;
|
||||
import org.eclipse.swt.browser.ProgressListener;
|
||||
import org.eclipse.swt.browser.StatusTextEvent;
|
||||
import org.eclipse.swt.browser.StatusTextListener;
|
||||
import org.eclipse.swt.browser.TitleEvent;
|
||||
import org.eclipse.swt.browser.TitleListener;
|
||||
import org.eclipse.swt.events.FocusEvent;
|
||||
import org.eclipse.swt.events.FocusListener;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseListener;
|
||||
import org.eclipse.swt.events.MouseWheelListener;
|
||||
import org.eclipse.swt.events.TraverseEvent;
|
||||
import org.eclipse.swt.events.TraverseListener;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
||||
public class Swt_html implements Gxw_html, Swt_control, FocusListener, Gfo_evt_mgr_owner {
|
||||
private Swt_html_lnr_location lnr_location; private Swt_html_lnr_status lnr_status;
|
||||
@ -206,7 +232,10 @@ class Swt_html_lnr_status implements StatusTextListener {
|
||||
public void Host_set(Gfo_evt_itm host) {this.host = host;} Gfo_evt_itm host;
|
||||
@Override public void changed(StatusTextEvent ev) {
|
||||
if (html_box.Kit().Kit_mode__term()) return; // shutting down raises status changed events; ignore, else SWT exception thrown; DATE:2014-05-29
|
||||
String ev_text = ev.text;
|
||||
|
||||
// 2020-09-22|ISSUE#:799|normalize URL due to SWT 4.16
|
||||
String ev_text = Swt_html_utl.NormalizeSwtUrl(ev.text);
|
||||
|
||||
String load_by_url_path = html_box.Load_by_url_path();
|
||||
if (load_by_url_path != null) ev_text = String_.Replace(ev_text, load_by_url_path, ""); // remove "C:/xowa/tab_1.html"
|
||||
// if (String_.Has(ev_text, "Loading [MathJax]")) return; // suppress MathJax messages; // NOTE: disabled for 2.1 (which no longer outputs messages to status); DATE:2013-05-03
|
||||
@ -227,17 +256,28 @@ class Swt_html_lnr_location implements LocationListener {
|
||||
@Override public void changed(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changed);}
|
||||
@Override public void changing(LocationEvent arg) {Pub_evt(arg, Gfui_html.Evt_location_changing);}
|
||||
private void Pub_evt(LocationEvent arg, String evt) {
|
||||
String location = arg.location;
|
||||
if (String_.Eq(location, "about:blank")) return; // location changing event fires once when page is loaded; ignore
|
||||
if ( html_box.Browser_tid() == Swt_html.Browser_tid_webkit // webkit prefixes "about:blank" to anchors; causes TOC to fail when clicking on links; EX:about:blank#TOC1; DATE:2015-06-09
|
||||
&& String_.Has_at_bgn(location, "about:blank")) {
|
||||
location = String_.Mid(location, 11); // 11 = "about:blank".length
|
||||
// 2020-09-22|ISSUE#:799|normalize URL due to SWT 4.16
|
||||
String location = Swt_html_utl.NormalizeSwtUrl(arg.location);
|
||||
|
||||
// location_changing fires once when page is loaded -> ignore
|
||||
if (String_.Eq(location, String_.Empty)) {
|
||||
return;
|
||||
}
|
||||
if ( html_box.Html_doc_html_load_tid() == Gxw_html_load_tid_.Tid_url // navigating to file://page.html will fire location event; ignore if url mode
|
||||
|
||||
// navigating to file://page.html will fire location event; ignore if url mode (loading pages from file)
|
||||
if (html_box.Html_doc_html_load_tid() == Gxw_html_load_tid_.Tid_url
|
||||
&& String_.Has_at_bgn(location, "file:")
|
||||
&& String_.Has_at_end(location, ".html")
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (String_.Has_at_bgn(location, "javascript:")) {
|
||||
html_box.Html_js_eval_script(location);
|
||||
arg.doit = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Gfo_evt_mgr_.Pub_obj(host, evt, "v", location);
|
||||
arg.doit = false; // cancel navigation event, else there will be an error when trying to go to invalid location
|
||||
|
40
150_gfui/src/gplx/gfui/kits/swts/Swt_html_utl.java
Normal file
40
150_gfui/src/gplx/gfui/kits/swts/Swt_html_utl.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.gfui.kits.swts;
|
||||
|
||||
import gplx.String_;
|
||||
|
||||
public class Swt_html_utl {
|
||||
private static final String URL_PREFIX_ABOUT = "about:";
|
||||
private static final String URL_PREFIX_BLANK = "blank";
|
||||
|
||||
public static String NormalizeSwtUrl(String url) {
|
||||
String rv = url;
|
||||
|
||||
// 2020-09-19|ISSUE#:799|strip "about:" from url due to SWT 4.16
|
||||
rv = String_.Has_at_bgn(rv, URL_PREFIX_ABOUT)
|
||||
? String_.Mid(rv, URL_PREFIX_ABOUT.length())
|
||||
: rv;
|
||||
|
||||
// 2015-06-09|webkit prefixes "about:blank" to anchors; causes TOC to fail when clicking on links; EX:about:blank#TOC1
|
||||
// 2020-09-22|removed webkit check due to SWT 4.16; `html_box.Browser_tid() == Swt_html.Browser_tid_webkit`
|
||||
// still strip "blank"; note that SWT 4.16 changes anchors from "file:///#anchor" to "en.w/wiki/page/#anchor"
|
||||
rv = String_.Has_at_bgn(rv, URL_PREFIX_BLANK)
|
||||
? String_.Mid(rv, URL_PREFIX_BLANK.length())
|
||||
: rv;
|
||||
return rv;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,24 @@ The terms of each license can be found in the source code repository:
|
||||
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.core.gfobjs; import gplx.*; import gplx.core.*;
|
||||
import gplx.langs.jsons.*;
|
||||
package gplx.core.gfobjs;
|
||||
|
||||
import gplx.Err_;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Io_url;
|
||||
import gplx.langs.jsons.Json_ary;
|
||||
import gplx.langs.jsons.Json_doc;
|
||||
import gplx.langs.jsons.Json_itm;
|
||||
import gplx.langs.jsons.Json_itm_;
|
||||
import gplx.langs.jsons.Json_itm_bool;
|
||||
import gplx.langs.jsons.Json_itm_decimal;
|
||||
import gplx.langs.jsons.Json_itm_int;
|
||||
import gplx.langs.jsons.Json_itm_long;
|
||||
import gplx.langs.jsons.Json_itm_str;
|
||||
import gplx.langs.jsons.Json_kv;
|
||||
import gplx.langs.jsons.Json_nde;
|
||||
import gplx.langs.jsons.Json_parser;
|
||||
|
||||
public class Gfobj_rdr__json {
|
||||
private final Json_parser parser = new Json_parser();
|
||||
public Gfobj_grp Load(Io_url url) {
|
||||
@ -56,7 +72,7 @@ public class Gfobj_rdr__json {
|
||||
case Json_itm_.Tid__nde:
|
||||
Gfobj_nde sub_gnde = Gfobj_nde.New();
|
||||
gnde.Add_nde(key_str, sub_gnde);
|
||||
Parse_nde(Json_nde.cast(val), sub_gnde);
|
||||
Parse_nde(Json_nde.Cast(val), sub_gnde);
|
||||
break;
|
||||
default: throw Err_.new_unhandled_default(val_tid);
|
||||
}
|
||||
@ -77,7 +93,7 @@ public class Gfobj_rdr__json {
|
||||
}
|
||||
case Json_itm_.Tid__nde: {
|
||||
Gfobj_nde sub_ary = Gfobj_nde.New();
|
||||
Parse_nde(Json_nde.cast(jsub), sub_ary);
|
||||
Parse_nde(Json_nde.Cast(jsub), sub_ary);
|
||||
ary[i] = sub_ary;
|
||||
break;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,7 +13,14 @@ The terms of each license can be found in the source code repository:
|
||||
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.core.primitives; import gplx.*; import gplx.core.*;
|
||||
package gplx.core.primitives;
|
||||
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Decimal_adp;
|
||||
import gplx.Decimal_adp_;
|
||||
import gplx.Int_;
|
||||
import gplx.Math_;
|
||||
|
||||
public class Gfo_number_parser {
|
||||
public int Rv_as_int() {return (int)num_val;} private long num_val = 0;
|
||||
public long Rv_as_long() {return num_val;}
|
||||
@ -112,6 +119,7 @@ public class Gfo_number_parser {
|
||||
has_exp = true;
|
||||
has_neg = false;
|
||||
has_plus = false; // allow +1E+2
|
||||
has_num = false; // 2020-09-07|ISSUE#:795|scientific notation requires coefficient; set has_num to false which will fail below if no coefficient
|
||||
}
|
||||
break;
|
||||
case Byte_ascii.Ltr_A:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,15 @@ The terms of each license can be found in the source code repository:
|
||||
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.core.primitives; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
package gplx.core.primitives;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Decimal_adp;
|
||||
import gplx.Decimal_adp_;
|
||||
import gplx.Tfds;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Gfo_number_parser_tst {
|
||||
@Before public void init() {fxt.Clear();} private final Gfo_number_parser_fxt fxt = new Gfo_number_parser_fxt();
|
||||
@Test public void Integer() {
|
||||
@ -42,6 +49,7 @@ public class Gfo_number_parser_tst {
|
||||
fxt.Test_dec("1.234E-2", Decimal_adp_.parse(".01234"));
|
||||
fxt.Test_dec("123.4E-2", Decimal_adp_.parse("1.234"));
|
||||
fxt.Test_dec("+6.0E-3", Decimal_adp_.parse(".006"));
|
||||
fxt.Test_err("e24", true); // 2020-09-07|ISSUE#:795|scientific notation requires coefficient
|
||||
}
|
||||
@Test public void Err() {
|
||||
fxt.Test_err("+", true);
|
||||
|
46
400_xowa/src/gplx/core/serials/binarys/BinaryLoadMgr.java
Normal file
46
400_xowa/src/gplx/core/serials/binarys/BinaryLoadMgr.java
Normal file
@ -0,0 +1,46 @@
|
||||
package gplx.core.serials.binarys;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.core.serials.core.SerialLoadMgr;
|
||||
import gplx.core.serials.core.SerialLoadWkr;
|
||||
import gplx.core.texts.Base64Converter;
|
||||
|
||||
public class BinaryLoadMgr implements SerialLoadMgr {
|
||||
public static final int CORE_VERSION = 0;
|
||||
private byte[] data;
|
||||
private int headerEnd;
|
||||
private int dataVersion;
|
||||
|
||||
@Override
|
||||
public int CoreVersion() {
|
||||
return CORE_VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int DataVersion() {return dataVersion;}
|
||||
|
||||
@Override
|
||||
public void ReadHeader(byte[] data) {
|
||||
this.data = data;
|
||||
this.dataVersion = Base64Converter.GetIndexInt((char)data[1]);
|
||||
this.headerEnd = 3; // 1=coreVersion; 2=dataVersion; 3=\n
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] Data() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int HeaderEnd() {
|
||||
return headerEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerialLoadWkr NewLoadWkr() {
|
||||
return new BinaryLoadWkr().Ctor(this);
|
||||
}
|
||||
|
||||
public byte[] FldDlm() {return fldDlm;} private final byte[] fldDlm = Bry_.new_a7("|");
|
||||
public byte[] RowDlm() {return rowDlm;} private final byte[] rowDlm = Bry_.new_a7("\n");
|
||||
}
|
75
400_xowa/src/gplx/core/serials/binarys/BinaryLoadWkr.java
Normal file
75
400_xowa/src/gplx/core/serials/binarys/BinaryLoadWkr.java
Normal file
@ -0,0 +1,75 @@
|
||||
package gplx.core.serials.binarys;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_find_;
|
||||
import gplx.Err_;
|
||||
import gplx.String_;
|
||||
import gplx.core.serials.core.SerialLoadMgr;
|
||||
import gplx.core.serials.core.SerialLoadWkr;
|
||||
|
||||
public class BinaryLoadWkr implements SerialLoadWkr {
|
||||
private BinaryLoadMgr mgr;
|
||||
private byte[] fldDlm;
|
||||
private byte[] rowDlm;
|
||||
private byte[] src;
|
||||
private int srcLen;
|
||||
private int cur;
|
||||
|
||||
@Override
|
||||
public SerialLoadWkr Ctor(SerialLoadMgr mgrObj) {
|
||||
this.mgr = (BinaryLoadMgr)mgrObj;
|
||||
this.fldDlm = mgr.FldDlm();
|
||||
this.rowDlm = mgr.RowDlm();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Init(byte[] src, int cur) {
|
||||
this.src = src;
|
||||
this.srcLen = src.length;
|
||||
this.cur = cur;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String LoadStr() {
|
||||
return String_.new_u8(LoadBry());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int LoadInt() {
|
||||
return LoadInt(rowDlm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] LoadBry() {
|
||||
int bryLen = LoadInt(fldDlm);
|
||||
|
||||
// extract bry
|
||||
int bryBgn = cur;
|
||||
int bryEnd = bryBgn + bryLen;
|
||||
if (bryEnd > srcLen) {
|
||||
throw Err_.new_wo_type(String_.Format("End position is out of bounds; src={0} currentPosition={1} byteArrayLength={2} remainder={3}", src, cur, bryLen, Bry_.Mid(src, bryBgn, bryEnd)));
|
||||
}
|
||||
cur = bryEnd + rowDlm.length;
|
||||
|
||||
return Bry_.Mid(src, bryBgn, bryEnd);
|
||||
}
|
||||
|
||||
private int LoadInt(byte[] dlm) {
|
||||
int bgn = cur;
|
||||
|
||||
// find position of delimiter
|
||||
int end = Bry_find_.Find_fwd(src, dlm, cur, srcLen);
|
||||
if (end == Bry_find_.Not_found) {
|
||||
throw Err_.new_wo_type(String_.Format("Failed to find delimiter for integer's end position; src={0} currentPosition={1} delimiter={2}", src, cur, fldDlm));
|
||||
}
|
||||
cur = end + dlm.length;
|
||||
|
||||
// parse int
|
||||
int val = Bry_.To_int_or(src, bgn, end, -1);
|
||||
if (val == -1) {
|
||||
throw Err_.new_wo_type(String_.Format("Failed to parse integer; src={0} currentPosition={1} string={2}", src, cur, Bry_.Mid(src, bgn, end)));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
16
400_xowa/src/gplx/core/serials/binarys/BinarySaveMgr.java
Normal file
16
400_xowa/src/gplx/core/serials/binarys/BinarySaveMgr.java
Normal file
@ -0,0 +1,16 @@
|
||||
package gplx.core.serials.binarys;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.core.serials.core.SerialSaveMgr;
|
||||
import gplx.core.serials.core.SerialSaveWkr;
|
||||
|
||||
public class BinarySaveMgr implements SerialSaveMgr {
|
||||
public int CoreVersion() {return BinaryLoadMgr.CORE_VERSION;}
|
||||
public byte[] FldDlm() {return fldDlm;} private final byte[] fldDlm = Bry_.new_a7("|");
|
||||
public byte[] RowDlm() {return rowDlm;} private final byte[] rowDlm = Bry_.new_a7("\n");
|
||||
|
||||
@Override
|
||||
public SerialSaveWkr NewSaveWkr() {
|
||||
return new BinarySaveWkr().Ctor(this);
|
||||
}
|
||||
}
|
60
400_xowa/src/gplx/core/serials/binarys/BinarySaveWkr.java
Normal file
60
400_xowa/src/gplx/core/serials/binarys/BinarySaveWkr.java
Normal file
@ -0,0 +1,60 @@
|
||||
package gplx.core.serials.binarys;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.core.serials.core.SerialSaveMgr;
|
||||
import gplx.core.serials.core.SerialSaveWkr;
|
||||
import gplx.core.texts.Base64Converter;
|
||||
|
||||
public class BinarySaveWkr implements SerialSaveWkr {
|
||||
private byte[] fldDlm;
|
||||
private byte[] rowDlm;
|
||||
private BinarySaveMgr mgr;
|
||||
private final Bry_bfr bfr = Bry_bfr_.New();
|
||||
|
||||
@Override
|
||||
public SerialSaveWkr Ctor(SerialSaveMgr mgrObj) {
|
||||
this.mgr = (BinarySaveMgr)mgrObj;
|
||||
this.fldDlm = mgr.FldDlm();
|
||||
this.rowDlm = mgr.RowDlm();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Init() {
|
||||
bfr.Clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SaveHdr(int dataVersion) {
|
||||
// EX: AA -> SerialCoreMgrID+DataVersionID
|
||||
bfr.Add_byte((byte)Base64Converter.GetIndexChar(mgr.CoreVersion()));
|
||||
bfr.Add_byte((byte)Base64Converter.GetIndexChar(dataVersion)).Add(rowDlm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SaveInt(int val) {
|
||||
SaveInt(val, rowDlm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SaveStr(String val) {
|
||||
this.SaveBry(Bry_.new_u8(val));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SaveBry(byte[] val) {
|
||||
SaveInt(val.length, fldDlm);
|
||||
bfr.Add(val).Add(rowDlm);
|
||||
}
|
||||
|
||||
private void SaveInt(int val, byte[] dlm) {
|
||||
bfr.Add_int_variable(val).Add(dlm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] ToBry() {
|
||||
return bfr.To_bry();
|
||||
}
|
||||
}
|
24
400_xowa/src/gplx/core/serials/core/SerialCoreFactory.java
Normal file
24
400_xowa/src/gplx/core/serials/core/SerialCoreFactory.java
Normal file
@ -0,0 +1,24 @@
|
||||
package gplx.core.serials.core;
|
||||
|
||||
import gplx.Err_;
|
||||
import gplx.core.serials.binarys.BinaryLoadMgr;
|
||||
import gplx.core.serials.binarys.BinarySaveMgr;
|
||||
import gplx.core.texts.Base64Converter;
|
||||
|
||||
public class SerialCoreFactory {
|
||||
public static SerialSaveMgr NewSaveMgr(int coreVersion) {
|
||||
if (coreVersion == BinaryLoadMgr.CORE_VERSION) {
|
||||
return new BinarySaveMgr();
|
||||
}
|
||||
throw Err_.new_unhandled_default(coreVersion);
|
||||
}
|
||||
public static SerialLoadMgr NewLoadMgr(byte[] data) {
|
||||
int coreVersion = Base64Converter.GetIndexInt((char)data[0]);
|
||||
if (coreVersion == BinaryLoadMgr.CORE_VERSION) {
|
||||
BinaryLoadMgr loadMgr = new BinaryLoadMgr();
|
||||
loadMgr.ReadHeader(data);
|
||||
return loadMgr;
|
||||
}
|
||||
throw Err_.new_unhandled_default(coreVersion);
|
||||
}
|
||||
}
|
10
400_xowa/src/gplx/core/serials/core/SerialLoadMgr.java
Normal file
10
400_xowa/src/gplx/core/serials/core/SerialLoadMgr.java
Normal file
@ -0,0 +1,10 @@
|
||||
package gplx.core.serials.core;
|
||||
|
||||
public interface SerialLoadMgr {
|
||||
int CoreVersion();
|
||||
int DataVersion();
|
||||
SerialLoadWkr NewLoadWkr();
|
||||
void ReadHeader(byte[] data);
|
||||
byte[] Data();
|
||||
int HeaderEnd();
|
||||
}
|
9
400_xowa/src/gplx/core/serials/core/SerialLoadWkr.java
Normal file
9
400_xowa/src/gplx/core/serials/core/SerialLoadWkr.java
Normal file
@ -0,0 +1,9 @@
|
||||
package gplx.core.serials.core;
|
||||
|
||||
public interface SerialLoadWkr {
|
||||
SerialLoadWkr Ctor(SerialLoadMgr mgr);
|
||||
void Init(byte[] src, int cur);
|
||||
int LoadInt();
|
||||
byte[] LoadBry();
|
||||
String LoadStr();
|
||||
}
|
6
400_xowa/src/gplx/core/serials/core/SerialSaveMgr.java
Normal file
6
400_xowa/src/gplx/core/serials/core/SerialSaveMgr.java
Normal file
@ -0,0 +1,6 @@
|
||||
package gplx.core.serials.core;
|
||||
|
||||
public interface SerialSaveMgr {
|
||||
int CoreVersion();
|
||||
SerialSaveWkr NewSaveWkr();
|
||||
}
|
11
400_xowa/src/gplx/core/serials/core/SerialSaveWkr.java
Normal file
11
400_xowa/src/gplx/core/serials/core/SerialSaveWkr.java
Normal file
@ -0,0 +1,11 @@
|
||||
package gplx.core.serials.core;
|
||||
|
||||
public interface SerialSaveWkr {
|
||||
SerialSaveWkr Ctor(SerialSaveMgr mgr);
|
||||
void Init();
|
||||
void SaveHdr(int dataVersion);
|
||||
void SaveInt(int val);
|
||||
void SaveStr(String val);
|
||||
void SaveBry(byte[] val);
|
||||
byte[] ToBry();
|
||||
}
|
@ -81,8 +81,8 @@ public class Gfh_tag_ { // NOTE: not serialized; used by tag_rdr
|
||||
, Id__rp = 59
|
||||
, Id__rt = 60
|
||||
, Id__form = 61
|
||||
, Id__mark = 62
|
||||
;
|
||||
// private static final int Id__ary_max = 60;
|
||||
public static final byte[]
|
||||
Bry__a = Bry_.new_a7("a")
|
||||
, Bry__ul = Bry_.new_a7("ul")
|
||||
@ -167,6 +167,7 @@ public class Gfh_tag_ { // NOTE: not serialized; used by tag_rdr
|
||||
.Add_str_int("rp" , Id__rp)
|
||||
.Add_str_int("rt" , Id__rt)
|
||||
.Add_str_int("form" , Id__form)
|
||||
.Add_str_int("mark" , Id__mark)
|
||||
;
|
||||
public static String To_str(int tid) {
|
||||
switch (tid) {
|
||||
@ -235,6 +236,7 @@ public class Gfh_tag_ { // NOTE: not serialized; used by tag_rdr
|
||||
case Id__rp: return "rp";
|
||||
case Id__rt: return "rt";
|
||||
case Id__form: return "form";
|
||||
case Id__mark: return "mark";
|
||||
default: throw Err_.new_unhandled(tid);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public class Gfh_tag_rdr {
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public Bry_err_wkr Err_wkr() {return err_wkr;} private final Bry_err_wkr err_wkr = new Bry_err_wkr();
|
||||
public Gfh_tag_rdr Skip_ws_after_slash_y_() {skip_ws_after_slash_y = true; return this;} private boolean skip_ws_after_slash_y;
|
||||
public Gfh_tag_rdr Reg(String tag_name, int tag_id) {name_hash.Add_str_int(tag_name, tag_id); return this;}
|
||||
public Gfh_tag_rdr Init(byte[] ctx_name, byte[] src, int src_bgn, int src_end) {
|
||||
this.src = src; this.pos = src_bgn; this.src_end = src_end;
|
||||
@ -205,6 +206,9 @@ public class Gfh_tag_rdr {
|
||||
case Byte_ascii.Slash: // EX: "<a/>"
|
||||
name_end = name_pos;
|
||||
tag_end = name_pos + 1; if (tag_end == src_end) return Tag__eos(tag_bgn);// EX: "<a/EOS"
|
||||
if (skip_ws_after_slash_y) {// skip ws after slash; EX:"<br />"; ISSUE#:542: DATE:2020-03-09
|
||||
tag_end = Bry_find_.Find_fwd_while_ws(src, tag_end, src_end);
|
||||
}
|
||||
if (src[tag_end] == Byte_ascii.Angle_end) {
|
||||
atrs_end = name_end;
|
||||
inline = true;
|
||||
@ -267,6 +271,9 @@ public class Gfh_tag_rdr {
|
||||
case Byte_ascii.Slash: // EX: "<a/>"
|
||||
name_end = name_pos;
|
||||
tag_end = name_pos + 1; if (tag_end == src_end) return Tag__eos(tag_bgn);// EX: "<a/EOS"
|
||||
if (skip_ws_after_slash_y) {// skip ws after slash; EX:"<br />"; ISSUE#:542: DATE:2020-03-09
|
||||
tag_end = Bry_find_.Find_fwd_while_ws(src, tag_end, src_end);
|
||||
}
|
||||
if (src[tag_end] == Byte_ascii.Angle_end) {
|
||||
atrs_end = name_end;
|
||||
inline = true;
|
||||
|
157
400_xowa/src/gplx/langs/javascripts/JsString_.java
Normal file
157
400_xowa/src/gplx/langs/javascripts/JsString_.java
Normal file
@ -0,0 +1,157 @@
|
||||
package gplx.langs.javascripts;
|
||||
|
||||
import gplx.Err_;
|
||||
import gplx.String_;
|
||||
import gplx.langs.javascripts.util.regex.JsPattern_;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class JsString_ {
|
||||
public static boolean charAtEq(String s, int i, char m) {
|
||||
int len = s.length();
|
||||
if (i < 0 || i >= len) {
|
||||
return false;
|
||||
} else {
|
||||
return s.charAt(i) == m;
|
||||
}
|
||||
}
|
||||
public static boolean charAtEqNot(String s, int i, char m) {
|
||||
int len = s.length();
|
||||
if (i < 0 || i >= len) {
|
||||
return false;
|
||||
} else {
|
||||
return s.charAt(i) != m;
|
||||
}
|
||||
}
|
||||
public static String charAt(String s, int i) {
|
||||
int len = s.length();
|
||||
if (i < 0 || i >= len) {
|
||||
return String_.Empty;
|
||||
} else {
|
||||
return Character.toString(s.charAt(i));
|
||||
}
|
||||
}
|
||||
public static String slice(String str, int beginIndex) {
|
||||
return slice(str, beginIndex, str.length());
|
||||
}
|
||||
// REF.JOS:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice
|
||||
public static String slice(String str, int beginIndex, int endIndex) {
|
||||
int srcLen = str.length();
|
||||
|
||||
// bgn
|
||||
if (beginIndex < 0) {
|
||||
beginIndex = srcLen + beginIndex;
|
||||
if (beginIndex < 0) {
|
||||
beginIndex = 0;
|
||||
}
|
||||
}
|
||||
else if (beginIndex > srcLen) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// end
|
||||
if (endIndex < 0) {
|
||||
endIndex = srcLen + endIndex;
|
||||
if (endIndex < 0) {
|
||||
endIndex = 0;
|
||||
}
|
||||
}
|
||||
else if (endIndex > srcLen) {
|
||||
endIndex = srcLen;
|
||||
}
|
||||
if (endIndex < beginIndex) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return str.substring(beginIndex, endIndex);
|
||||
}
|
||||
private static final int
|
||||
REPLACE_TYPE_STR = 0
|
||||
, REPLACE_TYPE_MATCHER = 1
|
||||
, REPLACE_TYPE_ARG1 = 2
|
||||
, REPLACE_TYPE_ARG2 = 3
|
||||
, REPLACE_TYPE_ARG3 = 4
|
||||
;
|
||||
public interface JsStringReplaceArg1 {
|
||||
String processMatcher(String all);
|
||||
}
|
||||
public interface JsStringReplaceArg2 {
|
||||
String processMatcher(String all, String arg1);
|
||||
}
|
||||
public interface JsStringReplaceArg3 {
|
||||
String processMatcher(String all, String arg1, String arg2);
|
||||
}
|
||||
public interface JsStringReplaceMatcher {
|
||||
String processMatcher(Matcher m);
|
||||
}
|
||||
public static String replace(String s, ConcurrentHashMap<String, Pattern> map, String p, String repl) {
|
||||
return replace(s, map, p, JsPattern_.NONE, repl);
|
||||
}
|
||||
public static String replace(String src, ConcurrentHashMap<String, Pattern> map, String pat, int patFlags, String repl) {
|
||||
return replaceObject(src, map, pat, patFlags, repl, REPLACE_TYPE_STR);
|
||||
}
|
||||
public static String replaceArg1(String src, ConcurrentHashMap<String, Pattern> map, String pat, JsStringReplaceArg1 func) {
|
||||
return replaceObject(src, map, pat, JsPattern_.NONE, func, REPLACE_TYPE_ARG1);
|
||||
}
|
||||
public static String replaceArg1(String src, ConcurrentHashMap<String, Pattern> map, String pat, int patFlags, JsStringReplaceArg1 func) {
|
||||
return replaceObject(src, map, pat, patFlags, func, REPLACE_TYPE_ARG1);
|
||||
}
|
||||
public static String replaceArg2(String src, ConcurrentHashMap<String, Pattern> map, String pat, JsStringReplaceArg2 func) {
|
||||
return replaceObject(src, map, pat, JsPattern_.NONE, func, REPLACE_TYPE_ARG2);
|
||||
}
|
||||
public static String replaceArg2(String src, ConcurrentHashMap<String, Pattern> map, String pat, int patFlags, JsStringReplaceArg2 func) {
|
||||
return replaceObject(src, map, pat, patFlags, func, REPLACE_TYPE_ARG2);
|
||||
}
|
||||
public static String replaceArg3(String src, ConcurrentHashMap<String, Pattern> map, String pat, int patFlags, JsStringReplaceArg3 func) {
|
||||
return replaceObject(src, map, pat, patFlags, func, REPLACE_TYPE_ARG3);
|
||||
}
|
||||
public static String replaceMatcher(String src, ConcurrentHashMap<String, Pattern> map, String pat, int patFlags, JsStringReplaceMatcher func) {
|
||||
return replaceObject(src, map, pat, patFlags, func, REPLACE_TYPE_MATCHER);
|
||||
}
|
||||
private static String replaceObject(String src, ConcurrentHashMap<String, Pattern> map, String pat, int patFlags, Object replObj, int replType) {
|
||||
Pattern pattern = JsPattern_.getOrCompile(map, pat, patFlags);
|
||||
|
||||
// match
|
||||
Matcher m = pattern.matcher(src);
|
||||
StringBuffer sb = null;
|
||||
while (m.find()) {
|
||||
// get repl
|
||||
String repl = null;
|
||||
switch (replType) {
|
||||
case REPLACE_TYPE_STR:
|
||||
repl = (String)replObj;
|
||||
break;
|
||||
case REPLACE_TYPE_MATCHER:
|
||||
repl = ((JsStringReplaceMatcher)replObj).processMatcher(m);
|
||||
break;
|
||||
case REPLACE_TYPE_ARG1:
|
||||
repl = ((JsStringReplaceArg1)replObj).processMatcher(m.group(0));
|
||||
break;
|
||||
case REPLACE_TYPE_ARG2:
|
||||
repl = ((JsStringReplaceArg2)replObj).processMatcher(m.group(0), m.group(1));
|
||||
break;
|
||||
case REPLACE_TYPE_ARG3:
|
||||
repl = ((JsStringReplaceArg3)replObj).processMatcher(m.group(0), m.group(1), m.group(2));
|
||||
break;
|
||||
default:
|
||||
throw Err_.new_unhandled_default(replType);
|
||||
}
|
||||
|
||||
if (sb == null) {
|
||||
sb = new StringBuffer();
|
||||
}
|
||||
m.appendReplacement(sb, repl);
|
||||
}
|
||||
|
||||
// return
|
||||
if (sb != null) {
|
||||
m.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
else {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package gplx.langs.javascripts.util.regex;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class JsPattern_ {
|
||||
public static final int NONE = 0;
|
||||
public static Pattern getOrCompile(ConcurrentHashMap<String, Pattern> map, String pat) {return getOrCompile(map, pat, NONE);}
|
||||
public static Pattern getOrCompile(ConcurrentHashMap<String, Pattern> map, String pat, int patFlags) {
|
||||
// get pattern
|
||||
Pattern pattern = map.get(pat);
|
||||
if (pattern == null) {
|
||||
pattern = Pattern.compile(pat, patFlags);
|
||||
map.put(pat, pattern);
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
}
|
69
400_xowa/src/gplx/langs/jsons/JsonDocBldr.java
Normal file
69
400_xowa/src/gplx/langs/jsons/JsonDocBldr.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.List_adp;
|
||||
import gplx.List_adp_;
|
||||
import gplx.String_;
|
||||
|
||||
public class JsonDocBldr {
|
||||
private final List_adp stack = List_adp_.New();
|
||||
private final Json_doc doc = new Json_doc();
|
||||
private Json_grp root;
|
||||
private Json_grp cur;
|
||||
JsonDocBldr() {}
|
||||
public JsonDocBldr Clear(boolean isRootNode) {
|
||||
this.root = isRootNode ? Json_nde.NewByDoc(doc, 0) : Json_ary.NewByDoc(doc, 0, 0);
|
||||
doc.Ctor(Bry_.Empty, root);
|
||||
this.cur = root;
|
||||
stack.Clear();
|
||||
return this;
|
||||
}
|
||||
public JsonDocBldr NdeBgn(String key) {
|
||||
Json_nde nde = Json_nde.NewByDoc(doc, 1);
|
||||
if (cur.Tid() == Json_itm_.Tid__nde) {
|
||||
Json_kv kv = new Json_kv(Json_itm_str.NewByVal(key), nde);
|
||||
cur.Add(kv);
|
||||
}
|
||||
else {
|
||||
cur.Add(nde);
|
||||
}
|
||||
stack.Add(cur);
|
||||
cur = nde;
|
||||
return this;
|
||||
}
|
||||
public JsonDocBldr NdeEnd() {
|
||||
this.cur = (Json_grp)List_adp_.Pop_last(stack);
|
||||
return this;
|
||||
}
|
||||
public JsonDocBldr KvBool(String key, boolean val) {return Kv(key, Json_itm_bool.Get(val));}
|
||||
public JsonDocBldr KvInt(String key, int val) {return Kv(key, Json_itm_int.NewByVal(val));}
|
||||
public JsonDocBldr KvStr(String key, byte[] val) {return Kv(key, Json_itm_str.NewByVal(String_.new_u8(val)));}
|
||||
public JsonDocBldr KvStr(String key, String val) {return Kv(key, Json_itm_str.NewByVal(val));}
|
||||
private JsonDocBldr Kv(String key, Json_itm val) {
|
||||
Json_kv rv = new Json_kv(Json_itm_str.NewByVal(key), val);
|
||||
cur.Add(rv);
|
||||
return this;
|
||||
}
|
||||
public Json_doc ToDoc() {
|
||||
return doc;
|
||||
}
|
||||
public Json_nde ToRootNde() {
|
||||
return doc.Root_nde();
|
||||
}
|
||||
public static JsonDocBldr NewRootNde() {return new JsonDocBldr().Clear(true);}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,11 +13,18 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Array_;
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Err_;
|
||||
|
||||
public class Json_ary extends Json_itm_base implements Json_grp {
|
||||
public Json_ary(int src_bgn, int src_end) {this.Ctor(src_bgn, src_end);}
|
||||
private Json_ary() {}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__ary;}
|
||||
public void Src_end_(int v) {this.src_end = v;}
|
||||
public void Src_end_(int v) {}
|
||||
@Override public Object Data() {return null;}
|
||||
@Override public byte[] Data_bry() {return null;}
|
||||
public int Len() {return subs_len;} private int subs_len = 0, subs_max = 0;
|
||||
@ -26,7 +33,7 @@ public class Json_ary extends Json_itm_base implements Json_grp {
|
||||
return (Json_nde)rv;
|
||||
}
|
||||
public Json_itm Get_at(int i) {return subs[i];}
|
||||
public Json_nde Get_as_nde(int i) {return Json_nde.cast(subs[i]);}
|
||||
public Json_nde Get_as_nde(int i) {return Json_nde.Cast(subs[i]);}
|
||||
public Json_ary Add_many(Json_itm... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
@ -75,4 +82,6 @@ public class Json_ary extends Json_itm_base implements Json_grp {
|
||||
if (v == null || v.Tid() != Json_itm_.Tid__ary) throw Err_.new_("json", "itm is not array");
|
||||
return (Json_ary)v;
|
||||
}
|
||||
public static Json_ary NewByDoc(Json_doc doc, int src_bgn, int src_end) {return new Json_ary();}
|
||||
public static Json_ary NewByVal() {return new Json_ary();}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,15 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import gplx.core.primitives.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Err_;
|
||||
import gplx.String_;
|
||||
import gplx.core.primitives.Gfo_number_parser;
|
||||
|
||||
public class Json_doc {
|
||||
private final byte[][] tmp_qry_bry = new byte[1][];
|
||||
public void Ctor(byte[] src, Json_grp new_root) {
|
||||
@ -66,10 +73,10 @@ public class Json_doc {
|
||||
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
|
||||
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
|
||||
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;
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
public class Json_doc_bldr {
|
||||
public Json_nde Nde(Json_doc jdoc) {return factory.Nde(jdoc, -1);}
|
||||
public Json_nde Nde(Json_doc jdoc, Json_grp owner) {
|
||||
Json_nde rv = factory.Nde(jdoc, -1);
|
||||
owner.Add(rv);
|
||||
return rv;
|
||||
}
|
||||
public Json_itm Str(byte[] v) {return Str(String_.new_u8(v));}
|
||||
public Json_itm Str(String v) {return Json_itm_tmp.new_str_(v);}
|
||||
public Json_itm Int(int v) {return Json_itm_tmp.new_int_(v);}
|
||||
public Json_kv Kv_int(Json_grp owner, String key, int val) {Json_kv rv = factory.Kv(Json_itm_tmp.new_str_(key), Json_itm_tmp.new_int_(val)); owner.Add(rv); return rv;}
|
||||
public Json_kv Kv_str(Json_grp owner, String key, String val) {Json_kv rv = factory.Kv(Json_itm_tmp.new_str_(key), Json_itm_tmp.new_str_(val)); owner.Add(rv); return rv;}
|
||||
public Json_ary Kv_ary(Json_grp owner, String key, Json_itm... subs) {
|
||||
Json_itm key_itm = Json_itm_tmp.new_str_(key);
|
||||
Json_ary val_ary = factory.Ary(-1, -1);
|
||||
Json_kv kv = factory.Kv(key_itm, val_ary);
|
||||
owner.Add(kv);
|
||||
int len = subs.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
val_ary.Add(subs[i]);
|
||||
return val_ary;
|
||||
}
|
||||
Json_doc doc = new Json_doc(); Json_factory factory = new Json_factory();
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,9 +13,20 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import gplx.objects.strings.unicodes.*;
|
||||
import gplx.core.encoders.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Double_;
|
||||
import gplx.Object_;
|
||||
import gplx.String_;
|
||||
import gplx.core.encoders.Hex_utl_;
|
||||
import gplx.objects.strings.unicodes.Ustring;
|
||||
import gplx.objects.strings.unicodes.Ustring_;
|
||||
|
||||
public class Json_doc_wtr {
|
||||
private int indent = -2;
|
||||
private Bry_bfr bfr = Bry_bfr_.Reset(255);
|
||||
@ -96,6 +107,7 @@ public class Json_doc_wtr {
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Kv(boolean comma, String key, byte[] val) {return Kv(comma, Bry_.new_u8(key), val);}
|
||||
public Json_doc_wtr Kv(boolean comma, byte[] key, byte[] val) {
|
||||
Key_internal(comma, key);
|
||||
Str(val);
|
||||
@ -108,12 +120,15 @@ public class Json_doc_wtr {
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Kv(boolean comma, String key, int v) {return Kv(comma, Bry_.new_u8(key), v);}
|
||||
public Json_doc_wtr Kv(boolean comma, byte[] key, int v) {
|
||||
Key_internal(comma, key);
|
||||
Int(v);
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Kv(boolean comma, String key, double v) {return Kv(comma, Bry_.new_u8(key), Bry_.new_u8(Double_.To_str(v)));}
|
||||
public Json_doc_wtr Kv(boolean comma, String key, boolean v) {return Kv(comma, Bry_.new_u8(key), v ? Bool_.Y_bry : Bool_.N_bry);}
|
||||
public Json_doc_wtr Key(boolean comma, String key) {return Key(comma, Bry_.new_u8(key));}
|
||||
public Json_doc_wtr Key(boolean comma, byte[] key) {
|
||||
Key_internal(comma, key);
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
public class Json_factory {
|
||||
public Json_itm Null() {return Json_itm_null.Null;}
|
||||
public Json_itm Bool_n() {return Json_itm_bool.Bool_n;}
|
||||
public Json_itm Bool_y() {return Json_itm_bool.Bool_y;}
|
||||
public Json_itm_int Int(Json_doc doc, int bgn, int end) {return new Json_itm_int(doc, bgn, end);}
|
||||
public Json_itm_long Long(Json_doc doc, int bgn, int end) {return new Json_itm_long(doc, bgn, end);}
|
||||
public Json_itm Decimal(Json_doc doc, int bgn, int end) {return new Json_itm_decimal(doc, bgn, end);}
|
||||
public Json_itm Str(Json_doc doc, int bgn, int end, boolean exact) {return new Json_itm_str(doc, bgn, end, exact);}
|
||||
public Json_kv Kv(Json_itm key, Json_itm val) {return new Json_kv(key, val);}
|
||||
public Json_ary Ary(int bgn, int end) {return new Json_ary(bgn, end);}
|
||||
public Json_nde Nde(Json_doc doc, int bgn) {return new Json_nde(doc, bgn);}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,18 +13,20 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Object_;
|
||||
|
||||
public interface Json_itm {
|
||||
byte Tid();
|
||||
int Src_bgn();
|
||||
int Src_end();
|
||||
Object Data();
|
||||
byte[] Data_bry();
|
||||
void Print_as_json(Bry_bfr bfr, int depth);
|
||||
boolean Data_eq(byte[] comp);
|
||||
void Print_as_json(Bry_bfr bfr, int depth);
|
||||
}
|
||||
class Json_itm_null extends Json_itm_base {
|
||||
Json_itm_null() {this.Ctor(-1, -1);}
|
||||
Json_itm_null() {}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__null;}
|
||||
@Override public Object Data() {return null;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add(Object_.Bry__null);}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,15 +13,20 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
|
||||
public abstract class Json_itm_base implements Json_itm {
|
||||
public abstract byte Tid();
|
||||
public void Ctor(int src_bgn, int src_end) {this.src_bgn = src_bgn; this.src_end = src_end;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} protected int src_end;
|
||||
public abstract Object Data();
|
||||
public abstract byte[] Data_bry();
|
||||
public String Print_as_json() {Bry_bfr bfr = Bry_bfr_.New(); Print_as_json(bfr, 0); return bfr.To_str_and_clear();}
|
||||
public String Print_as_json() {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
Print_as_json(bfr, 0);
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
public abstract void Print_as_json(Bry_bfr bfr, int depth);
|
||||
@gplx.Virtual public boolean Data_eq(byte[] comp) {return false;}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,14 +13,22 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
|
||||
public class Json_itm_bool extends Json_itm_base {
|
||||
private boolean data;
|
||||
public Json_itm_bool(boolean data) {this.data = data; this.Ctor(-1, -1);}
|
||||
private Json_itm_bool(boolean data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override public byte Tid() {return Json_itm_.Tid__bool;}
|
||||
public boolean Data_as_bool() {return data;}
|
||||
@Override public Object Data() {return data;}
|
||||
@Override public byte[] Data_bry() {return data ? Json_itm_.Bry__true : Json_itm_.Bry__false;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add(data ? Json_itm_.Bry__true: Json_itm_.Bry__false);}
|
||||
|
||||
public static final Json_itm_bool Bool_n = new Json_itm_bool(false), Bool_y = new Json_itm_bool(true);
|
||||
public static final Json_itm_bool Get(boolean v) {return v ? Bool_y : Bool_n;}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,20 +13,54 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Decimal_adp;
|
||||
import gplx.Decimal_adp_;
|
||||
import gplx.Double_;
|
||||
import gplx.String_;
|
||||
|
||||
public class Json_itm_decimal extends Json_itm_base {
|
||||
private final Json_doc doc; private Decimal_adp data; private byte[] data_bry;
|
||||
public Json_itm_decimal(Json_doc doc, int src_bgn, int src_end) {this.Ctor(src_bgn, src_end); this.doc = doc;}
|
||||
private final Json_doc doc;
|
||||
private final int src_bgn, src_end;
|
||||
private Decimal_adp data;
|
||||
private byte[] data_bry;
|
||||
|
||||
private Json_itm_decimal(Json_doc doc, int src_bgn, int src_end, Decimal_adp data) {
|
||||
this.doc = doc;
|
||||
this.src_bgn = src_bgn;
|
||||
this.src_end = src_end;
|
||||
this.data = data;
|
||||
}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__decimal;}
|
||||
@Override public Object Data() {return this.Data_as_decimal();}
|
||||
@Override public byte[] Data_bry() {
|
||||
if (data_bry == null) data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end());
|
||||
if (data_bry == null) {
|
||||
data_bry = data == null
|
||||
? Bry_.Mid(doc.Src(), src_bgn, src_end)
|
||||
: Bry_.new_u8(Double_.To_str_loose(data.To_double()));
|
||||
}
|
||||
return data_bry;
|
||||
}
|
||||
public Decimal_adp Data_as_decimal() {
|
||||
if (data == null)
|
||||
data = Decimal_adp_.parse(String_.new_a7(this.Data_bry()));
|
||||
if (data == null) {
|
||||
String s = String_.new_a7(this.Data_bry());
|
||||
s = String_.Replace(s, "e", "E"); // exponent can be either "e" or "E" in JSON, but Java decimal parse only takes "E"; ISSUE#:565; DATE:2020-03-25
|
||||
data = Decimal_adp_.parse(s);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
if (doc == null) {
|
||||
bfr.Add_str_a7(Double_.To_str_loose(data.To_double()));
|
||||
}
|
||||
else {
|
||||
bfr.Add_mid(doc.Src(), src_bgn, src_end);
|
||||
}
|
||||
}
|
||||
|
||||
public static Json_itm_decimal NewByDoc(Json_doc doc, int src_bgn, int src_end) {return new Json_itm_decimal(doc, src_bgn, src_end, null);}
|
||||
public static Json_itm_decimal NewByVal(Decimal_adp val) {return new Json_itm_decimal(null, -1, -1, val);}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,21 +13,52 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Int_;
|
||||
|
||||
public class Json_itm_int extends Json_itm_base {
|
||||
private final Json_doc doc;
|
||||
private byte[] data_bry; private int data; private boolean data_is_null = true;
|
||||
public Json_itm_int(Json_doc doc, int src_bgn, int src_end) {this.Ctor(src_bgn, src_end); this.doc = doc;}
|
||||
private final int src_bgn, src_end;
|
||||
private byte[] data_bry;
|
||||
private int data;
|
||||
private boolean data_needs_making;
|
||||
|
||||
private Json_itm_int(Json_doc doc, int src_bgn, int src_end, boolean data_needs_making, int data) {
|
||||
this.doc = doc;
|
||||
this.src_bgn = src_bgn;
|
||||
this.src_end = src_end;
|
||||
this.data_needs_making = data_needs_making;
|
||||
if (!data_needs_making)
|
||||
this.data = data;
|
||||
}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__int;}
|
||||
@Override public Object Data() {return Data_as_int();}
|
||||
@Override public byte[] Data_bry() {
|
||||
if (data_bry == null) {
|
||||
data_bry = doc == null
|
||||
? Int_.To_bry(data)
|
||||
: Bry_.Mid(doc.Src(), src_bgn, src_end);
|
||||
}
|
||||
return data_bry;
|
||||
}
|
||||
public int Data_as_int() {
|
||||
if (data_is_null) {
|
||||
data = doc.Utl_num_parser().Parse(doc.Src(), Src_bgn(), Src_end()).Rv_as_int();
|
||||
data_is_null = false;
|
||||
if (data_needs_making) {
|
||||
data = doc.Utl_num_parser().Parse(doc.Src(), src_bgn, src_end).Rv_as_int();
|
||||
data_needs_making = false;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@Override public Object Data() {return Data_as_int();}
|
||||
@Override public byte[] Data_bry() {if (data_bry == null) data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end()); return data_bry;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());}
|
||||
public static Json_itm_int cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__int ? null : (Json_itm_int)v;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
if (doc == null)
|
||||
bfr.Add_int_variable(data);
|
||||
else
|
||||
bfr.Add_mid(doc.Src(), src_bgn, src_end);
|
||||
}
|
||||
|
||||
public static Json_itm_int NewByDoc(Json_doc doc, int src_bgn, int src_end) {return new Json_itm_int(doc, src_bgn, src_end, true, -1);}
|
||||
public static Json_itm_int NewByVal(int val) {return new Json_itm_int(null, -1, -1, false, val);}
|
||||
public static Json_itm_int Cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__int ? null : (Json_itm_int)v;}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,21 +13,51 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Long_;
|
||||
|
||||
public class Json_itm_long extends Json_itm_base {
|
||||
private final Json_doc doc;
|
||||
private byte[] data_bry; private long data; private boolean data_is_null = true;
|
||||
public Json_itm_long(Json_doc doc, int src_bgn, int src_end) {this.Ctor(src_bgn, src_end); this.doc = doc;}
|
||||
private final int src_bgn, src_end;
|
||||
private byte[] data_bry;
|
||||
private long data;
|
||||
private boolean data_needs_making = true;
|
||||
private Json_itm_long(Json_doc doc, int src_bgn, int src_end, boolean data_needs_making, long data) {
|
||||
this.doc = doc;
|
||||
this.src_bgn = src_bgn;
|
||||
this.src_end = src_end;
|
||||
this.data_needs_making = data_needs_making;
|
||||
if (!data_needs_making)
|
||||
this.data = data;
|
||||
}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__long;}
|
||||
@Override public Object Data() {return Data_as_long();}
|
||||
@Override public byte[] Data_bry() {
|
||||
if (data_bry == null) {
|
||||
data_bry = doc == null
|
||||
? Bry_.new_u8(Long_.To_str(data))
|
||||
: Bry_.Mid(doc.Src(), src_bgn, src_end);
|
||||
}
|
||||
return data_bry;
|
||||
}
|
||||
public long Data_as_long() {
|
||||
if (data_is_null) {
|
||||
data = doc.Utl_num_parser().Parse(doc.Src(), Src_bgn(), Src_end()).Rv_as_long();
|
||||
data_is_null = false;
|
||||
if (data_needs_making) {
|
||||
data = doc.Utl_num_parser().Parse(doc.Src(), src_bgn, src_end).Rv_as_long();
|
||||
data_needs_making = false;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@Override public Object Data() {return Data_as_long();}
|
||||
@Override public byte[] Data_bry() {if (data_bry == null) data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end()); return data_bry;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());}
|
||||
public static Json_itm_long cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__long ? null : (Json_itm_long)v;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
if (doc == null)
|
||||
bfr.Add_long_variable(data);
|
||||
else
|
||||
bfr.Add_mid(doc.Src(), src_bgn, src_end);
|
||||
}
|
||||
|
||||
public static Json_itm_long NewByDoc(Json_doc doc, int src_bgn, int src_end) {return new Json_itm_long(doc, src_bgn, src_end, true, -1);}
|
||||
public static Json_itm_long NewByVal(long val) {return new Json_itm_long(null, -1, -1, false, val);}
|
||||
public static Json_itm_long Cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__long ? null : (Json_itm_long)v;}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,38 +13,97 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import gplx.core.intls.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.String_;
|
||||
import gplx.core.intls.Utf16_;
|
||||
import gplx.langs.htmls.Gfh_utl;
|
||||
|
||||
public class Json_itm_str extends Json_itm_base {
|
||||
private final boolean exact; private final Json_doc doc;
|
||||
private String data_str; private byte[] data_bry = null;
|
||||
public Json_itm_str(Json_doc doc, int src_bgn, int src_end, boolean exact) {this.Ctor(src_bgn + 1, src_end - 1); this.doc = doc; this.exact = exact;}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__str;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
bfr.Add_byte(Byte_ascii.Quote);
|
||||
gplx.langs.htmls.Gfh_utl.Escape_html_to_bfr(bfr, doc.Src(), this.Src_bgn(), this.Src_end(), true, true, true, true, false); // false to apos for backwards compatibility
|
||||
bfr.Add_byte(Byte_ascii.Quote);
|
||||
private final Json_doc doc;
|
||||
private final int src_bgn, src_end;
|
||||
private String data_str;
|
||||
private byte[] data_bry;
|
||||
private boolean data_needs_making;
|
||||
private boolean escaped;
|
||||
|
||||
private Json_itm_str(Json_doc doc, int src_bgn, int src_end, String data_str, boolean escaped) {
|
||||
this.doc = doc;
|
||||
this.src_bgn = src_bgn;
|
||||
this.src_end = src_end;
|
||||
this.data_str = data_str;
|
||||
this.data_bry = null;
|
||||
this.data_needs_making = true;
|
||||
this.escaped = escaped;
|
||||
}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__str;}
|
||||
@Override public Object Data() {return this.Data_as_str();}
|
||||
public void Overwrite_bry(byte[] v) {
|
||||
this.data_bry = v; //needed by MapLink/MapFrame
|
||||
this.data_needs_making = false;
|
||||
}
|
||||
@Override public byte[] Data_bry() {
|
||||
if (data_bry == null) {
|
||||
data_bry = Data_make_bry();
|
||||
}
|
||||
return data_bry;
|
||||
}
|
||||
public String Data_as_str() {
|
||||
if (data_str == null) {
|
||||
if (data_bry == null)
|
||||
data_bry = Data_make_bry();
|
||||
data_str = String_.new_u8(data_bry);
|
||||
}
|
||||
return data_str;
|
||||
}
|
||||
@Override public byte[] Data_bry() {if (data_bry == null) data_bry = Data_make_bry(); return data_bry;}
|
||||
@Override public boolean Data_eq(byte[] comp) {
|
||||
if (exact) return Bry_.Eq(doc.Src(), this.Src_bgn(), this.Src_end(), comp);
|
||||
if (data_bry == null) data_bry = Data_make_bry();
|
||||
return Bry_.Match(data_bry, comp);
|
||||
return Bry_.Match(this.Data_bry(), comp);
|
||||
}
|
||||
private byte[] Data_make_bry() {
|
||||
byte[] src = doc.Src(); int bgn = this.Src_bgn(), end = this.Src_end();
|
||||
if (exact) return Bry_.Mid(src, bgn, end);
|
||||
Bry_bfr bfr = doc.Bfr();
|
||||
byte[] utf8_bry = doc.Tmp_u8_bry();
|
||||
// data already made; return it;
|
||||
if (!data_needs_making)
|
||||
return data_bry;
|
||||
|
||||
// mark data as made
|
||||
this.data_needs_making = false;
|
||||
|
||||
// get src, bgn, end, depending on whether or not itm is from jdoc or standalone
|
||||
byte[] src;
|
||||
int bgn;
|
||||
int end;
|
||||
if (doc == null) {
|
||||
src = Bry_.new_u8_safe(this.data_str);
|
||||
bgn = 0;
|
||||
end = src == null ? 0 : src.length;
|
||||
}
|
||||
else {
|
||||
src = doc.Src();
|
||||
bgn = src_bgn;
|
||||
end = src_end;
|
||||
}
|
||||
|
||||
// not escaped -> return the src
|
||||
if (!escaped) {
|
||||
this.data_bry = Bry_.Mid(src, bgn, end);
|
||||
return data_bry;
|
||||
}
|
||||
|
||||
// escaped; get some temp vars
|
||||
Bry_bfr bfr;
|
||||
byte[] utf8_bry;
|
||||
if (doc == null) {
|
||||
bfr = Bry_bfr_.New();
|
||||
utf8_bry = new byte[6];
|
||||
}
|
||||
else { // PERF:reuse bfr / bry on jdoc itself
|
||||
bfr = doc.Bfr();
|
||||
utf8_bry = doc.Tmp_u8_bry();
|
||||
}
|
||||
|
||||
// loop and unescape
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
@ -90,6 +149,17 @@ public class Json_itm_str extends Json_itm_base {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bfr.To_bry_and_clear();
|
||||
this.data_bry = bfr.To_bry_and_clear();
|
||||
return data_bry;
|
||||
}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
bfr.Add_byte(Byte_ascii.Quote);
|
||||
byte[] data_bry = this.Data_bry();
|
||||
int data_len = data_bry.length;
|
||||
Gfh_utl.Escape_html_to_bfr(bfr, data_bry, 0, data_len, true, true, true, true, false); // false to apos for backwards compatibility
|
||||
bfr.Add_byte(Byte_ascii.Quote);
|
||||
}
|
||||
|
||||
public static Json_itm_str NewByDoc(Json_doc doc, int src_bgn, int src_end, boolean escaped) {return new Json_itm_str(doc, src_bgn + 1, src_end - 1, null, escaped);}
|
||||
public static Json_itm_str NewByVal(String val) {return new Json_itm_str(null, -1, -1, val, false);}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
public class Json_itm_tmp implements Json_itm { // TEST:
|
||||
public Json_itm_tmp(byte tid, String data) {this.tid = tid; this.data = data;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Data_bry() {return Bry_.new_u8(Object_.Xto_str_strict_or_empty(data));}
|
||||
public int Src_bgn() {return -1;}
|
||||
public int Src_end() {return -1;}
|
||||
public Object Data() {return data;} private String data;
|
||||
public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_str_u8(data);}
|
||||
public boolean Data_eq(byte[] comp) {return false;}
|
||||
public void Clear() {}
|
||||
public static Json_itm new_str_(String v) {return new Json_itm_tmp(Json_itm_.Tid__str, "\"" + v + "\"");}
|
||||
public static Json_itm new_int_(int v) {return new Json_itm_tmp(Json_itm_.Tid__int, Int_.To_str(v));}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,7 +13,11 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Byte_ascii;
|
||||
|
||||
public class Json_kv extends Json_itm_base {
|
||||
public Json_kv(Json_itm key, Json_itm val) {this.key = key; this.val = val;}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__kv;}
|
||||
@ -22,7 +26,7 @@ public class Json_kv extends Json_itm_base {
|
||||
public byte[] Key_as_bry() {return key.Data_bry();}
|
||||
public String Key_as_str() {return (String)key.Data();}
|
||||
public byte[] Val_as_bry() {return val.Data_bry();}
|
||||
public Json_nde Val_as_nde() {return Json_nde.cast(val);}
|
||||
public Json_nde Val_as_nde() {return Json_nde.Cast(val);}
|
||||
public Json_ary Val_as_ary() {return Json_ary.cast(val);}
|
||||
public boolean Key_eq(byte[] comp) {return ((Json_itm_str)key).Data_eq(comp);}
|
||||
@Override public Object Data() {return null;}
|
||||
@ -33,5 +37,5 @@ public class Json_kv extends Json_itm_base {
|
||||
val.Print_as_json(bfr, depth);
|
||||
}
|
||||
public static final Json_kv[] Ary_empty = new Json_kv[0];
|
||||
public static Json_kv cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__kv ? null : (Json_kv)v;}
|
||||
public static Json_kv Cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__kv ? null : (Json_kv)v;}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,36 +13,42 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import org.junit.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_;
|
||||
import gplx.Decimal_adp;
|
||||
import gplx.Decimal_adp_;
|
||||
import gplx.Keyval;
|
||||
import gplx.Keyval_;
|
||||
import gplx.Tfds;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Json_kv_ary_srl_tst {
|
||||
@Before public void init() {fxt.Clear();} private Json_kv_ary_srl_fxt fxt = new Json_kv_ary_srl_fxt();
|
||||
@Test public void Null() {fxt.Test_parse("{'k0':null}" , fxt.ary_(fxt.kv_str_("k0", null)));}
|
||||
@Test public void Bool_n() {fxt.Test_parse("{'k0':false}" , fxt.ary_(fxt.kv_bool_("k0", false)));}
|
||||
@Test public void Num() {fxt.Test_parse("{'k0':123}" , fxt.ary_(fxt.kv_int_("k0", 123)));}
|
||||
@Test public void Str() {fxt.Test_parse("{'k0':'v0'}" , fxt.ary_(fxt.kv_str_("k0", "v0")));}
|
||||
@Test public void Num_dec() {fxt.Test_parse("{'k0':1.23}" , fxt.ary_(fxt.kv_dec_("k0", Decimal_adp_.parse("1.23"))));}
|
||||
@Test public void Ary_int() {fxt.Test_parse("{'k0':[1,2,3]}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_(fxt.kv_int_("1", 1), fxt.kv_int_("2", 2), fxt.kv_int_("3", 3)))));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("{'k0':[]}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_())));}
|
||||
@Test public void Subs_int() {fxt.Test_parse("{'k0':{'k00':1,'k01':2}}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_(fxt.kv_int_("k00", 1), fxt.kv_int_("k01", 2)))));}
|
||||
@Test public void Subs_empty() {fxt.Test_parse("{'k0':{}}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_())));}
|
||||
private final Json_kv_ary_srl_fxt fxt = new Json_kv_ary_srl_fxt();
|
||||
@Test public void Null() {fxt.Test_parse("{'k0':null}" , fxt.ary_(fxt.New_kv_str("k0", null)));}
|
||||
@Test public void Bool_n() {fxt.Test_parse("{'k0':false}" , fxt.ary_(fxt.New_kv_bool("k0", false)));}
|
||||
@Test public void Num() {fxt.Test_parse("{'k0':123}" , fxt.ary_(fxt.New_kv_int("k0", 123)));}
|
||||
@Test public void Num_exp() {fxt.Test_parse("{'k0':1.23e2}" , fxt.ary_(fxt.New_kv_int("k0", 123)));} // exponent can be either "e" or "E" in JSON, but Java decimal parse only takes "E"; ISSUE#:565; DATE:2020-03-25
|
||||
@Test public void Str() {fxt.Test_parse("{'k0':'v0'}" , fxt.ary_(fxt.New_kv_str("k0", "v0")));}
|
||||
@Test public void Num_dec() {fxt.Test_parse("{'k0':1.23}" , fxt.ary_(fxt.New_kv_dec("k0", Decimal_adp_.parse("1.23"))));}
|
||||
@Test public void Ary_int() {fxt.Test_parse("{'k0':[1,2,3]}" , fxt.ary_(fxt.New_kv_obj("k0", fxt.ary_(fxt.New_kv_int("1", 1), fxt.New_kv_int("2", 2), fxt.New_kv_int("3", 3)))));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("{'k0':[]}" , fxt.ary_(fxt.New_kv_obj("k0", fxt.ary_())));}
|
||||
@Test public void Subs_int() {fxt.Test_parse("{'k0':{'k00':1,'k01':2}}" , fxt.ary_(fxt.New_kv_obj("k0", fxt.ary_(fxt.New_kv_int("k00", 1), fxt.New_kv_int("k01", 2)))));}
|
||||
@Test public void Subs_empty() {fxt.Test_parse("{'k0':{}}" , fxt.ary_(fxt.New_kv_obj("k0", fxt.ary_())));}
|
||||
}
|
||||
class Json_kv_ary_srl_fxt {
|
||||
public void Clear() {
|
||||
if (parser == null) {
|
||||
parser = new Json_parser();
|
||||
}
|
||||
} private Json_parser parser;
|
||||
private final Json_parser parser = new Json_parser();
|
||||
public void Test_parse(String raw_str, Keyval[] expd) {
|
||||
byte[] raw_bry = Json_parser_tst.Replace_apos(Bry_.new_u8(raw_str));
|
||||
byte[] raw_bry = Bry_.new_u8(Json_doc.Make_str_by_apos(raw_str));
|
||||
Json_doc doc = parser.Parse(raw_bry);
|
||||
Keyval[] actl = Json_kv_ary_srl.Val_by_itm_nde(doc.Root_nde());
|
||||
Tfds.Eq_str_lines(Keyval_.Ary_to_str(expd), Keyval_.Ary_to_str(actl));
|
||||
}
|
||||
public Keyval[] ary_(Keyval... ary) {return ary;}
|
||||
public Keyval kv_obj_(String key, Object val) {return Keyval_.new_(key, val);}
|
||||
public Keyval kv_str_(String key, String val) {return Keyval_.new_(key, val);}
|
||||
public Keyval kv_int_(String key, int val) {return Keyval_.new_(key, val);}
|
||||
public Keyval kv_bool_(String key, boolean val) {return Keyval_.new_(key, Bool_.To_str_lower(val));}
|
||||
public Keyval kv_dec_(String key, Decimal_adp val) {return Keyval_.new_(key, val.To_str());}
|
||||
public Keyval New_kv_obj(String key, Object val) {return Keyval_.new_(key, val);}
|
||||
public Keyval New_kv_str(String key, String val) {return Keyval_.new_(key, val);}
|
||||
public Keyval New_kv_int(String key, int val) {return Keyval_.new_(key, val);}
|
||||
public Keyval New_kv_bool(String key, boolean val) {return Keyval_.new_(key, Bool_.To_str_lower(val));}
|
||||
public Keyval New_kv_dec(String key, Decimal_adp val) {return Keyval_.new_(key, val.To_str());}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,11 +13,33 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Array_;
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.DateAdp;
|
||||
import gplx.DateAdp_;
|
||||
import gplx.Decimal_adp_;
|
||||
import gplx.Err_;
|
||||
import gplx.Hash_adp_bry;
|
||||
import gplx.Int_;
|
||||
import gplx.Long_;
|
||||
import gplx.String_;
|
||||
|
||||
public class Json_nde extends Json_itm_base implements Json_grp {
|
||||
private Json_itm[] subs = Json_itm_.Ary_empty; private int subs_len = 0, subs_max = 0;
|
||||
private final int src_bgn;
|
||||
private int src_end;
|
||||
private Json_itm[] subs = Json_itm_.Ary_empty;
|
||||
private int subs_len = 0, subs_max = 0;
|
||||
private Hash_adp_bry subs_hash;
|
||||
public Json_nde(Json_doc jdoc, int src_bgn) {this.jdoc = jdoc; this.Ctor(src_bgn, -1);}
|
||||
|
||||
private Json_nde(Json_doc jdoc, int src_bgn) {
|
||||
this.jdoc = jdoc;
|
||||
this.src_bgn = src_bgn;
|
||||
}
|
||||
@Override public byte Tid() {return Json_itm_.Tid__nde;}
|
||||
public Json_doc Doc() {return jdoc;} private final Json_doc jdoc;
|
||||
public void Src_end_(int v) {this.src_end = v;}
|
||||
@ -25,15 +47,23 @@ public class Json_nde extends Json_itm_base implements Json_grp {
|
||||
@Override public byte[] Data_bry() {return null;}
|
||||
public int Len() {return subs_len;}
|
||||
public Json_itm Get_at(int i) {return subs[i];}
|
||||
public Json_itm Get_as_itm_or_null(String key) {return Get_as_itm_or_null(Bry_.new_u8(key));}
|
||||
public Json_itm Get_as_itm_or_null(byte[] key) {if (subs_hash == null) subs_hash = subs_hash_init(); return (Json_itm)subs_hash.Get_by_bry(key);}
|
||||
public Json_ary Get_as_ary(int idx) {return Json_ary.cast(Get_at(idx));}
|
||||
public Json_nde Get_as_nde(String key) {return Json_nde.cast(Get_as_itm_or_null(Bry_.new_u8(key)));}
|
||||
public Json_nde Get_as_nde(int idx) {return Json_nde.cast(Get_at(idx));}
|
||||
public Json_nde Get_as_nde(String key) {return Json_nde.Cast(Get_as_itm_or_null(Bry_.new_u8(key)));}
|
||||
public Json_nde Get_as_nde(int idx) {return Json_nde.Cast(Get_at(idx));}
|
||||
public Json_ary Get_as_ary(String key) {return Get_as_ary(Bry_.new_u8(key));}
|
||||
public Json_ary Get_as_ary(byte[] key) {
|
||||
Json_itm rv = Get_as_itm_or_null(key); if (rv == null) throw Err_.new_("json", "key missing", "key", key);
|
||||
return Json_ary.cast(rv);
|
||||
}
|
||||
public Json_ary Get_as_ary_or_null(String key) {return Get_as_ary_or_null(Bry_.new_u8(key));}
|
||||
public Json_ary Get_as_ary_or_null(byte[] key) {
|
||||
Json_itm rv = Get_as_itm_or_null(key);
|
||||
return rv == null
|
||||
? null
|
||||
: Json_ary.cast(rv);
|
||||
}
|
||||
public byte[] Get_as_bry(String key) {
|
||||
byte[] rv = Get_as_bry_or(Bry_.new_u8(key), null); if (rv == null) throw Err_.new_("json", "key missing", "key", key);
|
||||
return rv;
|
||||
@ -83,21 +113,25 @@ public class Json_nde extends Json_itm_base implements Json_grp {
|
||||
public boolean Has(byte[] key) {return Get_bry(key, null) != null;}
|
||||
public Json_kv Get_at_as_kv(int i) {
|
||||
Json_itm rv_itm = Get_at(i);
|
||||
Json_kv rv = Json_kv.cast(rv_itm); if (rv == null) throw Err_.new_("json", "sub is not kv", "i", i, "src", Bry_.Mid(jdoc.Src(), this.Src_bgn(), src_end));
|
||||
Json_kv rv = Json_kv.Cast(rv_itm);
|
||||
if (rv == null) {
|
||||
byte[] snip = jdoc == null ? Bry_.new_a7("no source") : Bry_.Mid(jdoc.Src(), src_bgn, src_end);
|
||||
throw Err_.new_("json", "sub is not kv", "i", i, "src", snip);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
public Json_kv Get_kv(byte[] key) {return Json_kv.cast(Get_itm(key));}
|
||||
public Json_kv Get_kv(byte[] key) {return Json_kv.Cast(Get_itm(key));}
|
||||
public Json_nde Get(String key) {return Get(Bry_.new_u8(key));}
|
||||
public Json_nde Get(byte[] key) {
|
||||
Json_kv kv = Json_kv.cast(this.Get_itm(key)); if (kv == null) throw Err_.new_("json", "kv not found", "key", key);
|
||||
Json_nde rv = Json_nde.cast(kv.Val()); if (rv == null) throw Err_.new_("json", "nde not found", "key", key);
|
||||
Json_kv kv = Json_kv.Cast(this.Get_itm(key)); if (kv == null) throw Err_.new_("json", "kv not found", "key", key);
|
||||
Json_nde rv = Json_nde.Cast(kv.Val()); if (rv == null) throw Err_.new_("json", "nde not found", "key", key);
|
||||
return rv;
|
||||
}
|
||||
public Json_itm Get_itm(byte[] key) {
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Json_itm itm = subs[i];
|
||||
if (itm.Tid() == Json_itm_.Tid__kv) {
|
||||
if (itm != null && itm.Tid() == Json_itm_.Tid__kv) {
|
||||
Json_kv itm_as_kv = (Json_kv)itm;
|
||||
if (Bry_.Eq(key, itm_as_kv.Key().Data_bry()))
|
||||
return itm;
|
||||
@ -122,6 +156,17 @@ public class Json_nde extends Json_itm_base implements Json_grp {
|
||||
Json_itm val = kv.Val();
|
||||
return (val == null) ? or : val.Data_bry();
|
||||
}
|
||||
public void AddKvBool(String key, boolean val) {AddKv(key, Json_itm_bool.Get(val));}
|
||||
public void AddKvInt(String key, int val) {AddKv(key, Json_itm_int.NewByVal(val));}
|
||||
public void AddKvDouble(String key, double val) {AddKv(key, Json_itm_decimal.NewByVal(Decimal_adp_.double_(val)));}
|
||||
public void AddKvStr(String key, byte[] val) {AddKv(key, Json_itm_str.NewByVal(String_.new_u8(val)));}
|
||||
public void AddKvStr(String key, String val) {AddKv(key, Json_itm_str.NewByVal(val));}
|
||||
public void AddKvNde(String key, Json_nde val) {AddKv(key, val);}
|
||||
public void AddKvAry(String key, Json_ary val) {AddKv(key, val);}
|
||||
private void AddKv(String key, Json_itm val) {
|
||||
Json_kv rv = new Json_kv(Json_itm_str.NewByVal(key), val);
|
||||
Add(rv);
|
||||
}
|
||||
public Json_nde Add_many(Json_itm... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
@ -165,5 +210,8 @@ public class Json_nde extends Json_itm_base implements Json_grp {
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static Json_nde cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__nde ? null : (Json_nde)v;}
|
||||
|
||||
public static Json_nde NewByDoc(Json_doc doc, int src_bgn) {return new Json_nde(doc, src_bgn);}
|
||||
public static Json_nde NewByVal() {return new Json_nde(null, -1);}
|
||||
public static Json_nde Cast(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid__nde ? null : (Json_nde)v;}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,16 +13,26 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import gplx.core.primitives.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Char_;
|
||||
import gplx.Err;
|
||||
import gplx.Err_;
|
||||
import gplx.Int_;
|
||||
import gplx.String_;
|
||||
import gplx.core.primitives.Gfo_number_parser;
|
||||
|
||||
public class Json_parser {
|
||||
private byte[] src; private int src_len, pos; private final Gfo_number_parser num_parser = new Gfo_number_parser();
|
||||
public Json_factory Factory() {return factory;} private final Json_factory factory = new Json_factory();
|
||||
private byte[] src;
|
||||
private int src_len, pos;
|
||||
private final Gfo_number_parser num_parser = new Gfo_number_parser();
|
||||
public Json_doc Parse_by_apos_ary(String... ary) {return Parse_by_apos(String_.Concat_lines_nl(ary));}
|
||||
public Json_doc Parse_by_apos(String s) {return Parse(Bry_.Replace(Bry_.new_u8(s), Byte_ascii.Apos, Byte_ascii.Quote));}
|
||||
public Json_doc Parse(String src) {return Parse(Bry_.new_u8(src));}
|
||||
public Json_doc Parse(byte[] src) {
|
||||
synchronized (factory) {
|
||||
this.src = src; if (src == null) return null;
|
||||
this.src_len = src.length; if (src_len == 0) return null;
|
||||
this.pos = 0;
|
||||
@ -43,10 +53,9 @@ public class Json_parser {
|
||||
doc.Ctor(src, root);
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
private Json_nde Make_nde(Json_doc doc) {
|
||||
++pos; // brack_bgn
|
||||
Json_nde nde = new Json_nde(doc, pos);
|
||||
Json_nde nde = Json_nde.NewByDoc(doc, pos);
|
||||
while (pos < src_len) {
|
||||
Skip_ws();
|
||||
if (src[pos] == Byte_ascii.Curly_end) {++pos; return nde;}
|
||||
@ -72,9 +81,9 @@ public class Json_parser {
|
||||
while (pos < src_len) {
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Ltr_n: return Make_literal(Bry_null_ull , 3, factory.Null());
|
||||
case Byte_ascii.Ltr_f: return Make_literal(Bry_bool_alse , 4, factory.Bool_n());
|
||||
case Byte_ascii.Ltr_t: return Make_literal(Bry_bool_rue , 3, factory.Bool_y());
|
||||
case Byte_ascii.Ltr_n: return Make_literal(Bry_null_ull , 3, Json_itm_null.Null);
|
||||
case Byte_ascii.Ltr_f: return Make_literal(Bry_bool_alse , 4, Json_itm_bool.Bool_n);
|
||||
case Byte_ascii.Ltr_t: return Make_literal(Bry_bool_rue , 3, Json_itm_bool.Bool_y);
|
||||
case Byte_ascii.Quote: return Make_string(doc);
|
||||
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:
|
||||
@ -97,7 +106,7 @@ public class Json_parser {
|
||||
}
|
||||
private Json_itm Make_string(Json_doc doc) {
|
||||
int bgn = pos++; // ++: quote_bgn
|
||||
boolean exact = true;
|
||||
boolean escaped = false;
|
||||
while (pos < src_len) {
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Backslash:
|
||||
@ -106,10 +115,10 @@ public class Json_parser {
|
||||
case Byte_ascii.Ltr_u: pos += 5; break; // \uFFFF 1 u + 4 hex-dec; ISSUE#:486; DATE:2019-06-02
|
||||
default: ++pos; break; // \? " \ / b f n r t
|
||||
}
|
||||
exact = false;
|
||||
escaped = true;
|
||||
break;
|
||||
case Byte_ascii.Quote:
|
||||
return factory.Str(doc, bgn, ++pos, exact); // ++: quote_end
|
||||
return Json_itm_str.NewByDoc(doc, bgn, ++pos, escaped); // ++: quote_end
|
||||
default:
|
||||
++pos;
|
||||
break;
|
||||
@ -139,16 +148,16 @@ public class Json_parser {
|
||||
}
|
||||
num_parser.Parse(src, num_bgn, pos);
|
||||
if (num_parser.Has_frac())
|
||||
return factory.Decimal(doc, num_bgn, pos);
|
||||
return Json_itm_decimal.NewByDoc(doc, num_bgn, pos);
|
||||
else {
|
||||
if (num_parser.Is_int())
|
||||
return factory.Int(doc, num_bgn, pos);
|
||||
return Json_itm_int.NewByDoc(doc, num_bgn, pos);
|
||||
else
|
||||
return factory.Long(doc, num_bgn, pos);
|
||||
return Json_itm_long.NewByDoc(doc, num_bgn, pos);
|
||||
}
|
||||
}
|
||||
private Json_ary Make_ary(Json_doc doc) {
|
||||
Json_ary rv = factory.Ary(pos++, pos); // brack_bgn
|
||||
Json_ary rv = Json_ary.NewByDoc(doc, pos++, pos); // brack_bgn
|
||||
while (pos < src_len) {
|
||||
Skip_ws();
|
||||
if (src[pos] == Byte_ascii.Brack_end) {++pos; return rv;}
|
||||
@ -181,4 +190,8 @@ public class Json_parser {
|
||||
return Err_.new_wo_type(msg);
|
||||
}
|
||||
private static final byte[] Bry_bool_rue = Bry_.new_a7("rue"), Bry_bool_alse = Bry_.new_a7("alse"), Bry_null_ull = Bry_.new_a7("ull");
|
||||
public static Json_doc ParseToJdoc(String src) {
|
||||
Json_parser parser = new Json_parser();
|
||||
return parser.Parse(src);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,13 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import gplx.core.primitives.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Keyval_;
|
||||
import gplx.Ordered_hash;
|
||||
import gplx.String_;
|
||||
import gplx.core.primitives.Int_obj_val;
|
||||
|
||||
public class Json_parser__list_nde__base extends Json_parser__itm__base {
|
||||
public void Parse_grp(String context, Json_grp grp) {
|
||||
this.context = context;
|
||||
@ -22,11 +27,11 @@ public class Json_parser__list_nde__base extends Json_parser__itm__base {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Json_nde sub = null;
|
||||
if (grp.Tid() == Json_itm_.Tid__nde) {
|
||||
Json_kv kv = Json_nde.cast(grp).Get_at_as_kv(i);
|
||||
Json_kv kv = Json_nde.Cast(grp).Get_at_as_kv(i);
|
||||
sub = kv.Val_as_nde();
|
||||
}
|
||||
else {
|
||||
sub = Json_nde.cast(grp.Get_at(i));
|
||||
sub = Json_nde.Cast(grp.Get_at(i));
|
||||
}
|
||||
Parse_nde(context, sub);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,83 +13,92 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.jsons; import gplx.*; import gplx.langs.*;
|
||||
import org.junit.*;
|
||||
package gplx.langs.jsons;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_bfr;
|
||||
import gplx.Bry_bfr_;
|
||||
import gplx.Decimal_adp;
|
||||
import gplx.Decimal_adp_;
|
||||
import gplx.Tfds;
|
||||
import gplx.core.tests.Gftest;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Json_parser_tst {
|
||||
private final Json_parser_fxt fxt = new Json_parser_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Null() {fxt.Test_parse_val0("{'k0':null}" , null);}
|
||||
@Test public void Bool_n() {fxt.Test_parse_val0("{'k0':false}" , false);}
|
||||
@Test public void Bool_y() {fxt.Test_parse_val0("{'k0':true}" , true);}
|
||||
@Test public void Num() {fxt.Test_parse_val0("{'k0':123}" , 123);}
|
||||
@Test public void Num_neg() {fxt.Test_parse_val0("{'k0':-123}" , -123);}
|
||||
@Test public void Str() {fxt.Test_parse_val0("{'k0':'v0'}" , "v0");}
|
||||
@Test public void Str_esc_quote() {fxt.Test_parse_val0("{'k0':'a\\\"b'}" , "a\"b");}
|
||||
@Test public void Str_encoded_basic() {fxt.Test_parse_val0("{'k0':'a\\u0021b'}" , "a!b");}
|
||||
@Test public void Str_encoded_surrogate() {fxt.Test_parse_val0("{'k0':'a\\ud83c\\udf0eb'}", "a🌎b");} // check for UTF surrogate-pairs; symbol is earth globe americas (U+1F30E); ISSUE#:487; DATE:2019-06-02
|
||||
@Test public void Num_dec() {fxt.Test_parse("{'k0':1.23}" , fxt.itm_nde_().Add_many(fxt.itm_kv_dec_("k0", "1.23")));}
|
||||
@Test public void Num_exp() {fxt.Test_parse("{'k0':1e+2}" , fxt.itm_nde_().Add_many(fxt.itm_kv_dec_("k0", "1e+2")));}
|
||||
@Test public void Num_mix() {fxt.Test_parse("{'k0':-1.23e-1}" , fxt.itm_nde_().Add_many(fxt.itm_kv_dec_("k0", "-1.23e-1")));}
|
||||
@Test public void Str_many() {fxt.Test_parse("{'k0':'v0','k1':'v1','k2':'v2'}", fxt.itm_nde_().Add_many(fxt.itm_kv_("k0", "v0"), fxt.itm_kv_("k1", "v1"), fxt.itm_kv_("k2", "v2")));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("{'k0':[]}", fxt.itm_nde_().Add_many(fxt.itm_kv_ary_int_("k0")));}
|
||||
@Test public void Ary_int() {fxt.Test_parse("{'k0':[1,2,3]}", fxt.itm_nde_().Add_many(fxt.itm_kv_ary_int_("k0", 1, 2, 3)));}
|
||||
@Test public void Ary_str() {fxt.Test_parse("{'k0':['a','b','c']}", fxt.itm_nde_().Add_many(fxt.itm_kv_ary_str_("k0", "a", "b", "c")));}
|
||||
@Test public void Ary_ws() {fxt.Test_parse("{'k0': [ 1 , 2 , 3 ] }", fxt.itm_nde_().Add_many(fxt.itm_kv_ary_int_("k0", 1, 2, 3)));}
|
||||
@Test public void Subs_int() {fxt.Test_parse("{'k0':{'k00':1}}", fxt.itm_nde_().Add_many(fxt.itm_kv_("k0", fxt.itm_nde_().Add_many(fxt.itm_kv_("k00", 1)))));}
|
||||
@Test public void Subs_empty() {fxt.Test_parse("{'k0':{}}", fxt.itm_nde_().Add_many(fxt.itm_kv_("k0", fxt.itm_nde_())));}
|
||||
@Test public void Subs_ws() {fxt.Test_parse("{'k0': { 'k00' : 1 } }", fxt.itm_nde_().Add_many(fxt.itm_kv_("k0", fxt.itm_nde_().Add_many(fxt.itm_kv_("k00", 1)))));}
|
||||
@Test public void Ws() {fxt.Test_parse(" { 'k0' : 'v0' } ", fxt.itm_nde_().Add_many(fxt.itm_kv_("k0", "v0")));}
|
||||
@Test public void Root_is_ary() {fxt.Test_parse("[ 1 , 2 , 3 ]", fxt.itm_ary_().Add_many(fxt.itm_int_(1), fxt.itm_int_(2), fxt.itm_int_(3)));}
|
||||
public static String Replace_apos_as_str(String v) {return String_.new_u8(Replace_apos(Bry_.new_u8(v)));}
|
||||
public static byte[] Replace_apos(byte[] v) {return Bry_.Replace(v, Byte_ascii.Apos, Byte_ascii.Quote);}
|
||||
@Test public void Null() {fxt.Test_parse_obj("{'k0':null}" , null);}
|
||||
@Test public void Bool_n() {fxt.Test_parse_obj("{'k0':false}" , false);}
|
||||
@Test public void Bool_y() {fxt.Test_parse_obj("{'k0':true}" , true);}
|
||||
@Test public void Num() {fxt.Test_parse_obj("{'k0':123}" , 123);}
|
||||
@Test public void Num_neg() {fxt.Test_parse_obj("{'k0':-123}" , -123);}
|
||||
@Test public void Str() {fxt.Test_parse_obj("{'k0':'v0'}" , "v0");}
|
||||
@Test public void Str_esc_quote() {fxt.Test_parse_obj("{'k0':'a\\\"b'}" , "a\"b");}
|
||||
@Test public void Str_encoded_basic() {fxt.Test_parse_obj("{'k0':'a\\u0021b'}" , "a!b");}
|
||||
@Test public void Str_encoded_surrogate() {fxt.Test_parse_obj("{'k0':'a\\ud83c\\udf0eb'}", "a🌎b");} // check for UTF surrogate-pairs; symbol is earth globe americas (U+1F30E); ISSUE#:487; DATE:2019-06-02
|
||||
@Test public void Num_dec() {fxt.Test_parse_dec("{'k0':1.23}" , Decimal_adp_.parse("1.23"));}
|
||||
@Test public void Num_exp() {fxt.Test_parse_obj("{'k0':1e+2}" , 100);}
|
||||
@Test public void Num_mix() {fxt.Test_parse_dec("{'k0':-1.23e-1}" , Decimal_adp_.parse("-1.23e-1"));}
|
||||
@Test public void Str_many() {fxt.Test_parse("{'k0':'v0','k1':'v1','k2':'v2'}" , fxt.Init_nde().Add_many(fxt.Init_kv("k0", "v0"), fxt.Init_kv("k1", "v1"), fxt.Init_kv("k2", "v2")));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("{'k0':[]}" , fxt.Init_nde().Add_many(fxt.Init_kv_ary_int("k0")));}
|
||||
@Test public void Ary_int() {fxt.Test_parse("{'k0':[1,2,3]}" , fxt.Init_nde().Add_many(fxt.Init_kv_ary_int("k0", 1, 2, 3)));}
|
||||
@Test public void Ary_str() {fxt.Test_parse("{'k0':['a','b','c']}" , fxt.Init_nde().Add_many(fxt.Init_kvary_str_("k0", "a", "b", "c")));}
|
||||
@Test public void Ary_ws() {fxt.Test_parse("{'k0': [ 1 , 2 , 3 ] }" , fxt.Init_nde().Add_many(fxt.Init_kv_ary_int("k0", 1, 2, 3)));}
|
||||
@Test public void Subs_int() {fxt.Test_parse("{'k0':{'k00':1}}" , fxt.Init_nde().Add_many(fxt.Init_kv("k0", fxt.Init_nde().Add_many(fxt.Init_kv("k00", 1)))));}
|
||||
@Test public void Subs_empty() {fxt.Test_parse("{'k0':{}}" , fxt.Init_nde().Add_many(fxt.Init_kv("k0", fxt.Init_nde())));}
|
||||
@Test public void Subs_ws() {fxt.Test_parse("{'k0': { 'k00' : 1 } }" , fxt.Init_nde().Add_many(fxt.Init_kv("k0", fxt.Init_nde().Add_many(fxt.Init_kv("k00", 1)))));}
|
||||
@Test public void Ws() {fxt.Test_parse(" { 'k0' : 'v0' } " , fxt.Init_nde().Add_many(fxt.Init_kv("k0", "v0")));}
|
||||
@Test public void Root_is_ary() {fxt.Test_parse("[1,2,3]" , fxt.Init_ary().Add_many(fxt.Init_int(1), fxt.Init_int(2), fxt.Init_int(3)));}
|
||||
}
|
||||
class Json_parser_fxt {
|
||||
public void Clear() {
|
||||
if (parser == null) {
|
||||
parser = new Json_parser();
|
||||
factory = parser.Factory();
|
||||
}
|
||||
} Json_parser parser; Json_factory factory; Bry_bfr tmp_bfr = Bry_bfr_.Reset(255);
|
||||
public Json_itm itm_int_(int v) {return Json_itm_tmp.new_int_(v);}
|
||||
Json_itm itm_str_(String v) {return Json_itm_tmp.new_str_(v);}
|
||||
public Json_ary itm_ary_() {return factory.Ary(-1, -1);}
|
||||
public Json_nde itm_nde_() {return factory.Nde(null, -1);}
|
||||
public Json_kv itm_kv_null_(String k) {return factory.Kv(itm_str_(k), factory.Null());}
|
||||
public Json_kv itm_kv_(String k, String v) {return factory.Kv(itm_str_(k), itm_str_(v));}
|
||||
public Json_kv itm_kv_(String k, int v) {return factory.Kv(itm_str_(k), itm_int_(v));}
|
||||
public Json_kv itm_kv_(String k, boolean v) {return factory.Kv(itm_str_(k), v ? factory.Bool_y() : factory.Bool_n());}
|
||||
public Json_kv itm_kv_dec_(String k, String v) {return factory.Kv(itm_str_(k), new Json_itm_tmp(Json_itm_.Tid__decimal, v));}
|
||||
public Json_kv itm_kv_(String k, Json_nde v) {return factory.Kv(itm_str_(k), v);}
|
||||
public Json_kv itm_kv_ary_int_(String k, int... v) {
|
||||
Json_ary ary = factory.Ary(-1, -1);
|
||||
private final Json_parser parser = new Json_parser();
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.Reset(255);
|
||||
public Json_itm Init_int(int v) {return Json_itm_int.NewByVal(v);}
|
||||
public Json_itm Init_str(String v) {return Json_itm_str.NewByVal(v);}
|
||||
public Json_ary Init_ary() {return Json_ary.NewByVal();}
|
||||
public Json_nde Init_nde() {return Json_nde.NewByVal();}
|
||||
public Json_kv Init_kv_null(String k) {return new Json_kv(Init_str(k), Json_itm_null.Null);}
|
||||
public Json_kv Init_kv(String k, String v) {return new Json_kv(Init_str(k), Init_str(v));}
|
||||
public Json_kv Init_kv(String k, int v) {return new Json_kv(Init_str(k), Init_int(v));}
|
||||
public Json_kv Init_kv(String k, boolean v) {return new Json_kv(Init_str(k), v ? Json_itm_bool.Bool_y : Json_itm_bool.Bool_n);}
|
||||
public Json_kv Init_kv(String k, Json_nde v) {return new Json_kv(Init_str(k), v);}
|
||||
public Json_kv Init_kv_ary_int(String k, int... v) {
|
||||
Json_ary ary = Json_ary.NewByVal();
|
||||
int len = v.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
ary.Add(itm_int_(v[i]));
|
||||
return factory.Kv(itm_str_(k), ary);
|
||||
ary.Add(Init_int(v[i]));
|
||||
return new Json_kv(Init_str(k), ary);
|
||||
}
|
||||
public Json_kv itm_kv_ary_str_(String k, String... v) {
|
||||
Json_ary ary = factory.Ary(-1, -1);
|
||||
public Json_kv Init_kvary_str_(String k, String... v) {
|
||||
Json_ary ary = Json_ary.NewByVal();
|
||||
int len = v.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
ary.Add(itm_str_(v[i]));
|
||||
return factory.Kv(itm_str_(k), ary);
|
||||
ary.Add(Init_str(v[i]));
|
||||
return new Json_kv(Init_str(k), ary);
|
||||
}
|
||||
public void Test_parse(String raw_str, Json_itm... expd_ary) {
|
||||
byte[] raw = Json_parser_tst.Replace_apos(Bry_.new_u8(raw_str));
|
||||
byte[] raw = Bry_.new_u8(Json_doc.Make_str_by_apos(raw_str));
|
||||
Json_doc doc = parser.Parse(raw);
|
||||
doc.Root_grp().Print_as_json(tmp_bfr, 0);
|
||||
String actl = tmp_bfr.To_str_and_clear();
|
||||
String expd = Xto_str(raw, doc, expd_ary, 0, expd_ary.length);
|
||||
Tfds.Eq_str_lines(expd, actl, actl);
|
||||
}
|
||||
public void Test_parse_val0(String raw_str, Object expd) {
|
||||
byte[] raw = Json_parser_tst.Replace_apos(Bry_.new_u8(raw_str));
|
||||
Json_doc doc = parser.Parse(raw);
|
||||
Json_kv kv = Json_kv.cast(doc.Root_nde().Get_at(0)); // assume root has kv as first sub; EX: {"a":"b"}
|
||||
public void Test_parse_obj(String raw_str, Object expd) {
|
||||
Json_kv kv = Parse_and_get_kv0(raw_str);
|
||||
Object actl = kv.Val().Data(); // NOTE: Data_bry is escaped val; EX: a\"b has DataBry of a"b
|
||||
Tfds.Eq(expd, actl);
|
||||
Gftest.Eq__obj_or_null(expd, actl);
|
||||
}
|
||||
String Xto_str(byte[] raw, Json_doc doc, Json_itm[] ary, int bgn, int end) {
|
||||
public void Test_parse_dec(String raw_str, Decimal_adp expd) {
|
||||
Json_kv kv = Parse_and_get_kv0(raw_str);
|
||||
Json_itm_decimal decimal_itm = (Json_itm_decimal)kv.Val();
|
||||
Gftest.Eq__bool(true, decimal_itm.Data_as_decimal().Eq(expd));
|
||||
}
|
||||
private Json_kv Parse_and_get_kv0(String raw_str) {
|
||||
byte[] raw = Bry_.new_u8(Json_doc.Make_str_by_apos(raw_str));
|
||||
Json_doc doc = parser.Parse(raw);
|
||||
return Json_kv.Cast(doc.Root_nde().Get_at(0)); // assume root has kv as first sub; EX: {"a":"b"}
|
||||
}
|
||||
private String Xto_str(byte[] raw, Json_doc doc, Json_itm[] ary, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
Json_itm itm = ary[i];
|
||||
itm.Print_as_json(tmp_bfr, 0);
|
||||
|
112
400_xowa/src/gplx/langs/mustaches/JsonMustacheNde.java
Normal file
112
400_xowa/src/gplx/langs/mustaches/JsonMustacheNde.java
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
|
||||
You may use XOWA according to either of these licenses as is most appropriate
|
||||
for your project on a case-by-case basis.
|
||||
|
||||
The terms of each license can be found in the source code repository:
|
||||
|
||||
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.langs.mustaches;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_;
|
||||
import gplx.String_;
|
||||
import gplx.langs.jsons.Json_ary;
|
||||
import gplx.langs.jsons.Json_itm;
|
||||
import gplx.langs.jsons.Json_itm_;
|
||||
import gplx.langs.jsons.Json_kv;
|
||||
import gplx.langs.jsons.Json_nde;
|
||||
import gplx.objects.Object_;
|
||||
|
||||
public class JsonMustacheNde implements Mustache_doc_itm {
|
||||
private final Json_nde nde;
|
||||
public JsonMustacheNde(Json_nde nde) {this.nde = nde;}
|
||||
public boolean Mustache__write(String key, Mustache_bfr bfr) {
|
||||
Json_itm itm = nde.Get_itm(Bry_.new_u8(key));
|
||||
if (itm == null) { // mustacheKey does not exist in current jsonNde
|
||||
return false;
|
||||
}
|
||||
else { // mustacheKey exists
|
||||
switch (itm.Tid()) {
|
||||
// array / bool node -> ignore; EX: `{{#person}}Never shown{{/person}}`
|
||||
case Json_itm_.Tid__bool:
|
||||
case Json_itm_.Tid__ary:
|
||||
case Json_itm_.Tid__nde:
|
||||
return false;
|
||||
// item node -> render it; EX: `Hello {{name}}`
|
||||
default:
|
||||
bfr.Add_bry(Json_kv.Cast(itm).Val_as_bry());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
public Mustache_doc_itm[] Mustache__subs(String key) {
|
||||
Json_itm itm = nde.Get_itm(Bry_.new_u8(key));
|
||||
if (itm == null) { // mustacheKey does not exist in current jsonNde
|
||||
return Mustache_doc_itm_.Ary__bool__n;
|
||||
}
|
||||
else { // mustacheKey exists
|
||||
if (itm.Tid() == Json_itm_.Tid__kv) {
|
||||
Json_kv kv = Json_kv.Cast(itm);
|
||||
switch (kv.Val().Tid()) {
|
||||
// bool node -> render; EX: `{{#person}}Never shown{{/person}}`
|
||||
case Json_itm_.Tid__bool:
|
||||
boolean dataVal = Bool_.Cast(kv.Val().Data());
|
||||
return dataVal ? Mustache_doc_itm_.Ary__bool__y : Mustache_doc_itm_.Ary__bool__n;
|
||||
// array node -> render; EX: `{{#repo}} <b>{{name}}</b>{{/repo}}`
|
||||
case Json_itm_.Tid__ary:
|
||||
return ToJsonMustachNdeAry(itm);
|
||||
// item node -> render only if key matchers
|
||||
default:
|
||||
return new Mustache_doc_itm[] {new JsonMustacheVal(true, key, kv.Val().Data())};
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Mustache_doc_itm_.Ary__bool__n;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static Mustache_doc_itm[] ToJsonMustachNdeAry(Json_itm itm) {
|
||||
Json_ary dataAry = Json_ary.cast_or_null(Json_kv.Cast(itm).Val());
|
||||
int subs_len = dataAry.Len();
|
||||
Mustache_doc_itm[] rv = new Mustache_doc_itm[subs_len];
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Json_itm sub = dataAry.Get_at(i);
|
||||
if (sub.Tid() == Json_itm_.Tid__nde) {
|
||||
rv[i] = new JsonMustacheNde((Json_nde)sub);
|
||||
}
|
||||
else {
|
||||
rv[i] = new JsonMustacheVal(false, Mustache_tkn_def.ItemString, sub.Data());
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class JsonMustacheVal implements Mustache_doc_itm {
|
||||
private final boolean fromArray;
|
||||
private final String jsonKey;
|
||||
private final Object jsonVal;
|
||||
public JsonMustacheVal(boolean fromArray, String jsonKey, Object jsonVal) {
|
||||
this.fromArray = fromArray;
|
||||
this.jsonKey = jsonKey;
|
||||
this.jsonVal = jsonVal;
|
||||
}
|
||||
public boolean Mustache__write(String mustacheKey, Mustache_bfr bfr) {
|
||||
if ( (String_.Eq(mustacheKey, jsonKey)) // print if `{{match}}`; EX: `{{#prop}}{{prop}}{{/prop}}`
|
||||
|| (String_.Eq(mustacheKey, Mustache_tkn_def.ItemString) && fromArray)) { // print if `{{.}}` and from array; EX: `{{#array}}{{.}}{{/array}}`
|
||||
bfr.Add_bry(Bry_.new_u8(Object_.To_str(jsonVal)));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public Mustache_doc_itm[] Mustache__subs(String key) {return Mustache_doc_itm_.Ary__empty;}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,8 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.mustaches; import gplx.*; import gplx.langs.*;
|
||||
import gplx.langs.jsons.*;
|
||||
package gplx.langs.mustaches;
|
||||
|
||||
public interface Mustache_doc_itm {
|
||||
boolean Mustache__write(String key, Mustache_bfr bfr);
|
||||
Mustache_doc_itm[] Mustache__subs(String key);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,8 +13,18 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.mustaches; import gplx.*; import gplx.langs.*;
|
||||
import org.junit.*; import gplx.core.primitives.*;
|
||||
package gplx.langs.mustaches;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Hash_adp;
|
||||
import gplx.Hash_adp_;
|
||||
import gplx.Tfds;
|
||||
import gplx.core.primitives.Bool_obj_ref;
|
||||
import gplx.langs.jsons.Json_doc;
|
||||
import gplx.langs.jsons.Json_nde;
|
||||
import gplx.langs.jsons.Json_parser;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Mustache_itm_render_tst {
|
||||
private final Mustache_itm_render_fxt fxt = new Mustache_itm_render_fxt();
|
||||
@Test public void Text() {
|
||||
@ -121,6 +131,13 @@ public class Mustache_itm_render_tst {
|
||||
, "a1"
|
||||
);
|
||||
}
|
||||
@Test public void Dot() {
|
||||
fxt.Test__parse
|
||||
( "{'subs':['a', 'b', 'c', 'd']}"
|
||||
, "{{#subs}}{{.}},{{/subs}}"
|
||||
, "a,b,c,d,"
|
||||
);
|
||||
}
|
||||
}
|
||||
class Mustache_itm_render_fxt {
|
||||
private final Mustache_tkn_parser parser = new Mustache_tkn_parser();
|
||||
@ -136,6 +153,16 @@ class Mustache_itm_render_fxt {
|
||||
actl_itm.Render(bfr, ctx);
|
||||
Tfds.Eq_str_lines(expd, bfr.To_str_and_clear());
|
||||
}
|
||||
public void Test__parse(String jdoc, String src_str, String expd) {
|
||||
Json_nde jnde = Json_parser.ParseToJdoc(Json_doc.Make_str_by_apos(jdoc)).Root_nde();
|
||||
JsonMustacheNde nde = new JsonMustacheNde(jnde);
|
||||
|
||||
byte[] src_bry = Bry_.new_a7(src_str);
|
||||
Mustache_tkn_itm actl_itm = parser.Parse(src_bry, 0, src_bry.length);
|
||||
ctx.Init(nde);
|
||||
actl_itm.Render(bfr, ctx);
|
||||
Tfds.Eq_str_lines(expd, bfr.To_str_and_clear());
|
||||
}
|
||||
}
|
||||
class Mustache_doc_itm__mock implements Mustache_doc_itm {
|
||||
private final Hash_adp hash_prop = Hash_adp_.New(), hash_bool = Hash_adp_.New(), hash_subs = Hash_adp_.New();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,15 +13,24 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.mustaches; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.mustaches;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.List_adp;
|
||||
import gplx.List_adp_;
|
||||
|
||||
public class Mustache_render_ctx {
|
||||
private final List_adp stack = List_adp_.New();
|
||||
private Mustache_doc_itm cur;
|
||||
private Mustache_doc_itm[] subs; private int subs_idx, subs_len; private byte cur_is_bool;
|
||||
private Mustache_doc_itm[] subs;
|
||||
private int subs_idx, subs_len;
|
||||
private byte cur_is_bool;
|
||||
|
||||
public Mustache_render_ctx Init(Mustache_doc_itm cur) {
|
||||
this.cur = cur;
|
||||
this.subs = null;
|
||||
this.subs_idx = subs_len = 0; this.cur_is_bool = Bool_.__byte;
|
||||
this.subs_idx = subs_len = 0;
|
||||
this.cur_is_bool = Bool_.__byte;
|
||||
return this;
|
||||
}
|
||||
public boolean Render_variable(Mustache_bfr bfr, String key) {
|
||||
@ -30,10 +39,12 @@ public class Mustache_render_ctx {
|
||||
Mustache_doc_itm itm = cur;
|
||||
while (itm != Mustache_doc_itm_.Null_itm) {
|
||||
boolean resolved = itm.Mustache__write(key, bfr);
|
||||
// current itm handles key -> exit
|
||||
if (resolved) {
|
||||
rv = true;
|
||||
break;
|
||||
}
|
||||
// current itm does not handle key -> go up stack
|
||||
else {
|
||||
--stack_pos;
|
||||
if (stack_pos == -1) // nothing else in stack
|
||||
@ -47,12 +58,15 @@ public class Mustache_render_ctx {
|
||||
public void Section_bgn(String key) {
|
||||
Mustache_stack_itm stack_itm = new Mustache_stack_itm(cur, subs, subs_idx, subs_len, cur_is_bool); // note that cur is "owner" since subs_idx == 0
|
||||
stack.Add(stack_itm);
|
||||
subs = cur.Mustache__subs(key); if (subs == null) subs = Mustache_doc_itm_.Ary__empty; // subs == null if property does not exist; EX: "folder{{#files}}file{{/files}}" and folder = new Folder(File[0]);
|
||||
subs = cur.Mustache__subs(key);
|
||||
if (subs == null) // subs == null if property does not exist; EX: "folder{{#files}}file{{/files}}" and folder = new Folder(File[0]);
|
||||
subs = Mustache_doc_itm_.Ary__empty;
|
||||
subs_len = subs.length;
|
||||
subs_idx = -1;
|
||||
}
|
||||
public boolean Section_do(boolean inverted) {
|
||||
if (++subs_idx >= subs_len) return false;
|
||||
if (++subs_idx >= subs_len)
|
||||
return false;
|
||||
Mustache_doc_itm sub = subs[subs_idx];
|
||||
if (subs_idx == 0) { // special logic to handle 1st item; note that there always be at least one item
|
||||
if (sub == Mustache_doc_itm_.Itm__bool__n) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,7 +13,13 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.mustaches; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.mustaches;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Byte_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.String_;
|
||||
|
||||
class Mustache_tkn_def {
|
||||
public byte[] Variable_lhs = Dflt_variable_lhs;
|
||||
public byte[] Variable_rhs = Dflt_variable_rhs;
|
||||
@ -31,9 +37,13 @@ class Mustache_tkn_def {
|
||||
, Grp_end = Byte_ascii.Slash // {{/section}}
|
||||
, Inverted = Byte_ascii.Pow // {{^inverted}}
|
||||
, Comment = Byte_ascii.Bang // {{!comment}}
|
||||
, Partial = Byte_ascii.Angle_bgn // {{>partial}}
|
||||
, Partial = Byte_ascii.Angle_end // {{>partial}}
|
||||
, Delimiter_bgn = Byte_ascii.Eq // {{=<% %>=}}
|
||||
, Delimiter_end = Byte_ascii.Curly_end // {{=<% %>=}}
|
||||
, Item = Byte_ascii.Dot // {{.}}
|
||||
;
|
||||
public static final String
|
||||
ItemString = String_.new_u8(Byte_.To_bry(Item))
|
||||
;
|
||||
public Mustache_tkn_def() {
|
||||
Variable_lhs_len = Variable_lhs.length;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,7 +13,15 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.mustaches; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.mustaches;
|
||||
|
||||
import gplx.Bool_;
|
||||
import gplx.Bry_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Err_;
|
||||
import gplx.Io_url;
|
||||
import gplx.String_;
|
||||
|
||||
public interface Mustache_tkn_itm {
|
||||
int Tid();
|
||||
String Key();
|
||||
@ -103,8 +111,16 @@ class Mustache_tkn_inverted extends Mustache_tkn_base { // EX: {{^section}}missi
|
||||
@Override public void Render(Mustache_bfr bfr, Mustache_render_ctx ctx) {Mustache_tkn_section.Render_static(Bool_.Y, this, bfr, ctx);}
|
||||
}
|
||||
class Mustache_tkn_partial extends Mustache_tkn_base { // EX: {{>a}} -> abc (deferred eval)
|
||||
public Mustache_tkn_partial(byte[] key) {super(Mustache_tkn_itm_.Tid__partial, key);}
|
||||
private Mustache_tkn_itm template_root;
|
||||
public Mustache_tkn_partial(byte[] key, Io_url dir) {
|
||||
super(Mustache_tkn_itm_.Tid__partial, key);
|
||||
Mustache_tkn_parser parser = new Mustache_tkn_parser(dir);
|
||||
template_root = parser.Parse(String_.new_a7(Bry_.Trim_bgn(key, Byte_ascii.Space, 0)));
|
||||
}
|
||||
@Override public void Render(Mustache_bfr bfr, Mustache_render_ctx ctx) {
|
||||
template_root.Render(bfr, ctx);
|
||||
}
|
||||
}
|
||||
class Mustache_tkn_delimiter extends Mustache_tkn_base {// EX: {{=<% %>=}} -> <% variable %>
|
||||
class Mustache_tkn_delimiter extends Mustache_tkn_base { // EX: {{=<% %>=}} -> <% variable %>
|
||||
public Mustache_tkn_delimiter(byte[] key) {super(Mustache_tkn_itm_.Tid__delimiter, key);}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
||||
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||
|
||||
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||
or alternatively under the terms of the Apache License Version 2.0.
|
||||
@ -13,10 +13,32 @@ The terms of each license can be found in the source code repository:
|
||||
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.langs.mustaches; import gplx.*; import gplx.langs.*;
|
||||
package gplx.langs.mustaches;
|
||||
|
||||
import gplx.Bry_;
|
||||
import gplx.Bry_find_;
|
||||
import gplx.Byte_ascii;
|
||||
import gplx.Err;
|
||||
import gplx.Err_;
|
||||
import gplx.Io_mgr;
|
||||
import gplx.Io_url;
|
||||
import gplx.List_adp;
|
||||
import gplx.List_adp_;
|
||||
|
||||
public class Mustache_tkn_parser {
|
||||
private byte[] src; private int src_end;
|
||||
private Io_url template_root;
|
||||
private final Mustache_tkn_def tkn_def = new Mustache_tkn_def();
|
||||
public Mustache_tkn_parser() {
|
||||
}
|
||||
public Mustache_tkn_parser(Io_url template_root) {
|
||||
this.template_root = template_root;
|
||||
}
|
||||
public Mustache_tkn_itm Parse(String template) { return Parse(template, Bry_.Empty); }
|
||||
public Mustache_tkn_itm Parse(String template, byte[] default_text) {
|
||||
byte[] template_data = Io_mgr.Instance.LoadFilBryOr(template_root.GenSubFil_nest(template + ".mustache"), default_text);
|
||||
return Parse(template_data, 0, template_data.length);
|
||||
}
|
||||
public Mustache_tkn_itm Parse(byte[] src) {return Parse(src, 0, src.length);}
|
||||
public Mustache_tkn_itm Parse(byte[] src, int src_bgn, int src_end) {
|
||||
this.src = src; this.src_end = src_end;
|
||||
@ -80,7 +102,7 @@ public class Mustache_tkn_parser {
|
||||
default: throw Err_.new_unhandled(tkn_data.tid);
|
||||
case Mustache_tkn_def.Variable: tkn = new Mustache_tkn_variable(val_bry); break;
|
||||
case Mustache_tkn_def.Comment: tkn = new Mustache_tkn_comment(); break;
|
||||
case Mustache_tkn_def.Partial: tkn = new Mustache_tkn_partial(val_bry); break;
|
||||
case Mustache_tkn_def.Partial: tkn = new Mustache_tkn_partial(val_bry, template_root); break;
|
||||
case Mustache_tkn_def.Delimiter_bgn: tkn = new Mustache_tkn_delimiter(val_bry); break; // TODO_OLD: implement delimiter; EX: {{=<% %>=}}
|
||||
case Mustache_tkn_def.Escape_bgn: tkn = new Mustache_tkn_escape(val_bry); break;
|
||||
case Mustache_tkn_def.Section: tkn = new Mustache_tkn_section(val_bry); break;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user