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

Refactor: Refactor baselib; merge Array_ and Bool_

This commit is contained in:
gnosygnu
2021-12-05 16:25:05 -05:00
parent 197e0aa863
commit 48559edffe
1793 changed files with 177613 additions and 16991 deletions

View File

@@ -1,10 +1,24 @@
package gplx.objects;
/*
XOWA: the XOWA Offline Wiki Application
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.
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;
public class GfoKeyVal<K, V> {
public GfoKeyVal(K key, V val) {
this.key = key;
this.val = val;
}
public K Key() {return key;} private final K key;
public V Val() {return val;} public void ValSet(V v) {this.val = v;} private V val;
public GfoKeyVal(K key, V val) {
this.key = key;
this.val = val;
}
public K Key() {return key;} private final K key;
public V Val() {return val;} public void ValSet(V v) {this.val = v;} private V val;
}

View File

@@ -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,22 +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.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);
}
}
package gplx.objects;
import gplx.objects.arrays.BryUtl;
import gplx.objects.strings.StringUtl;
import gplx.objects.types.TypeUtl;
public class ObjectUtl {
public static String ToStrOrNullMark(Object v) {return v == null ? "<<NULL>>": ToStr(v);}
public static String ToStrOr(Object v, String or) {return v == null ? or : ToStr(v);}
public static String ToStr(Object v) {
Class<?> c = v.getClass();
if (TypeUtl.Eq(c, StringUtl.ClsRefType)) return (String)v;
else if (TypeUtl.Eq(c, BryUtl.ClsRefType)) return StringUtl.NewByBryUtf8((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,82 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.errs.ErrUtl;
import gplx.objects.lists.ComparerAble;
import gplx.objects.lists.ComparerAbleSorter;
import java.lang.reflect.Array;
public class ArrayUtl {
public static int Len(Object ary) {return Array.getLength(ary);}
public static int LenObjAry(Object[] ary) {return ary == null ? 0 : ary.length;}
public static Object GetAt(Object ary, int i) {return Array.get(ary, i);}
public static void SetAt(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 srcLen) {
try {System.arraycopy(src, 0, trg, 0, srcLen);}
catch (Exception e) {throw ErrUtl.NewFmt(e, "ArrayUtl.Expand failed; srcLen={0}", srcLen);}
return trg;
}
public static void Copy(Object src, Object trg) {System.arraycopy(src, 0, trg, 0, Len(src));}
public static void CopyTo(Object src, Object trg, int trgPos) {System.arraycopy(src, 0, trg, trgPos, Len(src));}
public static void CopyTo(Object src, int srcBgn, Object trg, int trgBgn, int srcLen) {System.arraycopy(src, srcBgn, trg, trgBgn, srcLen);}
public static Object Clone(Object src) {return Clone(src, 0, Len(src));}
public static Object Clone(Object src, int srcBgn) {return Clone(src, srcBgn, Array.getLength(src));}
private static Object Clone(Object src, int srcBgn, int srcEnd) {
int trgLen = srcEnd - srcBgn;
Object trg = Create(ComponentType(src), trgLen);
CopyTo(src, srcBgn, trg, 0, trgLen);
return trg;
}
public static Object Resize(Object src, int trgLen) {
Object trg = Create(ComponentType(src), trgLen);
int srcLen = Array.getLength(src);
int copyLen = srcLen > trgLen ? trgLen : srcLen; // trgLen can either expand or shrink
CopyTo(src, 0, trg, 0, copyLen);
return trg;
}
public static Object Append(Object src, Object add) {
int srcLen = Len(src);
int trgLen = srcLen + Len(add);
Object trg = Create(ComponentType(src), trgLen);
Copy(src, trg);
for (int i = srcLen; i < trgLen; i++)
SetAt(trg, i, GetAt(add, i - srcLen));
return trg;
}
public static Object AppendOne(Object src, int srcLen, Object newObj) {
Object rv = Resize(src, srcLen + 1);
SetAt(rv, srcLen, newObj);
return rv;
}
public static Object[] Insert(Object[] cur, Object[] add, int addPos) {
int curLen = cur.length, addLen = add.length;
Object[] rv = (Object[])Create(ComponentType(cur), curLen + addLen);
for (int i = 0; i < addPos; i++) // copy old up to addPos
rv[i] = cur[i];
for (int i = 0; i < addLen; i++) // insert add
rv[i + addPos] = add[i];
for (int i = addPos; i < curLen; i++) // copy old after addPos
rv[i + addLen] = cur[i];
return rv;
}
public static void Sort(Object[] obj) {new ComparerAbleSorter().Sort(obj, obj.length);}
public static void Sort(Object[] obj, ComparerAble comparer) {new ComparerAbleSorter().Sort(obj, obj.length, true, comparer);}
public static Object Cast(Object o) {return o;} // NOTE: leftover from .NET; casts System.Object to System.Array
private static Class<?> ComponentType(Object ary) {
if (ary == null) throw ErrUtl.NewMsg("Array is null");
return ary.getClass().getComponentType();
}
}

View File

@@ -1,51 +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.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,115 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.errs.ErrUtl;
public class BryUtl {
public static final Class<?> ClsRefType = 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 lhsBgn, int lhsEnd, byte[] rhs) {
if (lhs == null && rhs == null) return true;
else if (lhs == null || rhs == null) return false;
if (lhsBgn < 0) return false;
int rhsLen = rhs.length;
if (rhsLen != lhsEnd - lhsBgn) return false;
int lhsLen = lhs.length;
for (int i = 0; i < rhsLen; i++) {
int lhsPos = i + lhsBgn;
if (lhsPos == lhsLen) return false;
if (rhs[i] != lhs[lhsPos]) return false;
}
return true;
}
public static byte[][] Ary(byte[]... ary) {return ary;}
public static byte[][] Ary(String... ary) {
int aryLen = ary.length;
byte[][] rv = new byte[aryLen][];
for (int i = 0; i < aryLen; i++) {
String itm = ary[i];
rv[i] = itm == null ? null : BryUtl.NewUtf08(itm);
}
return rv;
}
public static byte[] NewA7(String str) {
if (str == null) return null;
int str_len = str.length();
if (str_len == 0) return Empty;
byte[] rv = new byte[str_len];
for (int i = 0; i < str_len; ++i) {
char c = str.charAt(i);
if (c > 128) c = '?';
rv[i] = (byte)c;
}
return rv;
}
public static byte[] NewUtf08(String src) {
try {
int srcLen = src.length();
if (srcLen == 0) return BryUtl.Empty;
int bryLen = NewUtf08Count(src, srcLen);
byte[] bry = new byte[bryLen];
NewUtf08Write(src, srcLen, bry, 0);
return bry;
}
catch (Exception e) {throw ErrUtl.NewFmt(e, "invalid UTF-8 sequence; src={0}", src);}
}
private static int NewUtf08Count(String src, int srcLen) {
int rv = 0;
for (int i = 0; i < srcLen; ++i) {
char c = src.charAt(i);
int cLen = 0;
if ( c < 128) cLen = 1; // 1 << 7
else if ( c < 2048) cLen = 2; // 1 << 11
else if ( (c > 55295) // 0xD800
&& (c < 56320)) cLen = 4; // 0xDFFF
else cLen = 3; // 1 << 16
if (cLen == 4) ++i; // surrogate is 2 wide, not 1
rv += cLen;
}
return rv;
}
private static void NewUtf08Write(String src, int srcLen, byte[] bry, int bryPos) {
for (int i = 0; i < srcLen; ++i) {
char c = src.charAt(i);
if ( c < 128) {
bry[bryPos++] = (byte)c;
}
else if ( c < 2048) {
bry[bryPos++] = (byte)(0xC0 | (c >> 6));
bry[bryPos++] = (byte)(0x80 | (c & 0x3F));
}
else if ( (c > 55295) // 0xD800
&& (c < 56320)) { // 0xDFFF
if (i >= srcLen) throw ErrUtl.NewMsg("incomplete surrogate pair at end of String");
char nxtChar = src.charAt(i + 1);
int v = 0x10000 + (c - 0xD800) * 0x400 + (nxtChar - 0xDC00);
bry[bryPos++] = (byte)(0xF0 | (v >> 18));
bry[bryPos++] = (byte)(0x80 | (v >> 12) & 0x3F);
bry[bryPos++] = (byte)(0x80 | (v >> 6) & 0x3F);
bry[bryPos++] = (byte)(0x80 | (v & 0x3F));
++i;
}
else {
bry[bryPos++] = (byte)(0xE0 | (c >> 12));
bry[bryPos++] = (byte)(0x80 | (c >> 6) & 0x3F);
bry[bryPos++] = (byte)(0x80 | (c & 0x3F));
}
}
}
}

View File

@@ -1,103 +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.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

@@ -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,7 +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.objects.errs; import gplx.*; import gplx.objects.*;
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;}

View File

@@ -0,0 +1,43 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.ObjectUtl;
import gplx.objects.strings.StringUtl;
public class ErrUtl {
public static void Noop(Exception e) {}
public static Err NewMsg(String msg) {return new Err(msg);}
public static Err NewFmt(String fmt, Object... args) {return new Err(StringUtl.Format(fmt, args));}
public static Err NewFmt(Exception e, String fmt, Object... args) {return new Err(StringUtl.Format(fmt, args) + " exc=" + ErrUtl.MessageLang(e));}
public static Err NewNull(String name) {return new Err("object was null; name=" + name);}
public static Err NewUnhandledDefault(Object o) {return new Err("val is not in switch; val=" + ObjectUtl.ToStr(o));}
public static Err NewUnimplemented() {return new Err("method is not implemented");}
public static Err NewParse(Class<?> cls, String raw) {return new Err("parse failed; cls=" + cls.getCanonicalName() + "; raw=" + raw);}
public static String MessageLang(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 TraceLang(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

@@ -1,47 +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.objects.errs; import gplx.objects.Object_;
import gplx.objects.strings.String_;
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 Err New_unimplemented() {return new Err("Method is not implemented");}
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

@@ -1,23 +1,36 @@
package gplx.objects.events;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.events;
import java.util.ArrayList;
import java.util.List;
public class GfoEvent<A> {
private final List<GfoHandler<A>> handlers = new ArrayList<>();
private final String name;
private final GfoEventOwner owner;
public GfoEvent(String name, GfoEventOwner owner) {
this.name = name;
this.owner = owner;
}
public void Add(GfoHandler<A> handler) {
owner.EventsEnabledSet(true);
handlers.add(handler);
}
public void Run(A args) {
for (GfoHandler<A> handler : handlers) {
handler.Run(owner, args);
}
}
private final List<GfoHandler<A>> handlers = new ArrayList<>();
private final String name;
private final GfoEventOwner owner;
public GfoEvent(String name, GfoEventOwner owner) {
this.name = name;
this.owner = owner;
}
public void Add(GfoHandler<A> handler) {
owner.EventsEnabledSet(true);
handlers.add(handler);
}
public void Run(A args) {
for (GfoHandler<A> handler : handlers) {
handler.Run(owner, args);
}
}
}

View File

@@ -1,5 +1,19 @@
package gplx.objects.events;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.events;
public interface GfoEventOwner {
boolean EventsEnabled(); void EventsEnabledSet(boolean v);
boolean EventsEnabled(); void EventsEnabledSet(boolean v);
}

View File

@@ -1,5 +1,19 @@
package gplx.objects.events;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.events;
public interface GfoHandler<A> {
void Run(GfoEventOwner sender, A args);
void Run(GfoEventOwner sender, A args);
}

View File

@@ -13,8 +13,6 @@ 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;
}
package gplx.objects.lists;
public interface CompareAble extends Comparable {} // URL:/doc/gplx/CompareAble_.txt
// public int compareTo(Object obj) {Type comp = (Type)obj; return prop.compareTo(comp.prop);}

View File

@@ -0,0 +1,41 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
public class CompareAbleUtl {
public static Comparable as_(Object obj) {return obj instanceof Comparable ? (Comparable)obj : null;}
public static int Compare_obj(Object lhs, Object rhs) {return Compare_comp(as_(lhs), as_(rhs));}
public static int Compare_comp(Comparable lhs, Comparable rhs) {
if (lhs == null && rhs == null) return CompareAbleUtl.Same;
else if (lhs == null) return CompareAbleUtl.More;
else if (rhs == null) return CompareAbleUtl.Less;
else return Compare(lhs, rhs);
}
public static int Compare(Comparable lhs, Comparable rhs) {return lhs.compareTo(rhs);}
public static boolean Is(int expd, Comparable lhs, Comparable rhs) {
int actl = Compare_comp(lhs, rhs);
if (actl == Same && expd % 2 == Same) // actl=Same and expd=(Same||MoreOrSame||LessOrSame)
return true;
else
return (actl * expd) > 0; // actl=More||Less; expd will match if on same side of 0 (ex: expd=Less; actl=Less; -1 * -1 = 1)
}
public static final int
More = 1,
Less = -1,
Same = 0,
More_or_same = 2,
Less_or_same = -2;
}

View File

@@ -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.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;
package gplx.objects.lists;
import java.util.Comparator;
public interface ComparerAble extends Comparator {
}
// public int compare(Object lhsObj, Object rhsObj) {}

View File

@@ -0,0 +1,61 @@
/*
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.lists;
public class ComparerAbleSorter {
private ComparerAble comparer = null;
public void Sort(Object[] orig, int origLen) {Sort(orig, origLen, true, null);}
public void Sort(Object[] orig, int origLen, boolean asc, ComparerAble comparer) {
this.comparer = comparer;
Object[] temp = new Object[origLen];
MergeSort(asc, orig, temp, 0, origLen - 1);
this.comparer = null;
}
private void MergeSort(boolean asc, Object[] orig, Object[] temp, int lhs, int rhs) {
if (lhs < rhs) {
int mid = (lhs + rhs) / 2;
MergeSort(asc, orig, temp, lhs, mid);
MergeSort(asc, orig, temp, mid + 1, rhs);
Combine(asc, orig, temp, lhs, mid + 1, rhs);
}
}
private void Combine(boolean asc, Object[] orig, Object[] temp, int lhsPos, int rhsPos, int rhsEnd) {
int lhsEnd = rhsPos - 1;
int tmpPos = lhsPos;
int aryLen = rhsEnd - lhsPos + 1;
while (lhsPos <= lhsEnd && rhsPos <= rhsEnd) {
int compareVal = 0;
if (comparer != null)
compareVal = ComparerAbleUtl.Compare(comparer, orig[lhsPos], orig[rhsPos]);
else {
Comparable lhsComp = (Comparable)orig[lhsPos];
compareVal = lhsComp == null ? CompareAbleUtl.Less : lhsComp.compareTo(orig[rhsPos]);
}
if (!asc) compareVal *= -1;
if (compareVal <= CompareAbleUtl.Same) // NOTE: (a) must be < 0; JAVA's String.compareTo returns -number based on position; (b) must be <= else sorting sorted list will change order; EX: sorting (a,1;a,2) on fld0 will switch to (a,2;a,1)
temp[tmpPos++] = orig[lhsPos++];
else
temp[tmpPos++] = orig[rhsPos++];
}
while (lhsPos <= lhsEnd) // Copy rest of first half
temp[tmpPos++] = orig[lhsPos++];
while (rhsPos <= rhsEnd) // Copy rest of right half
temp[tmpPos++] = orig[rhsPos++];
for (int i = 0; i < aryLen; i++, rhsEnd--)
orig[rhsEnd] = temp[rhsEnd];
}
}

View File

@@ -13,8 +13,7 @@ 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;
package gplx.objects.lists;
public class ComparerAbleUtl {
public static int Compare(ComparerAble comparer, Object lhs, Object rhs) {return comparer.compare(lhs, rhs);}
}

View File

@@ -1,4 +1,18 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
public interface GfoComparator<T> extends java.util.Comparator<T> {
}

View File

@@ -1,46 +1,59 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2021 gnosygnu@gmail.com
import gplx.objects.errs.Err_;
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.lists;
import gplx.objects.errs.ErrUtl;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Spliterator;
import java.util.function.Consumer;
public class GfoHashBase<K, V> implements Iterable<Map.Entry<K, V>> {
protected final Map<K, V> map = new HashMap<>();
protected final Map<K, V> map = new HashMap<>();
public int Len() {return map.size();}
public void Clear() {map.clear();}
public void Add(GfoHashKeyFunc<K> keyFunc, V v) {Add(keyFunc.ToHashKey(), v);}
public void Add(K k, V v) {
if (k == null) {
throw Err_.New_fmt("key cannot be null; val={0}", v);
}
if (map.containsKey(k)) {
throw Err_.New_fmt("key already exists: key={0} val={1}", k, v);
}
map.put(k, v);
}
public void Del(K k) {map.remove(k);}
public void Set(K k, V v) {map.put(k, v);}
public boolean Has(K k) {return map.containsKey(k);}
public V GetByOrNull(K k) {return map.get(k);}
public V GetByOr(K k, V or) {
V v = map.get(k);
if (v == null) {
v = or;
}
return v;
public int Len() {return map.size();}
public void Clear() {map.clear();}
public void Add(GfoHashKeyFunc<K> keyFunc, V v) {Add(keyFunc.ToHashKey(), v);}
public void Add(K k, V v) {
if (k == null) {
throw ErrUtl.NewFmt("key cannot be null; val={0}", v);
}
if (map.containsKey(k)) {
throw ErrUtl.NewFmt("key already exists: key={0} val={1}", k, v);
}
map.put(k, v);
}
public V GetByOrFail(GfoHashKeyFunc<K> func) {return GetByOrFail(func.ToHashKey());}
public V GetByOrFail(K k) {
V v = map.get(k);
if (v == null) {
throw Err_.New_fmt("val not found; key={0}", k);
}
return v;
public void Del(K k) {map.remove(k);}
public void Set(K k, V v) {map.put(k, v);}
public boolean Has(K k) {return map.containsKey(k);}
public V GetByOrNull(K k) {return map.get(k);}
public V GetByOr(K k, V or) {
V v = map.get(k);
if (v == null) {
v = or;
}
return v;
}
public V GetByOrFail(GfoHashKeyFunc<K> func) {return GetByOrFail(func.ToHashKey());}
public V GetByOrFail(K k) {
V v = map.get(k);
if (v == null) {
throw ErrUtl.NewFmt("val not found; key={0}", k);
}
return v;
}
@Override public Iterator<Map.Entry<K, V>> iterator() {return map.entrySet().iterator();}

View File

@@ -1,5 +1,19 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
public interface GfoHashKeyFunc<K> {
K ToHashKey();
K ToHashKey();
}

View File

@@ -1,127 +1,140 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
import gplx.objects.GfoKeyVal;
import gplx.objects.errs.Err_;
import gplx.objects.errs.ErrUtl;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
public class GfoIndexedList<K, V> implements Iterable<V> {
private final GfoListBase<V> list = new GfoListBase<>();
private final GfoHashBase<K, GfoIndexedListEntry<K, V>> hash = new GfoHashBase<>();
public boolean Has(K key) {
return hash.Has(key);
}
public int Len() {return hash.Len();}
public V GetAt(int key) {
return list.GetAt(key);
}
public V GetByOrFail(GfoHashKeyFunc<K> func) {return GetByOrFail(func.ToHashKey());}
public V GetByOrFail(K key) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
if (val == null) {
throw Err_.New_fmt("Unknown key: {0}", key);
}
return val.Val();
}
public V GetByOr(K key, V or) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
return val == null ? or : val.Val();
}
public Optional<V> GetBy(K key) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
return val == null ? Optional.empty() : Optional.of(val.Val());
}
public V GetByOrNull(K key) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
return val == null ? null : val.Val();
}
public void Sort(GfoComparator<V> comparator) {
private final GfoListBase<V> list = new GfoListBase<>();
private final GfoHashBase<K, GfoIndexedListEntry<K, V>> hash = new GfoHashBase<>();
public boolean Has(K key) {
return hash.Has(key);
}
public int Len() {return hash.Len();}
public V GetAt(int key) {
return list.GetAt(key);
}
public V GetByOrFail(GfoHashKeyFunc<K> func) {return GetByOrFail(func.ToHashKey());}
public V GetByOrFail(K key) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
if (val == null) {
throw ErrUtl.NewFmt("Unknown key: {0}", key);
}
return val.Val();
}
public V GetByOr(K key, V or) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
return val == null ? or : val.Val();
}
public Optional<V> GetBy(K key) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
return val == null ? Optional.empty() : Optional.of(val.Val());
}
public V GetByOrNull(K key) {
GfoIndexedListEntry<K, V> val = hash.GetByOrNull(key);
return val == null ? null : val.Val();
}
public void Sort(GfoComparator<V> comparator) {
list.Sort(comparator);
}
public void AddAt(int i, K key, V val) {
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
if (mapEntryItem.ListIdx() >= i) {
mapEntryItem.ListIdxSet(mapEntryItem.ListIdx() + 1);
}
}
hash.Add(key, new GfoIndexedListEntry<>(key, val, i));
list.AddAt(i, val);
}
public void DelAt(int i, K key) {
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
if (mapEntryItem.ListIdx() > i) {
mapEntryItem.ListIdxSet(mapEntryItem.ListIdx() - 1);
}
}
hash.Del(key);
list.DelAt(i);
}
public void Add(GfoHashKeyFunc<K> func, V val) {Add(func.ToHashKey(), val);}
public void Add(K key, V val) {
hash.Add(key, new GfoIndexedListEntry<>(key, val, list.Len()));
list.Add(val);
}
public void Set(K key, V val) {
GfoIndexedListEntry<K, V> entry = hash.GetByOrNull(key);
if (entry == null) {
this.Add(key, val);
}
else {
entry.ValSet(val);
list.Set(entry.ListIdx(), val);
}
}
public void DelBy(K key) {
GfoIndexedListEntry<K, V> entry = hash.GetByOrNull(key);
if (entry == null) {
return; // if key is unknown, do nothing; matches behavior of java.util.Hashtable
}
hash.Del(key);
int listIdx = entry.ListIdx();
list.DelAt(listIdx);
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
if (mapEntryItem.ListIdx() > listIdx) {
mapEntryItem.ListIdxSet(mapEntryItem.ListIdx() - 1);
}
}
}
public void Clear() {
list.Clear();
hash.Clear();
}
public V[] ToAry(Class<?> clz) {return list.ToAry(clz);}
public GfoKeyVal<K, V>[] ToKvAry() {
int len = this.Len();
GfoKeyVal<K, V>[] ary = new GfoKeyVal[len];
int idx = 0;
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
ary[idx++] = new GfoKeyVal<>(mapEntryItem.Key(), mapEntryItem.Val());
}
return ary;
}
}
public void AddAt(int i, K key, V val) {
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
if (mapEntryItem.ListIdx() >= i) {
mapEntryItem.ListIdxSet(mapEntryItem.ListIdx() + 1);
}
}
hash.Add(key, new GfoIndexedListEntry<>(key, val, i));
list.AddAt(i, val);
}
public void DelAt(int i, K key) {
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
if (mapEntryItem.ListIdx() > i) {
mapEntryItem.ListIdxSet(mapEntryItem.ListIdx() - 1);
}
}
hash.Del(key);
list.DelAt(i);
}
public void Add(GfoHashKeyFunc<K> func, V val) {Add(func.ToHashKey(), val);}
public void Add(K key, V val) {
hash.Add(key, new GfoIndexedListEntry<>(key, val, list.Len()));
list.Add(val);
}
public void Set(K key, V val) {
GfoIndexedListEntry<K, V> entry = hash.GetByOrNull(key);
if (entry == null) {
this.Add(key, val);
}
else {
entry.ValSet(val);
list.Set(entry.ListIdx(), val);
}
}
public void DelBy(K key) {
GfoIndexedListEntry<K, V> entry = hash.GetByOrNull(key);
if (entry == null) {
return; // if key is unknown, do nothing; matches behavior of java.util.Hashtable
}
hash.Del(key);
int listIdx = entry.ListIdx();
list.DelAt(listIdx);
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
if (mapEntryItem.ListIdx() > listIdx) {
mapEntryItem.ListIdxSet(mapEntryItem.ListIdx() - 1);
}
}
}
public void Clear() {
list.Clear();
hash.Clear();
}
public V[] ToAry(Class<?> clz) {return list.ToAry(clz);}
public GfoKeyVal<K, V>[] ToKvAry() {
int len = this.Len();
GfoKeyVal<K, V>[] ary = new GfoKeyVal[len];
int idx = 0;
for (Map.Entry<K, GfoIndexedListEntry<K, V>> mapEntry : hash) {
GfoIndexedListEntry<K, V> mapEntryItem = mapEntry.getValue();
ary[idx++] = new GfoKeyVal<>(mapEntryItem.Key(), mapEntryItem.Val());
}
return ary;
}
@Override public Iterator<V> iterator() {return list.iterator();}
@Override public void forEach(Consumer<? super V> action) {list.forEach(action);}
@Override public Spliterator<V> spliterator() {return list.spliterator();}
}
class GfoIndexedListEntry<K, V> {
private final K key;
private V val;
private int listIdx;
public GfoIndexedListEntry(K key, V val, int listIdx) {
this.key = key;
this.val = val;
this.listIdx = listIdx;
}
public K Key() {return key;}
public V Val() {return val;} public void ValSet(V v) {this.val = v;}
public int ListIdx() {return listIdx;} public void ListIdxSet(int v) {listIdx = v;}
private final K key;
private V val;
private int listIdx;
public GfoIndexedListEntry(K key, V val, int listIdx) {
this.key = key;
this.val = val;
this.listIdx = listIdx;
}
public K Key() {return key;}
public V Val() {return val;} public void ValSet(V v) {this.val = v;}
public int ListIdx() {return listIdx;} public void ListIdxSet(int v) {listIdx = v;}
}

View File

@@ -1,6 +1,20 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2021 gnosygnu@gmail.com
import gplx.objects.errs.Err_;
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.lists;
import gplx.objects.errs.ErrUtl;
import gplx.objects.events.GfoEvent;
import gplx.objects.events.GfoEventOwner;
@@ -8,116 +22,115 @@ import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GfoListBase<E> implements Iterable<E>, GfoEventOwner {
protected final List<E> list = new ArrayList<>();
private boolean eventsEnabled;
protected final List<E> list = new ArrayList<>();
private boolean eventsEnabled;
public GfoListBase() {
public GfoListBase() {
this.itemsChanged = new GfoEvent<>("Add", this);
}
}
public int Len() {return list.size();}
public E GetAt(int i) {return list.get(i);}
public E GetAtBgn() {return list.get(0);}
public E GetAtEnd() {return list.get(list.size() - 1);}
public int Len() {return list.size();}
public E GetAt(int i) {return list.get(i);}
public E GetAtBgn() {return list.get(0);}
public E GetAtEnd() {return list.get(list.size() - 1);}
@Override
public boolean EventsEnabled() {
return eventsEnabled;
}
}
@Override
public void EventsEnabledSet(boolean v) {
eventsEnabled = v;
}
public GfoEvent<ItemsChangedArg<E>> ItemsChanged() {return itemsChanged;} private final GfoEvent<ItemsChangedArg<E>> itemsChanged;
public GfoListBase<E> Add(E itm) {
list.add(itm);
if (eventsEnabled) {
public GfoListBase<E> Add(E itm) {
list.add(itm);
if (eventsEnabled) {
itemsChanged.Run(new ItemsChangedArg<>(ItemsChangedType.Add, GfoListBase.NewFromArray(itm)));
}
return this;
}
public GfoListBase<E> AddMany(E... ary) {
for (E itm : ary) {
this.Add(itm);
}
return this;
public GfoListBase<E> AddMany(E... ary) {
for (E itm : ary) {
this.Add(itm);
}
return this;
}
public GfoListBase<E> AddMany(GfoListBase<E> list) {
for (E itm : list) {
this.Add(itm);
}
return this;
public GfoListBase<E> AddMany(GfoListBase<E> list) {
for (E itm : list) {
this.Add(itm);
}
return this;
}
public void AddAt(int i, E itm) {
list.add(i, itm);
if (eventsEnabled) {
public void AddAt(int i, E itm) {
list.add(i, itm);
if (eventsEnabled) {
itemsChanged.Run(new ItemsChangedArg<>(ItemsChangedType.Add, GfoListBase.NewFromArray(itm)));
}
}
public void Set(int i, E itm) {
list.set(i, itm);
if (eventsEnabled) {
}
public void Set(int i, E itm) {
list.set(i, itm);
if (eventsEnabled) {
itemsChanged.Run(new ItemsChangedArg<>(ItemsChangedType.Set, GfoListBase.NewFromArray(itm)));
}
}
public void DelAt(int i) {
list.remove(i);
}
public void DelBetween(int i) {DelBetween(i, list.size() - 1);}
public void DelBetween(int bgn, int end) {
// put items in array for event
int len = end - bgn;
GfoListBase<E> old = new GfoListBase<>();
for (int i = 0; i < len; i++) {
old.Add(list.get(i + bgn));
}
}
public void DelAt(int i) {
list.remove(i);
}
public void DelBetween(int i) {DelBetween(i, list.size() - 1);}
public void DelBetween(int bgn, int end) {
// put items in array for event
int len = end - bgn;
GfoListBase<E> old = new GfoListBase<>();
for (int i = 0; i < len; i++) {
old.Add(list.get(i + bgn));
}
// actually delete
for (int i = bgn; i < end; i++) {
// actually delete
for (int i = bgn; i < end; i++) {
list.remove(bgn);
}
if (eventsEnabled) {
if (eventsEnabled) {
itemsChanged.Run(new ItemsChangedArg<>(ItemsChangedType.Del, old));
}
}
}
public void DelAtEnd() {
int idx = list.size() - 1;
E itm = list.get(idx);
list.remove(idx);
if (eventsEnabled) {
public void DelAtEnd() {
int idx = list.size() - 1;
E itm = list.get(idx);
list.remove(idx);
if (eventsEnabled) {
itemsChanged.Run(new ItemsChangedArg<>(ItemsChangedType.Del, GfoListBase.NewFromArray(itm)));
}
}
public void Clear() {
GfoListBase<E> old = new GfoListBase<>();
for (E itm : list)
old.Add(itm);
list.clear();
if (eventsEnabled) {
public void Clear() {
GfoListBase<E> old = new GfoListBase<>();
for (E itm : list)
old.Add(itm);
list.clear();
if (eventsEnabled) {
itemsChanged.Run(new ItemsChangedArg<>(ItemsChangedType.Clear, old));
}
}
public void Sort(GfoComparator<E> comparator) {
}
public void Sort(GfoComparator<E> comparator) {
list.sort(comparator);
}
public E[] ToAry(Class<?> clz) {
int len = list.size();
E[] rv = (E[])Array.newInstance(clz, len);
for (int i = 0; i < len; i++)
rv[i] = list.get(i);
return rv;
}
public String[] ToStringAry() {
int len = list.size();
String[] rv = new String[len];
for (int i = 0; i < len; i++)
rv[i] = list.get(i).toString();
return rv;
}
}
public E[] ToAry(Class<?> clz) {
int len = list.size();
E[] rv = (E[])Array.newInstance(clz, len);
for (int i = 0; i < len; i++)
rv[i] = list.get(i);
return rv;
}
public String[] ToStringAry() {
int len = list.size();
String[] rv = new String[len];
for (int i = 0; i < len; i++)
rv[i] = list.get(i).toString();
return rv;
}
@Override
public Iterator<E> iterator() {
@@ -143,7 +156,7 @@ public class GfoListBase<E> implements Iterable<E>, GfoEventOwner {
}
@Override
public void remove() {
throw Err_.New_unimplemented();
throw ErrUtl.NewUnimplemented();
}
}

View File

@@ -1,37 +1,50 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2021 gnosygnu@gmail.com
import gplx.objects.errs.Err_;
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.lists;
import gplx.objects.errs.ErrUtl;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Spliterator;
import java.util.function.Consumer;
public class GfoSetBase<I> implements Iterable<I> {
protected final Set<I> hash = new HashSet<>();
protected final Set<I> hash = new HashSet<>();
public int Len() {return hash.size();}
public void Clear() {hash.clear();}
public GfoSetBase<I> AddMany(I... ary) {
for (I itm : ary) {
public int Len() {return hash.size();}
public void Clear() {hash.clear();}
public GfoSetBase<I> AddMany(I... ary) {
for (I itm : ary) {
Add(itm);
}
return this;
}
public void Add(GfoHashKeyFunc<I> keyFunc) {Add(keyFunc.ToHashKey());}
public GfoSetBase<I> Add(I itm) {
if (itm == null) {
throw Err_.New_fmt("key cannot be null; val={0}", itm);
}
if (hash.contains(itm)) {
throw Err_.New_fmt("key already exists: key={0} val={1}", itm);
}
hash.add(itm);
}
public void Add(GfoHashKeyFunc<I> keyFunc) {Add(keyFunc.ToHashKey());}
public GfoSetBase<I> Add(I itm) {
if (itm == null) {
throw ErrUtl.NewFmt("key cannot be null; val={0}", itm);
}
if (hash.contains(itm)) {
throw ErrUtl.NewFmt("key already exists: key={0} val={1}", itm);
}
hash.add(itm);
return this;
}
public void Del(I itm) {hash.remove(itm);}
public boolean Has(I itm) {return hash.contains(itm);}
}
public void Del(I itm) {hash.remove(itm);}
public boolean Has(I itm) {return hash.contains(itm);}
@Override public Iterator<I> iterator() {return hash.iterator();}
@Override public void forEach(Consumer<? super I> action) {hash.forEach(action);}

View File

@@ -1,11 +1,25 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
public class ItemsChangedArg<T> {
public ItemsChangedArg(ItemsChangedType type, GfoListBase<T> itms) {
this.type = type;
this.itms = itms;
}
public ItemsChangedType Type() {return type;} private final ItemsChangedType type;
public GfoListBase<T> Itms() {return itms;} private final GfoListBase<T> itms;
public T Itm() {return itms.GetAt(0);}
public ItemsChangedArg(ItemsChangedType type, GfoListBase<T> itms) {
this.type = type;
this.itms = itms;
}
public ItemsChangedType Type() {return type;} private final ItemsChangedType type;
public GfoListBase<T> Itms() {return itms;} private final GfoListBase<T> itms;
public T Itm() {return itms.GetAt(0);}
}

View File

@@ -1,8 +1,22 @@
package gplx.objects.lists;
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
public enum ItemsChangedType {
Add,
Del,
Set,
Clear,
Add,
Del,
Set,
Clear,
}

View File

@@ -1,14 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.lists;
import java.util.List;
public class ListUtil {
public static byte[] ToArray(List<Byte> list) {
int len = list.size();
byte[] rv = new byte[len];
for (int i = 0; i < len; i++) {
rv[i] = list.get(i);
}
return rv;
}
public static byte[] ToArray(List<Byte> list) {
int len = list.size();
byte[] rv = new byte[len];
for (int i = 0; i < len; i++) {
rv[i] = list.get(i);
}
return rv;
}
}

View File

@@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.ObjectUtl;
import gplx.objects.arrays.BryUtl;
import gplx.objects.errs.ErrUtl;
import gplx.objects.lists.CompareAbleUtl;
import gplx.objects.strings.AsciiByte;
import gplx.objects.strings.StringUtl;
public class BoolUtl {
public static final String ClsValName = "bool";
public static final Class<?> ClsRefType = Boolean.class;
public static final boolean N = false , Y = true;
public static final byte NByte = 0 , YByte = 1 , NullByte = 127;
public static final int NInt = 0 , YInt = 1 , NullInt = -1;
public static final String TrueStr = "true", FalseStr = "false";
public static final byte[] NBry = new byte[] {AsciiByte.Ltr_n}, YBry = new byte[] {AsciiByte.Ltr_y};
public static final byte[] TrueBry = BryUtl.NewA7(TrueStr) , FalseBry = BryUtl.NewA7(FalseStr);
public static boolean ByInt(int v) {return v == YInt;}
public static int ToInt(boolean v) {return v ? YInt : NInt;}
public static byte ToByte(boolean v) {return v ? YByte : NByte;}
public static String ToStrLower(boolean v) {return v ? TrueStr : FalseStr;}
public static boolean Cast(Object o) {
try {
return (Boolean)o;
}
catch (Exception e) {
throw ErrUtl.NewFmt(e, "failed to cast to boolean; obj={0}", ObjectUtl.ToStr(o));
}
}
public static boolean Parse(String raw) {
if ( StringUtl.Eq(raw, TrueStr)
|| StringUtl.Eq(raw, "True") // needed for Store_Wtr(){boolVal.toString();}
)
return true;
else if ( StringUtl.Eq(raw, FalseStr)
|| StringUtl.Eq(raw, "False")
)
return false;
else
throw ErrUtl.NewParse(boolean.class, raw);
}
public static int Compare(boolean lhs, boolean rhs) {
if ( lhs == rhs) return CompareAbleUtl.Same;
else if (!lhs && rhs) return CompareAbleUtl.Less;
else /*lhs && !rhs*/ return CompareAbleUtl.More;
}
}

