1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Scribunto: Use Luaj for pattern-matching (instead of Java Regex) [#413]

This commit is contained in:
gnosygnu
2019-04-28 17:31:33 -04:00
parent 4a1b2e25c0
commit f860edf064
51 changed files with 2045 additions and 729 deletions

View File

@@ -0,0 +1,34 @@
/*
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.objects; import gplx.*;
import gplx.objects.brys.*;
import gplx.objects.strings.*;
import gplx.objects.types.*;
public class Object_ {
public static String To_str_or_null_mark(Object v) {return v == null ? "<<NULL>>": To_str(v);}
public static String To_str_or(Object v, String or) {return v == null ? or : To_str(v);}
public static String To_str(Object v) {
Class<?> c = v.getClass();
if (Type_.Eq(c, String_.Cls_ref_type)) return (String)v;
else if (Type_.Eq(c, Bry_.Cls_ref_type)) return String_.New_bry_utf8((byte[])v);
else return v.toString();
}
public static boolean Eq(Object lhs, Object rhs) {
if (lhs == null && rhs == null) return true;
else if (lhs == null || rhs == null) return false;
else return lhs.equals(rhs);
}
}

View File

@@ -0,0 +1,51 @@
/*
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.objects.arrays; import gplx.*; import gplx.objects.*;
import java.lang.reflect.Array;
import gplx.objects.errs.*;
public class Array_ {
public static int Len(Object ary) {return Array.getLength(ary);}
public static final int Len_obj(Object[] ary) {return ary == null ? 0 : ary.length;}
public static Object Get_at(Object ary, int i) {return Array.get(ary, i);}
public static void Set_at(Object ary, int i, Object o) {Array.set(ary, i, o);}
public static Object Create(Class<?> t, int count) {return Array.newInstance(t, count);}
public static Object Expand(Object src, Object trg, int src_len) {
try {System.arraycopy(src, 0, trg, 0, src_len);}
catch (Exception e) {throw Err_.New_fmt(e, "Array_.Expand failed; src_len={0}", src_len);}
return trg;
}
public static void Copy(Object src, Object trg) {System.arraycopy(src, 0, trg, 0, Len(src));}
public static void Copy_to(Object src, Object trg, int trgPos) {System.arraycopy(src, 0, trg, trgPos, Len(src));}
public static void Copy_to(Object src, int srcBgn, Object trg, int trgBgn, int srcLen) {System.arraycopy(src, srcBgn, trg, trgBgn, srcLen);}
private static Class<?> Component_type(Object ary) {
if (ary == null) throw Err_.New_msg("Array is null");
return ary.getClass().getComponentType();
}
public static Object Resize_add(Object src, Object add) {
int srcLen = Len(src);
int trgLen = srcLen + Len(add);
Object trg = Create(Component_type(src), trgLen);
Copy(src, trg);
for (int i = srcLen; i < trgLen; i++)
Set_at(trg, i, Get_at(add, i - srcLen));
return trg;
}
public static Object Clone(Object src) {
Object trg = Create(Component_type(src), Len(src));
Copy(src, trg);
return trg;
}
}

View File

@@ -0,0 +1,103 @@
/*
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.objects.brys; import gplx.*; import gplx.objects.*;
import gplx.objects.errs.*;
public class Bry_ {
public static final Class<?> Cls_ref_type = byte[].class;
public static final byte[] Empty = new byte[0];
public static boolean Eq(byte[] lhs, byte[] rhs) {return Eq(lhs, 0, lhs == null ? 0 : lhs.length, rhs);}
public static boolean Eq(byte[] lhs, int lhs_bgn, int lhs_end, byte[] rhs) {
if (lhs == null && rhs == null) return true;
else if (lhs == null || rhs == null) return false;
if (lhs_bgn < 0) return false;
int rhs_len = rhs.length;
if (rhs_len != lhs_end - lhs_bgn) return false;
int lhs_len = lhs.length;
for (int i = 0; i < rhs_len; i++) {
int lhs_pos = i + lhs_bgn;
if (lhs_pos == lhs_len) return false;
if (rhs[i] != lhs[lhs_pos]) return false;
}
return true;
}
public static byte[][] Ary(byte[]... ary) {return ary;}
public static byte[][] Ary(String... ary) {
int ary_len = ary.length;
byte[][] rv = new byte[ary_len][];
for (int i = 0; i < ary_len; i++) {
String itm = ary[i];
rv[i] = itm == null ? null : Bry_.New_utf08(itm);
}
return rv;
}
public static byte[] New_utf08(String src) {
try {
int src_len = src.length();
if (src_len == 0) return Bry_.Empty;
int bry_len = New_utf08__count(src, src_len);
byte[] bry = new byte[bry_len];
New_utf08__write(src, src_len, bry, 0);
return bry;
}
catch (Exception e) {throw Err_.New_fmt(e, "invalid UTF-8 sequence; src={0}", src);}
}
public static int New_utf08__count(String src, int src_len) {
int rv = 0;
for (int i = 0; i < src_len; ++i) {
char c = src.charAt(i);
int c_len = 0;
if ( c < 128) c_len = 1; // 1 << 7
else if ( c < 2048) c_len = 2; // 1 << 11
else if ( (c > 55295) // 0xD800
&& (c < 56320)) c_len = 4; // 0xDFFF
else c_len = 3; // 1 << 16
if (c_len == 4) ++i; // surrogate is 2 wide, not 1
rv += c_len;
}
return rv;
}
public static void New_utf08__write(String src, int src_len, byte[] bry, int bry_pos) {
for (int i = 0; i < src_len; ++i) {
char c = src.charAt(i);
if ( c < 128) {
bry[bry_pos++] = (byte)c;
}
else if ( c < 2048) {
bry[bry_pos++] = (byte)(0xC0 | (c >> 6));
bry[bry_pos++] = (byte)(0x80 | (c & 0x3F));
}
else if ( (c > 55295) // 0xD800
&& (c < 56320)) { // 0xDFFF
if (i >= src_len) throw Err_.New_msg("incomplete surrogate pair at end of String");
char nxt_char = src.charAt(i + 1);
int v = 0x10000 + (c - 0xD800) * 0x400 + (nxt_char - 0xDC00);
bry[bry_pos++] = (byte)(0xF0 | (v >> 18));
bry[bry_pos++] = (byte)(0x80 | (v >> 12) & 0x3F);
bry[bry_pos++] = (byte)(0x80 | (v >> 6) & 0x3F);
bry[bry_pos++] = (byte)(0x80 | (v & 0x3F));
++i;
}
else {
bry[bry_pos++] = (byte)(0xE0 | (c >> 12));
bry[bry_pos++] = (byte)(0x80 | (c >> 6) & 0x3F);
bry[bry_pos++] = (byte)(0x80 | (c & 0x3F));
}
}
}
}

View File

@@ -0,0 +1,21 @@
/*
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.objects.errs; import gplx.*; import gplx.objects.*;
public class Err extends RuntimeException {
private final String msg;
public Err(String msg) {this.msg = msg;}
@Override public String getMessage() {return msg;}
}

View File

@@ -0,0 +1,46 @@
/*
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.objects.errs; import gplx.*; import gplx.objects.*;
import gplx.objects.strings.*;
public class Err_ {
public static void Noop(Exception e) {}
public static Err New_fmt(String fmt, Object... args) {return new Err(String_.Format(fmt, args));}
public static Err New_msg(String msg) {return new Err(msg);}
public static Err New_fmt(Exception e, String fmt, Object... args) {
return new Err(String_.Format(fmt, args) + " exc=" + Err_.Message_lang(e));
}
public static Err New_null(String name) {return new Err("Object was null; name=" + name);}
public static Err New_unhandled_default(Object o) {
return new Err("val is not in switch; val=" + Object_.To_str(o));
}
public static String Message_lang(Exception e) {
return Error.class.isAssignableFrom(e.getClass())
? e.toString() // java.lang.Error returns null for "getMessage()"; return "toString()" instead
: e.getMessage();
}
public static String Trace_lang(Throwable e) {
StackTraceElement[] ary = e.getStackTrace();
String rv = "";
for (int i = 0; i < ary.length; i++) {
if (i != 0) rv += "\n";
rv += ary[i].toString();
}
return rv;
}
}

View File

@@ -0,0 +1,36 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
import gplx.objects.errs.*;
public class Bool_ {
public static final String Cls_val_name = "bool";
public static final Class<?> Cls_ref_type = Boolean.class;
public static final boolean N = false , Y = true;
public static final byte N_byte = 0 , Y_byte = 1 , __byte = 127;
public static final int N_int = 0 , Y_int = 1 , __int = -1;
public static final String True_str = "true", False_str = "false";
public static boolean Cast(Object o) {
try {
return (Boolean)o;
}
catch (Exception e) {
throw Err_.New_fmt(e, "failed to cast to boolean; obj={0}", Object_.To_str(o));
}
}
}

View File

@@ -0,0 +1,29 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
import gplx.objects.errs.*;
public class Byte_ {
public static final String Cls_val_name = "byte";
public static final Class<?> Cls_ref_type = Byte.class;
public static byte Cast(Object o) {
try {
return (Byte)o;
}
catch (Exception e) {
throw Err_.New_fmt(e, "failed to cast to byte; obj={0}", Object_.To_str(o));
}
}
}

View File

@@ -0,0 +1,20 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
public class Char_ {
public static final String Cls_val_name = "char";
public static final Class<?> Cls_ref_type = Character.class;
}

View File

@@ -0,0 +1,25 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
public class Char_code_ {
public static final char
New_line = '\n'
, Space = ' '
, Colon = ':'
, Num_0 = '0'
, Pipe = '|'
;
}

View File

@@ -0,0 +1,20 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
public class Double_ {
public static final String Cls_val_name = "double";
public static final Class<?> Cls_ref_type = Double.class;
}

View File

@@ -0,0 +1,20 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
public class Float_ {
public static final String Cls_val_name = "float";
public static final Class<?> Cls_ref_type = Float.class;
}

View File

@@ -0,0 +1,112 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
import gplx.objects.errs.*;
import gplx.objects.strings.*;
public class Int_ {
public static final String Cls_val_name = "int";
public static final Class<?> Cls_ref_type = Integer.class;
public static final int
Min_value = Integer.MIN_VALUE
, Max_value = Integer.MAX_VALUE
, Max_value__31 = 2147483647
, Neg1 = -1
, 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)
;
public static int Cast(Object o) {
try {
return (Integer)o;
}
catch(Exception e) {
throw Err_.New_fmt(e, "failed to cast to int; obj={0}", Object_.To_str(o));
}
}
public static String To_str(int v) {return new Integer(v).toString();}
public static int Parse_or(String raw, int or) {
// process args
if (raw == null) return or;
int raw_len = String_.Len(raw);
if (raw_len == 0) return or;
// loop backwards from nth to 0th char
int rv = 0, power_of_10 = 1;
for (int idx = raw_len - 1; idx >= 0; idx--) {
char cur = String_.Char_at(raw, idx);
int digit = -1;
switch (cur) {
// numbers -> assign digit
case '0': digit = 0; break; case '1': digit = 1; break; case '2': digit = 2; break; case '3': digit = 3; break; case '4': digit = 4; break;
case '5': digit = 5; break; case '6': digit = 6; break; case '7': digit = 7; break; case '8': digit = 8; break; case '9': digit = 9; break;
// negative sign
case '-':
if (idx != 0) { // invalid if not 1st
return or;
}
else { // is first; multiply by -1
rv *= -1;
continue;
}
// anything else
default:
return or;
}
rv += (digit * power_of_10);
power_of_10 *= 10;
}
return rv;
}
public static boolean Between(int v, int lhs, int rhs) {
int lhs_comp = v == lhs ? 0 : (v < lhs ? -1 : 1);
int rhs_comp = v == rhs ? 0 : (v < rhs ? -1 : 1);
return (lhs_comp * rhs_comp) != 1; // 1 when v is (a) greater than both or (b) less than both
}
private static int[] Log_10s = new int[] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, Int_.Max_value};
public static int Log10(int v) {
if (v == 0) return 0;
int sign = 1;
if (v < 0) {
if (v == Int_.Min_value) return -9; // NOTE: Int_.Min_value * -1 = Int_.Min_value
v *= -1;
sign = -1;
}
int log_10s_len = Log_10s.length;
int rv = log_10s_len - 2; // rv will only happen when v == Int_.Max_value
int bgn = 0;
if (v > 1000) { // optimization to reduce number of ops to < 5
bgn = 3;
if (v > 1000000) bgn = 6;
}
for (int i = bgn; i < log_10s_len; i++) {
if (v < Log_10s[i]) {rv = i - 1; break;}
}
return rv * sign;
}
public static int Count_digits(int v) {
int log10 = Log10(v);
return v > -1 ? log10 + 1 : log10 * -1 + 2;
}
}

View File

@@ -0,0 +1,90 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
import org.junit.*; import gplx.tests.*;
public class Int__tst {
private final Int__fxt fxt = new Int__fxt();
@Test public void Parse_or() {
fxt.Test__Parse_or("123", 123); // basic
fxt.Test__Parse_or_min_value(null); // null
fxt.Test__Parse_or_min_value(""); // empty
fxt.Test__Parse_or_min_value("1a"); // invalid number
fxt.Test__Parse_or("-123", -123); // negative
fxt.Test__Parse_or_min_value("1-23"); // negative at invalid position
}
@Test public void Between() {
fxt.Test__Between(1, 0, 2, true); // simple true
fxt.Test__Between(3, 0, 2, false); // simple false
fxt.Test__Between(0, 0, 2, true); // bgn true
fxt.Test__Between(2, 0, 2, true); // end true
}
@Test public void Count_digits() {
fxt.Test__Count_digits( 0, 1);
fxt.Test__Count_digits( 9, 1);
fxt.Test__Count_digits( 100, 3);
fxt.Test__Count_digits( -1, 2);
fxt.Test__Count_digits(-100, 4);
}
@Test public void Log10() {
fxt.Test__Log10( 0, 0);
fxt.Test__Log10( 1, 0);
fxt.Test__Log10( 2, 0);
fxt.Test__Log10( 10, 1);
fxt.Test__Log10( 12, 1);
fxt.Test__Log10( 100, 2);
fxt.Test__Log10( 123, 2);
fxt.Test__Log10( 1000, 3);
fxt.Test__Log10( 1234, 3);
fxt.Test__Log10( 10000, 4);
fxt.Test__Log10( 12345, 4);
fxt.Test__Log10( 100000, 5);
fxt.Test__Log10( 123456, 5);
fxt.Test__Log10( 1000000, 6);
fxt.Test__Log10( 1234567, 6);
fxt.Test__Log10( 10000000, 7);
fxt.Test__Log10( 12345678, 7);
fxt.Test__Log10( 100000000, 8);
fxt.Test__Log10( 123456789, 8);
fxt.Test__Log10( 1000000000, 9);
fxt.Test__Log10( 1234567890, 9);
fxt.Test__Log10(Int_.Max_value, 9);
fxt.Test__Log10( -1, 0);
fxt.Test__Log10( -10, -1);
fxt.Test__Log10( -100, -2);
fxt.Test__Log10( -1000000, -6);
fxt.Test__Log10( -1000000000, -9);
fxt.Test__Log10(Int_.Min_value, -9);
fxt.Test__Log10(Int_.Min_value + 1, -9);
}
}
class Int__fxt {
public void Test__Parse_or(String raw, int expd) {
Gftest_fxt.Eq__int(expd, Int_.Parse_or(raw, -1));
}
public void Test__Parse_or_min_value(String raw) {
Gftest_fxt.Eq__int(Int_.Min_value, Int_.Parse_or(raw, Int_.Min_value));
}
public void Test__Between(int val, int lhs, int rhs, boolean expd) {
Gftest_fxt.Eq__bool(expd, Int_.Between(val, lhs, rhs));
}
public void Test__Count_digits(int val, int expd) {
Gftest_fxt.Eq__int(expd, Int_.Count_digits(val), Int_.To_str(val));
}
public void Test__Log10(int val, int expd) {
Gftest_fxt.Eq__int(expd, Int_.Log10(val));
}
}

View File

@@ -0,0 +1,29 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
import gplx.objects.errs.*;
public class Long_ {
public static final String Cls_val_name = "long";
public static final Class<?> Cls_ref_type = Long.class;
public static long Cast(Object o) {
try {
return (Long)o;
}
catch(Exception e) {
throw Err_.New_fmt(e, "failed to cast to long; obj={0}", Object_.To_str(o));
}
}
}

View File

@@ -0,0 +1,20 @@
/*
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.objects.primitives; import gplx.*; import gplx.objects.*;
public class Short_ {
public static final String Cls_val_name = "short";
public static final Class<?> Cls_ref_type = Short.class;
}

View File

@@ -0,0 +1,95 @@
/*
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.objects.strings; import gplx.*; import gplx.objects.*;
import java.lang.*;
import gplx.objects.errs.*;
import gplx.objects.strings.bfrs.*;
import gplx.objects.arrays.*; import gplx.objects.primitives.*;
public class String_ {
public static final Class<?> Cls_ref_type = String.class;
public static final String Cls_val_name = "str" + "ing";
public static final int Find_none = -1, Pos_neg1 = -1;
public static final String Empty = "", Null_mark = "<<NULL>>", Tab = "\t", Lf = "\n", CrLf = "\r\n";
public static boolean Eq(String lhs, String rhs) {return lhs == null ? rhs == null : lhs.equals(rhs);}
public static int Len(String s) {return s.length();}
public static char Char_at(String s, int i) {return s.charAt(i);}
// use C# flavor ("a {0}") rather than Java format ("a %s"); also: (a) don't fail on format errors; (b) escape brackets by doubling
private static final char FORMAT_ITM_LHS = '{', FORMAT_ITM_RHS = '}';
public static String Format(String fmt, Object... args) {
// method vars
int args_len = Array_.Len_obj(args);
if (args_len == 0) return fmt; // nothing to format
int fmt_len = Len(fmt);
// loop vars
int pos = 0; String arg_idx_str = ""; boolean inside_brackets = false;
String_bfr bfr = new String_bfr();
while (pos < fmt_len) { // loop over every char; NOTE: UT8-SAFE b/c only checking for "{"; "}"
char c = Char_at(fmt, pos);
if (inside_brackets) {
if (c == FORMAT_ITM_LHS) { // first FORMAT_ITM_LHS is fake; add FORMAT_ITM_LHS and whatever is in arg_idx_str
bfr.Add_char(FORMAT_ITM_LHS).Add(arg_idx_str);
arg_idx_str = "";
}
else if (c == FORMAT_ITM_RHS) { // itm completed
int args_idx = Int_.Parse_or(arg_idx_str, Int_.Min_value);
String itm = args_idx != Int_.Min_value && Int_.Between(args_idx, 0, args_len - 1) // check (a) args_idx is num; (b) args_idx is in bounds
? Object_.To_str_or_null_mark(args[args_idx]) // valid; add itm
: FORMAT_ITM_LHS + arg_idx_str + FORMAT_ITM_RHS; // not valid; just add String
bfr.Add(itm);
inside_brackets = false;
arg_idx_str = "";
}
else
arg_idx_str += c;
}
else {
if (c == FORMAT_ITM_LHS || c == FORMAT_ITM_RHS) {
boolean pos_is_end = pos == fmt_len - 1;
if (pos_is_end) // last char is "{" or "}" (and not inside_brackets); ignore and just ad
bfr.Add_char(c);
else {
char next = Char_at(fmt, pos + 1);
if (next == c) { // "{{" or "}}": escape by doubling
bfr.Add_char(c);
pos++;
}
else
inside_brackets = true;
}
}
else
bfr.Add_char(c);
}
pos++;
}
if (Len(arg_idx_str) > 0) // unclosed bracket; add FORMAT_ITM_LHS and whatever is in arg_idx_str; ex: "{0"
bfr.Add_char(FORMAT_ITM_LHS).Add(arg_idx_str);
return bfr.To_str();
}
public static String New_bry_utf8(byte[] v) {return v == null ? null : New_bry_utf8(v, 0, v.length);}
public static String New_bry_utf8(byte[] v, int bgn, int end) {
try {
return v == null
? null
: new String(v, bgn, end - bgn, "UTF-8");
}
catch (Exception e) {throw Err_.New_fmt(e, "unsupported encoding; bgn={0} end={1}", bgn, end);}
}
}

View File

@@ -0,0 +1,47 @@
/*
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.objects.strings; import gplx.*; import gplx.objects.*;
import org.junit.*; import gplx.tests.*;
public class String__tst {
private final String__fxt fxt = new String__fxt();
@Test public void Len() {
fxt.Test__Len("" , 0);
fxt.Test__Len("abc", 3);
}
@Test public void Format() {
fxt.Test__Format("" , ""); // empty fmt
fxt.Test__Format("" , "", "a"); // empty fmt w/ args
fxt.Test__Format("a" , "a"); // no args
fxt.Test__Format("a" , "{0}", "a"); // args = 1
fxt.Test__Format("a + b" , "{0} + {1}", "a", "b"); // args = n
fxt.Test__Format("{" , "{{", 0); // escape "{"
fxt.Test__Format("}" , "}}", 0); // escape "}"
fxt.Test__Format("{a0c}" , "{a{0}c}", 0); // nested;
fxt.Test__Format("{a{b}c}" , "{a{b}c}", 0); // nested; invalid
fxt.Test__Format("{1}" , "{1}", "a"); // out of bounds
fxt.Test__Format("{a} {b}" , "{a} {b}", 0); // invalid arg
fxt.Test__Format("{a}0{b}1", "{a}{0}{b}{1}", 0, 1); // invalid and valid args
fxt.Test__Format("{0", "{0", 0); // dangling
}
}
class String__fxt {
public void Test__Format(String expd, String fmt, Object... ary) {
Gftest_fxt.Eq__str(expd, String_.Format(fmt, ary));
}
public void Test__Len(String v, int expd) {
Gftest_fxt.Eq__int(expd, String_.Len(v));
}
}

View File

@@ -0,0 +1,76 @@
/*
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.objects.strings.bfrs; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
import java.lang.*;
import gplx.objects.primitives.*;
import gplx.objects.errs.*;
public class String_bfr {
private java.lang.StringBuilder sb = new java.lang.StringBuilder();
public boolean Has_none() {return this.Len() == 0;}
public boolean Has_some() {return this.Len() > 0;}
public String_bfr Add_fmt(String format, Object... args) {Add(String_.Format(format, args)); return this;}
public String_bfr Add_char_pipe() {return Add_char(Char_code_.Pipe);}
public String_bfr Add_char_nl() {return Add_char(Char_code_.New_line);}
public String_bfr Add_char_space() {return Add_char(Char_code_.Space);}
public String_bfr Add_char_colon() {return Add_char(Char_code_.Colon);}
public String_bfr Add_char_repeat(char c, int repeat) {
this.Ensure_capacity(this.Len() + repeat);
for (int i = 0; i < repeat; i++)
Add_char(c);
return this;
}
public String_bfr Add_int_pad_bgn(char pad_char, int str_len, int val) {
int digit_len = Int_.Count_digits(val);
int pad_len = str_len - digit_len;
if (pad_len > 0) // note that this skips pad_len == 0, as well as guarding against negative pad_len; EX: pad(" ", 3, 1234) -> "1234"
Add_char_repeat(pad_char, pad_len);
Add_int(val);
return this;
}
public String_bfr Add_bool(boolean val) {
this.Add(val ? Bool_.True_str : Bool_.False_str);
return this;
}
public String_bfr Add_bool_as_yn(boolean val) {
this.Add(val ? "y" : "n");
return this;
}
public String_bfr Clear() {Del(0, this.Len()); return this;}
public String To_str_and_clear() {
String rv = To_str();
Clear();
return rv;
}
@Override public String toString() {return To_str();}
public String To_str() {return sb.toString();}
public int Len() {return sb.length();}
public String_bfr Add_at(int idx, String s) {sb.insert(idx, s); return this;}
public String_bfr Add(String s) {sb.append(s); return this;}
public String_bfr Add_char(char c) {sb.append(c); return this;}
public String_bfr Add_byte(byte i) {sb.append(i); return this;}
public String_bfr Add_int(int i) {sb.append(i); return this;}
public String_bfr Add_long(long i) {sb.append(i); return this;}
public String_bfr Add_double(double i) {sb.append(i); return this;}
public String_bfr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
public String_bfr Add_obj(Object o) {sb.append(o); return this;}
public String_bfr Add_bry(byte[] v) {
if (v != null)
sb.append(String_.New_bry_utf8(v));
return this;
}
private void Ensure_capacity(int capacity) {sb.ensureCapacity(capacity);}
public String_bfr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
}

View File

@@ -0,0 +1,25 @@
/*
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.objects.strings.char_sources; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
public interface Char_source {
String Src();
int Get_data(int pos);
int Len_in_data();
String Substring(int bgn, int end);
int Index_of(Char_source find, int bgn);
boolean Eq(int lhs_bgn, Char_source rhs, int rhs_bgn, int rhs_end);
}

View File

@@ -0,0 +1,30 @@
/*
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.objects.strings.char_sources; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
public class Char_source_ {
public static int Index_of_any(String src, char[] ary) {
int src_len = String_.Len(src);
int ary_len = ary.length;
for (int i = 0; i < src_len; i++) {
for (int j = 0; j < ary_len; j++) {
if (String_.Char_at(src, i) == ary[j] ) {
return i;
}
}
}
return -1;
}
}

View File

@@ -0,0 +1,151 @@
/*
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.objects.strings.unicodes; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
import gplx.objects.errs.*;
import gplx.objects.brys.*;
import gplx.objects.strings.char_sources.*;
public interface Ustring extends Char_source {
int Len_in_chars();
int Map_data_to_char(int pos);
int Map_char_to_data(int pos);
}
class Ustring_single implements Ustring { // 1 char == 1 codepoint
public Ustring_single(String src, int src_len) {
this.src = src;
this.src_len = src_len;
}
public String Src() {return src;} private final String src;
public int Len_in_chars() {return src_len;} private final int src_len;
public int Len_in_data() {return src_len;}
public String Substring(int bgn, int end) {return src.substring(bgn, end);}
public int Index_of(Char_source find, int bgn) {return src.indexOf(find.Src(), bgn);}
public boolean Eq(int lhs_bgn, Char_source rhs, int rhs_bgn, int rhs_end) {
if (src_len < lhs_bgn + rhs_end || rhs.Len_in_data() < rhs_bgn + rhs_end)
return false;
while ( --rhs_end>=0 )
if (this.Get_data(lhs_bgn++) != rhs.Get_data(rhs_bgn++))
return false;
return true;
}
public int Get_data(int i) {return String_.Char_at(src, i);}
public int Map_data_to_char(int i) {if (i < 0 || i > src_len) throw Err_.New_fmt("invalid idx; idx={0} src={1}", i, src); return i;}
public int Map_char_to_data(int i) {if (i < 0 || i > src_len) throw Err_.New_fmt("invalid idx; idx={0} src={1}", i, src); return i;}
}
class Ustring_codepoints implements Ustring {
private final int[] codes;
public Ustring_codepoints(String src, int chars_len, int codes_len) {
// set members
this.src = src;
this.chars_len = chars_len;
this.codes_len = codes_len;
// make codes[]
this.codes = new int[codes_len];
int code_idx = 0;
for (int i = 0; i < chars_len; i++) {
char c = src.charAt(i);
if (c >= Ustring_.Surrogate_hi_bgn && c <= Ustring_.Surrogate_hi_end) { // character is 1st part of surrogate-pair
i++;
if (i == chars_len) throw Err_.New_fmt("invalid surrogate pair found; src={0}", src);
int c2 = src.charAt(i);
codes[code_idx++] = Ustring_.Surrogate_cp_bgn + (c - Ustring_.Surrogate_hi_bgn) * Ustring_.Surrogate_range + (c2 - Ustring_.Surrogate_lo_bgn);
}
else {
codes[code_idx++] = c;
}
}
}
public String Src() {return src;} private final String src;
public String Substring(int bgn, int end) {
int len = 0;
for (int i = bgn; i < end; i++) {
int code = codes[i];
len += code >= Ustring_.Surrogate_cp_bgn && code <= Ustring_.Surrogate_cp_end ? 2 : 1;
}
char[] rv = new char[len];
int rv_idx = 0;
for (int i = bgn; i < end; i++) {
int code = codes[i];
if (code >= Ustring_.Surrogate_cp_bgn && code <= Ustring_.Surrogate_cp_end) {
rv[rv_idx++] = (char)((code - 0x10000) / 0x400 + 0xD800);
rv[rv_idx++] = (char)((code - 0x10000) % 0x400 + 0xDC00);
}
else {
rv[rv_idx++] = (char)code;
}
}
return new String(rv);
}
public int Index_of(Char_source find, int bgn) {
int find_len = find.Len_in_data();
int codes_len = codes.length;
for (int i = bgn; i < codes.length; i++) {
boolean found = true;
for (int j = 0; j < find_len; j++) {
int codes_idx = i + j;
if (codes_idx >= codes_len) {
found = false;
break;
}
if (codes[codes_idx] != find.Get_data(j)) {
found = false;
break;
}
}
if (found == true)
return i;
}
return -1;
}
public boolean Eq(int lhs_bgn, Char_source rhs, int rhs_bgn, int rhs_end) {
if (this.Len_in_data() < lhs_bgn + rhs_end || rhs.Len_in_data() < rhs_bgn + rhs_end)
return false;
while ( --rhs_end>=0 )
if ((this.Get_data(lhs_bgn++) != rhs.Get_data(rhs_bgn++)))
return false;
return true;
}
public int Len_in_chars() {return chars_len;} private final int chars_len;
public int Len_in_data() {return codes_len;} private final int codes_len;
public int Get_data(int i) {return codes[i];}
public int Map_data_to_char(int code_pos) {
if (code_pos == codes_len) return chars_len; // if char_pos is chars_len, return codes_len; allows "int end = u.Map_char_to_data(str_len)"
// sum all items before requested pos
int rv = 0;
for (int i = 0; i < code_pos; i++) {
rv += codes[i] < Ustring_.Surrogate_cp_bgn ? 1 : 2;
}
return rv;
}
public int Map_char_to_data(int char_pos) {
if (char_pos == chars_len) return codes_len; // if char_pos is chars_len, return codes_len; allows "int end = u.Map_char_to_data(str_len)"
// sum all items before requested pos
int rv = 0;
for (int i = 0; i < char_pos; i++) {
char c = src.charAt(i);
if (c >= Ustring_.Surrogate_hi_bgn && c <= Ustring_.Surrogate_hi_end){ // Surrogate_hi
if (i == char_pos - 1) // char_pos is Surrogate_lo; return -1 since Surrogate_lo doesn't map to a code_pos
return -1;
}
else
rv++;
}
return rv;
}
}

View File

@@ -0,0 +1,51 @@
/*
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.objects.strings.unicodes; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
import gplx.objects.errs.*;
public class Ustring_ {
public static Ustring New_codepoints(String src) {
if (src == null) throw Err_.New_null("src");
// calc lens
int chars_len = src.length();
int codes_len = Ustring_.Len(src, chars_len);
return chars_len == codes_len
? (Ustring)new Ustring_single(src, chars_len)
: (Ustring)new Ustring_codepoints(src, chars_len, codes_len);
}
public static int Len(String src, int src_len) {
int rv = 0;
for (int i = 0; i < src_len; i++) {
char c = src.charAt(i);
if (c >= Surrogate_hi_bgn && c <= Surrogate_hi_end) {
i++;
}
rv++;
}
return rv;
}
public static final int // REF: https://en.wikipedia.org/wiki/Universal_Character_Set_characters
Surrogate_hi_bgn = 0xD800 // 55,296: Surrogate high start
, Surrogate_hi_end = 0xDBFF // 56,319: Surrogate high end
, Surrogate_lo_bgn = 0xDC00 // 56,320: Surrogate low start
, Surrogate_lo_end = 0xDFFF // 57,343: Surrogate low end
, Surrogate_cp_bgn = 0x010000 // 65,536: Surrogate codepoint start
, Surrogate_cp_end = 0x10FFFF // 1,114,111: Surrogate codepoint end
, Surrogate_range = 0x400 // 1,024: Surrogate range (end - start) for high / low
;
}

View File

@@ -0,0 +1,104 @@
/*
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.objects.strings.unicodes; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
import org.junit.*; import gplx.tests.*;
import gplx.objects.errs.*;
public class Ustring_tst {
private final Ustring_fxt fxt = new Ustring_fxt();
@Test public void Empty() {
fxt.Init("");
fxt.Test__Len(0, 0);
}
@Test public void Blank() {
fxt.Init("");
fxt.Test__Len(0, 0);
}
@Test public void Single() {
fxt.Init("Abc");
fxt.Test__Len(3, 3);
fxt.Test__Get_code(65, 98, 99);
fxt.Test__Map_code_to_char(0, 1, 2, 3);
fxt.Test__Map_char_to_code(0, 1, 2, 3);
}
@Test public void Multi() {
fxt.Init("a¢€𤭢b");
fxt.Test__Len(5, 6);
fxt.Test__Get_code(97, 162, 8364, 150370, 98);
fxt.Test__Map_code_to_char(0, 1, 2, 3, 5, 6);
fxt.Test__Map_char_to_code(0, 1, 2, 3, -1, 4, 5);
}
@Test public void Index_of() {
fxt.Test__Index_of("abc", "b", 0, 1); // basic
fxt.Test__Index_of("ab", "bc", 0, -1); // out-of-bounds
fxt.Test__Index_of("a¢e", "¢", 0, 1); // check UTF-8 strings still match at byte-level
}
@Test public void Substring() {
fxt.Test__Substring("abc", 1, 2, "b"); // basic
fxt.Test__Substring("¢bc", 1, 2, "b"); // check UTF-8 strings don't get lopped off
}
}
class Ustring_fxt {
private Ustring under;
public void Init(String src) {
this.under = Ustring_.New_codepoints(src);
}
public void Test__Len(int expd_codes, int expd_chars) {
Gftest_fxt.Eq__int(expd_codes, under.Len_in_data(), "codes");
Gftest_fxt.Eq__int(expd_chars, under.Len_in_chars(), "chars");
}
public void Test__Get_code(int... expd) {
int actl_len = under.Len_in_data();
int[] actl = new int[actl_len];
for (int i = 0; i < actl_len; i++)
actl[i] = under.Get_data(i);
Gftest_fxt.Eq__ary(expd, actl);
}
public void Test__Map_code_to_char(int... expd) {
int actl_len = under.Len_in_data() + 1;
int[] actl = new int[actl_len];
for (int i = 0; i < actl_len; i++)
actl[i] = under.Map_data_to_char(i);
Gftest_fxt.Eq__ary(expd, actl);
}
public void Test__Map_char_to_code(int... expd) {
int actl_len = under.Len_in_chars() + 1;
int[] actl = new int[actl_len];
for (int i = 0; i < actl_len; i++) {
int val = 0;
try {
val = under.Map_char_to_data(i);
}
catch (Exception exc) {
val = -1;
Err_.Noop(exc);
}
actl[i] = val;
}
Gftest_fxt.Eq__ary(expd, actl);
}
public void Test__Index_of(String src_str, String find_str, int bgn, int expd) {
Ustring src = Ustring_.New_codepoints(src_str);
Ustring find = Ustring_.New_codepoints(find_str);
int actl = src.Index_of(find, bgn);
Gftest_fxt.Eq__int(expd, actl);
}
public void Test__Substring(String src_str, int bgn, int end, String expd) {
Ustring src = Ustring_.New_codepoints(src_str);
String actl = src.Substring(bgn, end);
Gftest_fxt.Eq__str(expd, actl);
}
}

View File

@@ -0,0 +1,23 @@
/*
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.objects.types; import gplx.*; import gplx.objects.*;
public class Type_ {
public static boolean Eq(Class<?> lhs, Class<?> rhs) {// DUPE_FOR_TRACKING: same as Object_.Eq
if (lhs == null && rhs == null) return true;
else if (lhs == null || rhs == null) return false;
else return lhs.equals(rhs);
}
}

View File

@@ -0,0 +1,59 @@
/*
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.objects.types; import gplx.*; import gplx.objects.*;
import gplx.objects.primitives.*;
import gplx.objects.strings.*;
public class Type_ids_ {
public static final int // SERIALIZABLE.N
Id__obj = 0
, Id__null = 1
, Id__bool = 2
, Id__byte = 3
, Id__short = 4
, Id__int = 5
, Id__long = 6
, Id__float = 7
, Id__double = 8
, Id__char = 9
, Id__str = 10
, Id__bry = 11
, Id__date = 12
, Id__decimal = 13
, Id__array = 14
;
public static int To_id_by_obj(Object o) {
if (o == null) return Type_ids_.Id__null;
Class<?> type = o.getClass();
return Type_ids_.To_id_by_type(type);
}
public static int To_id_by_type(Class<?> type) {
if (Type_.Eq(type, Int_.Cls_ref_type)) return Id__int;
else if (Type_.Eq(type, String_.Cls_ref_type)) return Id__str;
else if (Type_.Eq(type, byte[].class)) return Id__bry;
else if (Type_.Eq(type, Bool_.Cls_ref_type)) return Id__bool;
else if (Type_.Eq(type, Byte_.Cls_ref_type)) return Id__byte;
else if (Type_.Eq(type, Long_.Cls_ref_type)) return Id__long;
else if (Type_.Eq(type, Double_.Cls_ref_type)) return Id__double;
// else if (Type_.Eq(type, Decimal_.Cls_ref_type)) return Id__decimal;
// else if (Type_.Eq(type, Date_.Cls_ref_type)) return Id__date;
else if (Type_.Eq(type, Float_.Cls_ref_type)) return Id__float;
else if (Type_.Eq(type, Short_.Cls_ref_type)) return Id__short;
else if (Type_.Eq(type, Char_.Cls_ref_type)) return Id__char;
else return Id__obj;
}
}

View File

@@ -0,0 +1,220 @@
/*
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.tests; import gplx.*;
import gplx.objects.*;
import gplx.objects.errs.*;
import gplx.objects.primitives.*; import gplx.objects.brys.*;
import gplx.objects.strings.*; import gplx.objects.strings.bfrs.*;
import gplx.objects.arrays.*; import gplx.objects.types.*;
public class Gftest_fxt {
private static final String_bfr bfr = new String_bfr();
public static void Eq__ary(Object[] expd, Object[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__obj, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary(boolean[] expd, boolean[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__bool, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary(int[] expd, int[] actl) {Eq__array(Type_ids_.Id__int, expd, actl, "");}
public static void Eq__ary(int[] expd, int[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__int, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary(long[] expd, long[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__long, expd, actl, msg_fmt, msg_args);}
public static void Eq__ary(byte[] expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__byte, expd, actl, msg_fmt, msg_args);}
// public static void Eq__ary__lines(String expd, String actl) {Eq__ary__lines(expd, actl, "no_msg");}
// public static void Eq__ary__lines(String expd, byte[] actl) {Eq__ary__lines(expd, String_.New_bry_utf8(actl), "no_msg");}
// public static void Eq__ary__lines(String expd, byte[] actl, String msg_fmt, params Object[] msg_args) {Eq__ary__lines(expd, String_.New_bry_utf8(actl), msg_fmt, msg_args);}
// public static void Eq__ary__lines(String expd, String actl, String msg_fmt, params Object[] msg_args) {Eq__array(Type_ids_.Id__str, Bry_split_.Split_lines(Bry_.New_utf08(expd)), Bry_split_.Split_lines(Bry_.New_utf08(actl)), msg_fmt, msg_args);}
public static void Eq__ary(String[] expd, String[] actl) {Eq__array(Type_ids_.Id__bry, Bry_.Ary(expd), Bry_.Ary(actl), "no_msg");}
public static void Eq__ary(String[] expd, String[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__bry, Bry_.Ary(expd), Bry_.Ary(actl), msg_fmt, msg_args);}
public static void Eq__ary(String[] expd, byte[][] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__bry, Bry_.Ary(expd), actl, msg_fmt, msg_args);}
public static void Eq__ary(byte[][] expd, byte[][] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__bry, expd, actl, msg_fmt, msg_args);}
private static void Eq__array(int type_tid, Object expd_ary, Object actl_ary, String msg_fmt, Object... msg_args) {
boolean[] failures = Calc__failures(type_tid, expd_ary, actl_ary);
if (failures != null) {
Write_fail_head(bfr, msg_fmt, msg_args);
Write_fail_ary(bfr, failures, type_tid, expd_ary, actl_ary);
throw Err_.New_msg(bfr.To_str_and_clear());
}
}
public static void Eq__null(boolean expd, Object actl) {Eq__null(expd, actl, null);}
public static void Eq__null(boolean expd, Object actl, String msg_fmt, Object... msg_args) {
if ( expd && actl == null
|| !expd && actl != null
) return;
Write_fail_head(bfr, msg_fmt, msg_args);
String expd_str = expd ? "null" : "not null";
String actl_str = actl == null ? "null" : "not null";
bfr.Add("expd: ").Add(expd_str).Add_char_nl();
bfr.Add("actl: ").Add(actl_str).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
public static void Eq__obj_or_null(Object expd, Object actl) {
if (expd == null) expd = Null;
if (actl == null) actl = Null;
Eq__str(Object_.To_str_or(expd, Null), Object_.To_str_or(actl, null), Null);
}
public static void Eq__str(String expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__str(expd, String_.New_bry_utf8(actl), msg_fmt, msg_args);}
public static void Eq__str(String expd, byte[] actl) {Eq__str(expd, String_.New_bry_utf8(actl), null);}
public static void Eq__str(String expd, String actl) {Eq__str(expd, actl, null);}
public static void Eq__str(String expd, String actl, String msg_fmt, Object... msg_args) {
if (String_.Eq(expd, actl)) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add(expd).Add_char_nl();
bfr.Add("actl: ").Add(actl).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
public static void Eq__bry(byte[] expd, byte[] actl) {Eq__bry(expd, actl, null);}
public static void Eq__bry(byte[] expd, byte[] actl, String msg_fmt, Object... msg_args) {
if (Bry_.Eq(expd, actl)) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add(String_.New_bry_utf8(expd)).Add_char_nl();
bfr.Add("actl: ").Add(String_.New_bry_utf8(actl)).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
public static void Eq__long(long expd, long actl) {Eq__long(expd, actl, null);}
public static void Eq__long(long expd, long actl, String msg_fmt, Object... msg_args) {
if (expd == actl) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add_long(expd).Add_char_nl();
bfr.Add("actl: ").Add_long(actl).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
public static void Eq__byte(byte expd, byte actl) {Eq__byte(expd, actl, null);}
public static void Eq__byte(byte expd, byte actl, String msg_fmt, Object... msg_args) {
if (expd == actl) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add_byte(expd).Add_char_nl();
bfr.Add("actl: ").Add_byte(actl).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
public static void Eq__int(int expd, int actl) {Eq__int(expd, actl, null);}
public static void Eq__int(int expd, int actl, String msg_fmt, Object... msg_args) {
if (expd == actl) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add_int(expd).Add_char_nl();
bfr.Add("actl: ").Add_int(actl).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
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);}
public static void Eq__bool(boolean expd, boolean actl, String msg_fmt, Object... msg_args) {
if (expd == actl) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add_bool(expd).Add_char_nl();
bfr.Add("actl: ").Add_bool(actl).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
public static void Eq__double(double expd, double actl) {Eq__double(expd, actl, null);}
public static void Eq__double(double expd, double actl, String msg_fmt, Object... msg_args) {
if (expd == actl) return;
Write_fail_head(bfr, msg_fmt, msg_args);
bfr.Add("expd: ").Add_double(expd).Add_char_nl();
bfr.Add("actl: ").Add_double(actl).Add_char_nl();
bfr.Add(Section_end);
throw Err_.New_msg(bfr.To_str_and_clear());
}
private static void Write_fail_head(String_bfr bfr, String msg_fmt, Object[] msg_args) {
bfr.Add(Section_bgn);
if (msg_fmt != null) {
bfr.Add(String_.Format(msg_fmt, msg_args));
bfr.Add(Section_mid);
}
}
private static void Write_fail_ary(String_bfr bfr, boolean[] failures, int type_id, Object expd_ary, Object actl_ary) {
int len = failures.length;
int expd_len = Array_.Len(expd_ary);
int actl_len = Array_.Len(actl_ary);
for (int i = 0; i < len; ++i) {
boolean failure = failures[i];
int pad_len = 5 - Int_.Count_digits(i);
bfr.Add_int_pad_bgn(Char_code_.Num_0, pad_len, i).Add_char_colon().Add_char_space();
Write__itm(bfr, type_id, expd_ary, expd_len, i);
if (failure) {
bfr.Add(Eq_n).Add_char_repeat(Char_code_.Space, pad_len - 1);
Write__itm(bfr, type_id, actl_ary, actl_len, i);
}
}
bfr.Add(Section_end);
}
private static void Write__itm(String_bfr bfr, int type_id, Object ary, int len, int idx) {
if (idx < len) {
Object val = Array_.Get_at(ary, idx);
switch (type_id) {
case Type_ids_.Id__bool: bfr.Add_bool_as_yn(Bool_.Cast(val)); break;
case Type_ids_.Id__bry: bfr.Add_bry((byte[])val); break;
case Type_ids_.Id__long: bfr.Add_long(Long_.Cast(val)); break;
case Type_ids_.Id__int: bfr.Add_int(Int_.Cast(val)); break;
case Type_ids_.Id__byte: bfr.Add_int((int)(Byte_.Cast(val))); break;
case Type_ids_.Id__obj: bfr.Add(Object_.To_str(val)); break;
default: throw Err_.New_unhandled_default(type_id);
}
}
else
bfr.Add(Null);
bfr.Add_char_nl();
}
private static boolean[] Calc__failures(int tid, Object expd_ary, Object actl_ary) {
int expd_len = Array_.Len(expd_ary);
int actl_len = Array_.Len(actl_ary);
int max_len = expd_len > actl_len ? expd_len : actl_len; if (max_len == 0) return null;
boolean[] rv = null;
for (int i = 0; i < max_len; ++i) {
Object expd_obj = i < expd_len ? Array_.Get_at(expd_ary, i) : null;
Object actl_obj = i < actl_len ? Array_.Get_at(actl_ary, i) : null;
boolean eq = false;
if (expd_obj == null && actl_obj == null) eq = true;
else if (expd_obj == null || actl_obj == null) eq = false;
else {
switch (tid) {
case Type_ids_.Id__bool: eq = Bool_.Cast(expd_obj) == Bool_.Cast(actl_obj); break;
case Type_ids_.Id__bry: eq = Bry_.Eq((byte[])expd_obj, (byte[])actl_obj); break;
case Type_ids_.Id__long: eq = Long_.Cast(expd_obj) == Long_.Cast(actl_obj); break;
case Type_ids_.Id__int: eq = Int_.Cast(expd_obj) == Int_.Cast(actl_obj); break;
case Type_ids_.Id__byte: eq = Byte_.Cast(expd_obj) == Byte_.Cast(actl_obj); break;
case Type_ids_.Id__obj: eq = Object_.Eq(expd_obj, actl_obj); break;
}
}
if (!eq) {
if (rv == null) {
rv = new boolean[max_len];
}
rv[i] = true;
}
}
return rv;
}
private static final String Null = "<<NULL>>";
private static final String Eq_n = "!= "
, Section_bgn = "\n************************************************************************************************\n"
, Section_mid = "\n------------------------------------------------------------------------------------------------\n"
, Section_end = "________________________________________________________________________________________________"
;
// public static void Write(byte[] s, int b, int e) {Write(Bry_.Mid(s, b, e));}
public static void Write() {Write("tmp");}
public static void Write(Object... ary) {
String_bfr bfr = new String_bfr();
int ary_len = Array_.Len(ary);
for (int i = 0; i < ary_len; i++) {
bfr.Add("'");
bfr.Add(Object_.To_str_or_null_mark(ary[i]));
bfr.Add("' ");
}
System.out.println(bfr.To_str() + String_.Lf);
}
}