View File

@@ -1,36 +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.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

@@ -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,17 +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.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;
package gplx.objects.primitives;
import gplx.objects.ObjectUtl;
import gplx.objects.errs.ErrUtl;
public class ByteUtl {
public static final String ClsValName = "byte";
public static final Class<?> ClsRefType = 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));
throw ErrUtl.NewFmt(e, "failed to cast to byte; obj={0}", ObjectUtl.ToStr(o));
}
}
}

View File

@@ -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,13 +13,12 @@ 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 = '|'
;
}
package gplx.objects.primitives;
public class CharCode {
public static final char
NewLine = '\n',
Space = ' ',
Colon = ':',
Num0 = '0',
Pipe = '|';
}

View File

@@ -0,0 +1,20 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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;
public class CharUtl {
public static final String ClsValName = "char";
public static final Class<?> ClsRefType = Character.class;
}

View File

@@ -1,6 +1,6 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 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,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.objects.primitives;
public class Double_ {
public static final String Cls_val_name = "double";
public static final Class<?> Cls_ref_type = Double.class;
public class DoubleUtl {
public static final String ClsValName = "double";
public static final Class<?> ClsRefType = Double.class;
public static String ToStrByPrintF(double val) {
// call sprintf-like format; EX:"sprintf((s), "%.14g", (n));"

View File

@@ -0,0 +1,20 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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;
public class FloatUtl {
public static final String ClsValName = "float";
public static final Class<?> ClsRefType = Float.class;
}

View File

@@ -0,0 +1,110 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.ObjectUtl;
import gplx.objects.errs.ErrUtl;
import gplx.objects.strings.StringUtl;
public class IntUtl {
public static final String ClsValName = "int";
public static final Class<?> ClsRefType = Integer.class;
public static final int
MinValue = Integer.MIN_VALUE,
MaxValue = Integer.MAX_VALUE,
MaxValue31 = 2147483647,
Neg1 = -1,
Null = IntUtl.MinValue,
Base1 = 1, // for base-1 lists / arrays; EX: PHP; [a, b, c]; [1] => a
Offset1 = 1; // common symbol for + 1 after current pos; EX: StringUtl.Mid(lhs + Offset1, rhs)
public static int Cast(Object o) {
try {
return (Integer)o;
}
catch(Exception e) {
throw ErrUtl.NewFmt(e, "failed to cast to int; obj={0}", ObjectUtl.ToStr(o));
}
}
public static String ToStr(int v) {return new Integer(v).toString();}
public static int ParseOr(String raw, int or) {
// process args
if (raw == null) return or;
int rawLen = StringUtl.Len(raw);
if (rawLen == 0) return or;
// loop backwards from nth to 0th char
int rv = 0, powerOf10 = 1;
for (int idx = rawLen - 1; idx >= 0; idx--) {
char cur = StringUtl.CharAt(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 * powerOf10);
powerOf10 *= 10;
}
return rv;
}
public static boolean Between(int v, int lhs, int rhs) {
int lhsComp = v == lhs ? 0 : (v < lhs ? -1 : 1);
int rhsComp = v == rhs ? 0 : (v < rhs ? -1 : 1);
return (lhsComp * rhsComp) != 1; // 1 when v is (a) greater than both or (b) less than both
}
private static int[] Log10Vals = new int[] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, IntUtl.MaxValue};
public static int Log10(int v) {
if (v == 0) return 0;
int sign = 1;
if (v < 0) {
if (v == IntUtl.MinValue) return -9; // NOTE: IntUtl.MinValue * -1 = IntUtl.MinValue
v *= -1;
sign = -1;
}
int log10sLen = Log10Vals.length;
int rv = log10sLen - 2; // rv will only happen when v == IntUtl.MaxValue
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 < log10sLen; i++) {
if (v < Log10Vals[i]) {rv = i - 1; break;}
}
return rv * sign;
}
public static int CountDigits(int v) {
int log10 = Log10(v);
return v > -1 ? log10 + 1 : log10 * -1 + 2;
}
}

View File

@@ -1,112 +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.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

@@ -1,90 +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.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

@@ -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,17 +13,19 @@ 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;
package gplx.objects.primitives;
import gplx.objects.ObjectUtl;
import gplx.objects.errs.ErrUtl;
public class LongUtl {
public static final String ClsValName = "long";
public static final Class<?> ClsRefType = 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));
throw ErrUtl.NewFmt(e, "failed to cast to long; obj={0}", ObjectUtl.ToStr(o));
}
}
public static String ToStr(long v) {return new Long(v).toString();}
}

View File

@@ -0,0 +1,20 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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;
public class ShortUtl {
public static final String ClsValName = "short";
public static final Class<?> ClsRefType = Short.class;
}

View File

@@ -0,0 +1,119 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.errs.ErrUtl;
public class AsciiByte {
public static final byte
Null = 0 , Backfeed = 8, Tab = 9,
Nl = 10, VerticalTab = 11, Formfeed = 12, Cr = 13,
Escape = 27,
Space = 32, Bang = 33, Quote = 34,
Hash = 35, Dollar = 36, Percent = 37, Amp = 38, Apos = 39,
ParenBgn = 40, ParenEnd = 41, Star = 42, Plus = 43, Comma = 44,
Dash = 45, Dot = 46, Slash = 47, Num0 = 48, Num1 = 49,
Num2 = 50, Num3 = 51, Num4 = 52, Num5 = 53, Num6 = 54,
Num7 = 55, Num8 = 56, Num9 = 57, Colon = 58, Semic = 59,
Lt = 60, Eq = 61, Gt = 62, Question = 63, At = 64,
Ltr_A = 65, Ltr_B = 66, Ltr_C = 67, Ltr_D = 68, Ltr_E = 69,
Ltr_F = 70, Ltr_G = 71, Ltr_H = 72, Ltr_I = 73, Ltr_J = 74,
Ltr_K = 75, Ltr_L = 76, Ltr_M = 77, Ltr_N = 78, Ltr_O = 79,
Ltr_P = 80, Ltr_Q = 81, Ltr_R = 82, Ltr_S = 83, Ltr_T = 84,
Ltr_U = 85, Ltr_V = 86, Ltr_W = 87, Ltr_X = 88, Ltr_Y = 89,
Ltr_Z = 90, BrackBgn = 91, Backslash = 92, BrackEnd = 93, Pow = 94, // Circumflex
Underline = 95, Tick = 96, Ltr_a = 97, Ltr_b = 98, Ltr_c = 99,
Ltr_d = 100, Ltr_e = 101, Ltr_f = 102, Ltr_g = 103, Ltr_h = 104,
Ltr_i = 105, Ltr_j = 106, Ltr_k = 107, Ltr_l = 108, Ltr_m = 109,
Ltr_n = 110, Ltr_o = 111, Ltr_p = 112, Ltr_q = 113, Ltr_r = 114,
Ltr_s = 115, Ltr_t = 116, Ltr_u = 117, Ltr_v = 118, Ltr_w = 119,
Ltr_x = 120, Ltr_y = 121, Ltr_z = 122, CurlyBgn = 123, Pipe = 124,
CurlyEnd = 125, Tilde = 126, Delete = 127;
public static final byte
AngleBgn = Lt,
AngleEnd = Gt;
public static final int Len1 = 1;
public static final byte Max7Bit = 127, AsciiMin = 0, AsciiMax = 127;
public static boolean IsLtr(byte b) {
return ( b >= Ltr_a && b <= Ltr_z
|| b >= Ltr_A && b <= Ltr_Z);
}
public static boolean IsWs(byte b) {
switch (b) {
case Tab: case Nl: case Cr: case Space: return true;
default: return false;
}
}
public static boolean IsNum(byte b) {
return b > Slash && b < Colon;
}
public static byte ToA7Int(byte b) {return (byte)(b - Num0);}
public static byte ToA7Str(int digit) {
switch (digit) {
case 0: return Num0; case 1: return Num1; case 2: return Num2; case 3: return Num3; case 4: return Num4;
case 5: return Num5; case 6: return Num6; case 7: return Num7; case 8: return Num8; case 9: return Num9;
default: throw ErrUtl.NewFmt("unknown digit; digit={0}", digit);
}
}
public static String ToStr(byte b) {return String.valueOf((char)b);}
public static byte CaseUpper(byte b) {
return b > 96 && b < 123
? (byte)(b - 32)
: b;
}
public static byte CaseLower(byte b) {
return b > 64 && b < 91
? (byte)(b + 32)
: b;
}
public static final byte[]
TabBry = new byte[] {Tab},
NlBry = new byte[] {Nl},
SpaceBry = new byte[] {Space},
BangBry = new byte[] {Bang},
QuoteBry = new byte[] {Quote},
HashBry = new byte[] {Hash},
DotBry = new byte[] {Dot},
AngleBgnBry = new byte[] {AngleBgn},
AngleEndBry = new byte[] {AngleEnd},
CommaBry = new byte[] {Comma},
ColonBry = new byte[] {Colon},
SemicBry = new byte[] {Semic},
EqBry = new byte[] {Eq},
AmpBry = new byte[] {Amp},
LtBry = new byte[] {Lt},
GtBry = new byte[] {Gt},
QuestionBry = new byte[] {Question},
BrackBgnBry = new byte[] {BrackBgn},
BrackEndBry = new byte[] {BrackEnd},
AposBry = new byte[] {Apos},
PipeBry = new byte[] {Pipe},
UnderlineBry = new byte[] {Underline},
SlashBry = new byte[] {Slash},
StarBry = new byte[] {Star},
DashBry = new byte[] {Dash},
CrLfBry = new byte[] {Cr, Nl},
Num0Bry = new byte[] {Num0},
Num1Bry = new byte[] {Num1};
}
/*
SYMBOLS
-------
Bang | Slash | 33 -> 47 | !"#$%&'()*+,-./
Colon | At | 58 -> 64 | :;<=>?@
BrackBgn | Tick | 91 -> 96 | [\]^_`
CurlyBgn | Tilde | 123 -> 126 | {|}~
*/

View File

@@ -0,0 +1,96 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.ObjectUtl;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.errs.ErrUtl;
import gplx.objects.primitives.IntUtl;
import gplx.objects.strings.bfrs.GfoStrBldr;
public class StringUtl {
public static final Class<?> ClsRefType = String.class;
public static final String ClsValName = "str" + "ing";
public static final int FindNone = -1, PosNeg1 = -1;
public static final String Empty = "", NullMark = "<<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 CharAt(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 FormatItmLhs = '{', FormatItmRhs = '}';
public static String Format(String fmt, Object... args) {
// method vars
int argsLen = ArrayUtl.LenObjAry(args);
if (argsLen == 0) return fmt; // nothing to format
int fmtLen = Len(fmt);
// loop vars
int pos = 0; String argIdxStr = ""; boolean insideBrackets = false;
GfoStrBldr bfr = new GfoStrBldr();
while (pos < fmtLen) { // loop over every char; NOTE: UT8-SAFE b/c only checking for "{"; "}"
char c = CharAt(fmt, pos);
if (insideBrackets) {
if (c == FormatItmLhs) { // first FormatItmLhs is fake; add FormatItmLhs and whatever is in argIdxStr
bfr.AddChar(FormatItmLhs).Add(argIdxStr);
argIdxStr = "";
}
else if (c == FormatItmRhs) { // itm completed
int argsIdx = IntUtl.ParseOr(argIdxStr, IntUtl.MinValue);
String itm = argsIdx != IntUtl.MinValue && IntUtl.Between(argsIdx, 0, argsLen - 1) // check (a) argsIdx is num; (b) argsIdx is in bounds
? ObjectUtl.ToStrOrNullMark(args[argsIdx]) // valid; add itm
: FormatItmLhs + argIdxStr + FormatItmRhs; // not valid; just add String
bfr.Add(itm);
insideBrackets = false;
argIdxStr = "";
}
else
argIdxStr += c;
}
else {
if (c == FormatItmLhs || c == FormatItmRhs) {
boolean posIsEnd = pos == fmtLen - 1;
if (posIsEnd) // last char is "{" or "}" (and not insideBrackets); ignore and just ad
bfr.AddChar(c);
else {
char next = CharAt(fmt, pos + 1);
if (next == c) { // "{{" or "}}": escape by doubling
bfr.AddChar(c);
pos++;
}
else
insideBrackets = true;
}
}
else
bfr.AddChar(c);
}
pos++;
}
if (Len(argIdxStr) > 0) // unclosed bracket; add FormatItmLhs and whatever is in argIdxStr; ex: "{0"
bfr.AddChar(FormatItmLhs).Add(argIdxStr);
return bfr.ToStr();
}
public static String NewByBryUtf8(byte[] v) {return v == null ? null : NewByBryUtf8(v, 0, v.length);}
public static String NewByBryUtf8(byte[] v, int bgn, int end) {
try {
return v == null
? null
: new String(v, bgn, end - bgn, "UTF-8");
}
catch (Exception e) {throw ErrUtl.NewFmt(e, "unsupported encoding; bgn={0} end={1}", bgn, end);}
}
}

View File

@@ -1,95 +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.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

@@ -1,47 +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.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,88 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.primitives.BoolUtl;
import gplx.objects.primitives.CharCode;
import gplx.objects.primitives.IntUtl;
import gplx.objects.strings.StringUtl;
import gplx.objects.strings.unicodes.UstringUtl;
public class GfoStrBldr {
private StringBuilder sb = new StringBuilder();
public int Len() {return sb.length();}
public boolean HasNone() {return this.Len() == 0;}
public boolean HasSome() {return this.Len() > 0;}
public GfoStrBldr Clear() {Del(0, this.Len()); return this;}
public GfoStrBldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
public GfoStrBldr AddFmt(String format, Object... args) {Add(StringUtl.Format(format, args)); return this;}
public GfoStrBldr AddAt(int idx, String s) {sb.insert(idx, s); return this;}
public GfoStrBldr Add(String s) {sb.append(s); return this;}
public GfoStrBldr AddChar(char c) {sb.append(c); return this;}
public GfoStrBldr AddByte(byte i) {sb.append(i); return this;}
public GfoStrBldr AddInt(int i) {sb.append(i); return this;}
public GfoStrBldr AddLong(long i) {sb.append(i); return this;}
public GfoStrBldr AddDouble(double i) {sb.append(i); return this;}
public GfoStrBldr AddObj(Object o) {sb.append(o); return this;}
public GfoStrBldr AddBry(byte[] v) {
if (v != null)
sb.append(StringUtl.NewByBryUtf8(v));
return this;
}
public GfoStrBldr AddMid(String s, int bgn) {sb.append(s, bgn, s.length()); return this;}
public GfoStrBldr AddMid(String s, int bgn, int count) {sb.append(s, bgn, count); return this;}
public GfoStrBldr AddBool(boolean val) {
this.Add(val ? BoolUtl.TrueStr : BoolUtl.FalseStr);
return this;
}
public GfoStrBldr AddBoolAsYn(boolean val) {
this.Add(val ? "y" : "n");
return this;
}
public GfoStrBldr AddCharNl() {return AddChar(CharCode.NewLine);}
public GfoStrBldr AddCharSpace() {return AddChar(CharCode.Space);}
public GfoStrBldr AddCharColon() {return AddChar(CharCode.Colon);}
public GfoStrBldr AddCharRepeat(char c, int repeat) {
this.EnsureCapacity(this.Len() + repeat);
for (int i = 0; i < repeat; i++)
AddChar(c);
return this;
}
public GfoStrBldr AddCharByCode(int code) {
if (code >= UstringUtl.SurrogateCpBgn && code <= UstringUtl.SurrogateCpEnd) {
sb.append((char)((code - 0x10000) / 0x400 + 0xD800));
sb.append((char)((code - 0x10000) % 0x400 + 0xDC00));
}
else {
sb.append((char)code);
}
return this;
}
public GfoStrBldr AddIntPadBgn(char padChar, int strLen, int val) {
int digitLen = IntUtl.CountDigits(val);
int padLen = strLen - digitLen;
if (padLen > 0) // note that this skips padLen == 0, as well as guarding against negative padLen; EX: pad(" ", 3, 1234) -> "1234"
AddCharRepeat(padChar, padLen);
AddInt(val);
return this;
}
public String ToStr() {return sb.toString();}
public String ToStrAndClear() {
String rv = ToStr();
Clear();
return rv;
}
@Override public String toString() {return ToStr();}
private void EnsureCapacity(int capacity) {sb.ensureCapacity(capacity);}
}

View File

@@ -1,35 +0,0 @@
package gplx.objects.strings.bfrs;
import gplx.objects.strings.String_;
public class GfoStringBuilder {
private final StringBuilder sb = new StringBuilder();
public int Len() {return sb.length();}
public GfoStringBuilder Clear() {
sb.delete(0, sb.length());
return this;
}
public GfoStringBuilder AddNl() {return Add("\n");}
public GfoStringBuilder Add(int v) {sb.append(v); return this;}
public GfoStringBuilder Add(String v) {sb.append(v); return this;}
public GfoStringBuilder Add(char v) {sb.append(v); return this;}
public GfoStringBuilder AddObj(Object v) {sb.append(v); return this;}
public GfoStringBuilder AddMid(String s, int bgn) {sb.append(s, bgn, s.length()); return this;}
public GfoStringBuilder AddMid(String s, int bgn, int end) {sb.append(s, bgn, end); return this;}
public GfoStringBuilder AddFmt(String fmt, Object... args) {
sb.append(String_.Format(fmt, args));
return this;
}
public GfoStringBuilder AddRepeat(char c, int repeat) {
sb.ensureCapacity(this.Len() + repeat);
for (int i = 0; i < repeat; i++)
sb.append(c);
return this;
}
public String ToStr() {return sb.toString();}
@Override
public String toString() {
return sb.toString();
}
}

View File

@@ -1,87 +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.objects.strings.bfrs; import gplx.*; import gplx.objects.*; import gplx.objects.strings.*;
import java.lang.*;
import gplx.objects.primitives.*;
import gplx.objects.errs.*;
import gplx.objects.strings.unicodes.*;
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_char_by_code(int code) {
if (code >= Ustring_.Surrogate_cp_bgn && code <= Ustring_.Surrogate_cp_end) {
sb.append((char)((code - 0x10000) / 0x400 + 0xD800));
sb.append((char)((code - 0x10000) % 0x400 + 0xDC00));
}
else {
sb.append((char)code);
}
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

@@ -1,6 +1,6 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2020 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,15 +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.objects.strings.char_sources;
public interface Char_source {
package gplx.objects.strings.charSources;
public interface CharSource {
String Src();
int Get_data(int pos);
int Len_in_data();
int GetData(int pos);
int LenInData();
String Substring(int bgn, int end);
byte[] SubstringAsBry(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);
int IndexOf(CharSource find, int bgn);
boolean Eq(int lhsBgn, CharSource rhs, int rhsBgn, int rhsEnd);
}

View File

@@ -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,18 +13,19 @@ 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;
}
}
package gplx.objects.strings.charSources;
import gplx.objects.strings.StringUtl;
public class CharSourceUtl {
public static int IndexOfAny(String src, char[] ary) {
int srcLen = StringUtl.Len(src);
int aryLen = ary.length;
for (int i = 0; i < srcLen; i++) {
for (int j = 0; j < aryLen; j++) {
if (StringUtl.CharAt(src, i) == ary[j] ) {
return i;
}
}
}
return -1;
}
}

View File

@@ -1,168 +1,166 @@
/*
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.objects.strings.unicodes;
import gplx.objects.errs.Err_;
import gplx.objects.strings.String_;
import gplx.objects.strings.char_sources.Char_source;
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 byte[] SubstringAsBry(int bgn, int end) {
String rv = src.substring(bgn, end);
try {
return rv.getBytes("UTF-8");
} catch (Exception e) {
throw new RuntimeException("failed to get bytes; src=" + src);
}
}
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 byte[] SubstringAsBry(int bgn, int end) {
String rv = src.substring(bgn, end);
try {
return rv.getBytes("UTF-8");
} catch (Exception e) {
throw new RuntimeException("failed to get bytes; src=" + src);
}
}
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;
}
}
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.errs.ErrUtl;
import gplx.objects.strings.StringUtl;
import gplx.objects.strings.charSources.CharSource;
public interface Ustring extends CharSource {
int LenInChars();
int MapDataToChar(int pos);
int MapCharToData(int pos);
}
class UstringSingle implements Ustring { // 1 char == 1 codepoint
public UstringSingle(String src, int srcLen) {
this.src = src;
this.srcLen = srcLen;
}
public String Src() {return src;} private final String src;
public int LenInChars() {return srcLen;} private final int srcLen;
public int LenInData() {return srcLen;}
public String Substring(int bgn, int end) {return src.substring(bgn, end);}
public byte[] SubstringAsBry(int bgn, int end) {
String rv = src.substring(bgn, end);
try {
return rv.getBytes("UTF-8");
} catch (Exception e) {
throw new RuntimeException("failed to get bytes; src=" + src);
}
}
public int IndexOf(CharSource find, int bgn) {return src.indexOf(find.Src(), bgn);}
public boolean Eq(int lhsBgn, CharSource rhs, int rhsBgn, int rhsEnd) {
if (srcLen < lhsBgn + rhsEnd || rhs.LenInData() < rhsBgn + rhsEnd)
return false;
while ( --rhsEnd>=0 )
if (this.GetData(lhsBgn++) != rhs.GetData(rhsBgn++))
return false;
return true;
}
public int GetData(int i) {return StringUtl.CharAt(src, i);}
public int MapDataToChar(int i) {if (i < 0 || i > srcLen) throw ErrUtl.NewFmt("invalid idx; idx={0} src={1}", i, src); return i;}
public int MapCharToData(int i) {if (i < 0 || i > srcLen) throw ErrUtl.NewFmt("invalid idx; idx={0} src={1}", i, src); return i;}
}
class UstringCodepoints implements Ustring {
private final int[] codes;
public UstringCodepoints(String src, int charsLen, int codesLen) {
// set members
this.src = src;
this.charsLen = charsLen;
this.codesLen = codesLen;
// make codes[]
this.codes = new int[codesLen];
int codeIdx = 0;
for (int i = 0; i < charsLen; i++) {
char c = src.charAt(i);
if (c >= UstringUtl.SurrogateHiBgn && c <= UstringUtl.SurrogateHiEnd) { // character is 1st part of surrogate-pair
i++;
if (i == charsLen) throw ErrUtl.NewFmt("invalid surrogate pair found; src={0}", src);
int c2 = src.charAt(i);
codes[codeIdx++] = UstringUtl.SurrogateCpBgn + (c - UstringUtl.SurrogateHiBgn) * UstringUtl.SurrogateRange + (c2 - UstringUtl.SurrogateLoBgn);
}
else {
codes[codeIdx++] = 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 >= UstringUtl.SurrogateCpBgn && code <= UstringUtl.SurrogateCpEnd ? 2 : 1;
}
char[] rv = new char[len];
int rvIdx = 0;
for (int i = bgn; i < end; i++) {
int code = codes[i];
if (code >= UstringUtl.SurrogateCpBgn && code <= UstringUtl.SurrogateCpEnd) {
rv[rvIdx++] = (char)((code - 0x10000) / 0x400 + 0xD800);
rv[rvIdx++] = (char)((code - 0x10000) % 0x400 + 0xDC00);
}
else {
rv[rvIdx++] = (char)code;
}
}
return new String(rv);
}
public byte[] SubstringAsBry(int bgn, int end) {
String rv = src.substring(bgn, end);
try {
return rv.getBytes("UTF-8");
} catch (Exception e) {
throw new RuntimeException("failed to get bytes; src=" + src);
}
}
public int IndexOf(CharSource find, int bgn) {
int findLen = find.LenInData();
int codesLen = codes.length;
for (int i = bgn; i < codes.length; i++) {
boolean found = true;
for (int j = 0; j < findLen; j++) {
int codesIdx = i + j;
if (codesIdx >= codesLen) {
found = false;
break;
}
if (codes[codesIdx] != find.GetData(j)) {
found = false;
break;
}
}
if (found == true)
return i;
}
return -1;
}
public boolean Eq(int lhsBgn, CharSource rhs, int rhsBgn, int rhsEnd) {
if (this.LenInData() < lhsBgn + rhsEnd || rhs.LenInData() < rhsBgn + rhsEnd)
return false;
while ( --rhsEnd>=0 )
if ((this.GetData(lhsBgn++) != rhs.GetData(rhsBgn++)))
return false;
return true;
}
public int LenInChars() {return charsLen;} private final int charsLen;
public int LenInData() {return codesLen;} private final int codesLen;
public int GetData(int i) {return codes[i];}
public int MapDataToChar(int codePos) {
if (codePos == codesLen) return charsLen; // if charPos is charsLen, return codesLen; allows "int end = u.MapCharToData(strLen)"
// sum all items before requested pos
int rv = 0;
for (int i = 0; i < codePos; i++) {
rv += codes[i] < UstringUtl.SurrogateCpBgn ? 1 : 2;
}
return rv;
}
public int MapCharToData(int charPos) {
if (charPos == charsLen) return codesLen; // if charPos is charsLen, return codesLen; allows "int end = u.MapCharToData(strLen)"
// sum all items before requested pos
int rv = 0;
for (int i = 0; i < charPos; i++) {
char c = src.charAt(i);
if (c >= UstringUtl.SurrogateHiBgn && c <= UstringUtl.SurrogateHiEnd){ // SurrogateHi
if (i == charPos - 1) // charPos is SurrogateLo; return -1 since SurrogateLo doesn't map to a codePos
return -1;
}
else
rv++;
}
return rv;
}
}

View File

@@ -0,0 +1,50 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.errs.ErrUtl;
public class UstringUtl {
public static Ustring NewCodepoints(String src) {
if (src == null) throw ErrUtl.NewNull("src");
// calc lens
int charsLen = src.length();
int codesLen = UstringUtl.Len(src, charsLen);
return charsLen == codesLen
? new UstringSingle(src, charsLen)
: new UstringCodepoints(src, charsLen, codesLen);
}
public static int Len(String src, int srcLen) {
int rv = 0;
for (int i = 0; i < srcLen; i++) {
char c = src.charAt(i);
if (c >= SurrogateHiBgn && c <= SurrogateHiEnd) {
i++;
}
rv++;
}
return rv;
}
public static final int // REF: https://en.wikipedia.org/wiki/Universal_Character_Set_characters
SurrogateHiBgn = 0xD800, // 55,296: Surrogate high start
SurrogateHiEnd = 0xDBFF, // 56,319: Surrogate high end
SurrogateLoBgn = 0xDC00, // 56,320: Surrogate low start
SurrogateLoEnd = 0xDFFF, // 57,343: Surrogate low end
SurrogateCpBgn = 0x010000, // 65,536: Surrogate codepoint start
SurrogateCpEnd = 0x10FFFF, // 1,114,111: Surrogate codepoint end
SurrogateRange = 0x400; // 1,024: Surrogate range (end - start) for high / low
}

View File

@@ -1,51 +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.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

@@ -1,104 +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.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,65 @@
/*
XOWA: the XOWA Offline Wiki Application
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.
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.objects.arrays.BryUtl;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.primitives.ByteUtl;
import gplx.objects.primitives.CharUtl;
import gplx.objects.primitives.DoubleUtl;
import gplx.objects.primitives.FloatUtl;
import gplx.objects.primitives.IntUtl;
import gplx.objects.primitives.LongUtl;
import gplx.objects.primitives.ShortUtl;
import gplx.objects.strings.StringUtl;
public class TypeIds {
public static final int // SERIALIZABLE.N
IdObj = 0,
IdNull = 1,
IdBool = 2,
IdByte = 3,
IdShort = 4,
IdInt = 5,
IdLong = 6,
IdFloat = 7,
IdDouble = 8,
IdChar = 9,
IdStr = 10,
IdBry = 11,
IdDate = 12,
IdDecimal = 13,
IdArray = 14;
public static int ToIdByObj(Object o) {
if (o == null) return TypeIds.IdNull;
Class<?> type = o.getClass();
return TypeIds.ToIdByCls(type);
}
public static int ToIdByCls(Class<?> type) {
if (TypeUtl.Eq(type, IntUtl.ClsRefType)) return IdInt;
else if (TypeUtl.Eq(type, StringUtl.ClsRefType)) return IdStr;
else if (TypeUtl.Eq(type, BryUtl.ClsRefType)) return IdBry;
else if (TypeUtl.Eq(type, BoolUtl.ClsRefType)) return IdBool;
else if (TypeUtl.Eq(type, ByteUtl.ClsRefType)) return IdByte;
else if (TypeUtl.Eq(type, LongUtl.ClsRefType)) return IdLong;
else if (TypeUtl.Eq(type, DoubleUtl.ClsRefType)) return IdDouble;
else if (TypeUtl.Eq(type, FloatUtl.ClsRefType)) return IdFloat;
else if (TypeUtl.Eq(type, ShortUtl.ClsRefType)) return IdShort;
else if (TypeUtl.Eq(type, CharUtl.ClsRefType)) return IdChar;
// else if (TypeUtl.Eq(type, DecimalUtl.ClsRefType)) return IdDecimal;
// else if (TypeUtl.Eq(type, DateUtl.ClsRefType)) return IdDate;
else return IdObj;
}
}

View File

@@ -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,11 +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.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);
}
}
package gplx.objects.types;
public class TypeUtl {
public static boolean Eq(Class<?> lhs, Class<?> rhs) {// NOTE: same as ObjectUtl.Eq
if (lhs == null && rhs == null) return true;
else if (lhs == null || rhs == null) return false;
else return lhs.equals(rhs);
}
}

View File

@@ -1,59 +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.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;
}
}