Refactor: Pull more classes into baselib

xowa2
gnosygnu 2 years ago
parent 48559edffe
commit 0e80d7ef6d

4
.gitignore vendored

@ -1,2 +1,2 @@
*.iml
**/.idea/**
*.iml
**/.idea/**

File diff suppressed because it is too large Load Diff

@ -1,323 +0,0 @@
/*
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;
import gplx.core.primitives.Int_obj_ref;
import gplx.core.tests.Gftest;
import gplx.objects.lists.CompareAbleUtl;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.strings.AsciiByte;
import org.junit.Test;
public class Bry__tst {
private final Bry__fxt fxt = new Bry__fxt();
@Test public void new_ascii_() {
fxt.Test_new_a7("a" , Bry_.New_by_ints(97)); // one
fxt.Test_new_a7("abc" , Bry_.New_by_ints(97, 98, 99)); // many
fxt.Test_new_a7("" , Bry_.Empty); // none
fxt.Test_new_a7("¢€𤭢" , Bry_.New_by_ints(63, 63, 63, 63)); // non-ascii -> ?
}
@Test public void new_u8() {
fxt.Test_new_u8("a" , Bry_.New_by_ints(97)); // one
fxt.Test_new_u8("abc" , Bry_.New_by_ints(97, 98, 99)); // many
fxt.Test_new_u8("¢" , Bry_.New_by_ints(194, 162)); // bry_len=2; cent
fxt.Test_new_u8("€" , Bry_.New_by_ints(226, 130, 172)); // bry_len=3; euro
fxt.Test_new_u8("𤭢" , Bry_.New_by_ints(240, 164, 173, 162)); // bry_len=4; example from en.w:UTF-8
}
@Test public void Add__bry_plus_byte() {
fxt.Test_add("a" , AsciiByte.Pipe , "a|"); // basic
fxt.Test_add("" , AsciiByte.Pipe , "|"); // empty String
}
@Test public void Add__byte_plus_bry() {
fxt.Test_add(AsciiByte.Pipe , "a" , "|a"); // basic
fxt.Test_add(AsciiByte.Pipe , "" , "|"); // empty String
}
@Test public void Add_w_dlm() {
fxt.Test_add_w_dlm(AsciiByte.Pipe, String_.Ary("a", "b", "c") , "a|b|c"); // basic
fxt.Test_add_w_dlm(AsciiByte.Pipe, String_.Ary("a") , "a"); // one item
fxt.Test_add_w_dlm(AsciiByte.Pipe, String_.Ary("a", null, "c") , "a||c"); // null
}
@Test public void Add_w_dlm_bry() {
fxt.Test_add_w_dlm("<>", String_.Ary("a","b","c"), "a<>b<>c");
}
@Test public void MidByPos() {
tst_MidByPos("abcba", 0, 1, "a");
tst_MidByPos("abcba", 0, 2, "ab");
tst_MidByPos("abcba", 1, 4, "bcb");
} void tst_MidByPos(String src, int bgn, int end, String expd) {Tfds.Eq(expd, String_.new_u8(Bry_.Mid(Bry_.new_u8(src), bgn, end)));}
@Test public void Replace_one() {
tst_ReplaceOne("a" , "b" , "c" , "a");
tst_ReplaceOne("b" , "b" , "c" , "c");
tst_ReplaceOne("bb" , "b" , "c" , "cb");
tst_ReplaceOne("abcd" , "bc" , "" , "ad");
tst_ReplaceOne("abcd" , "b" , "ee" , "aeecd");
} void tst_ReplaceOne(String src, String find, String repl, String expd) {Tfds.Eq(expd, String_.new_u8(Bry_.Replace_one(Bry_.new_u8(src), Bry_.new_u8(find), Bry_.new_u8(repl))));}
@Test public void XtoStrBytesByInt() {
tst_XtoStrBytesByInt(0, 0);
tst_XtoStrBytesByInt(9, 9);
tst_XtoStrBytesByInt(10, 1, 0);
tst_XtoStrBytesByInt(321, 3, 2, 1);
tst_XtoStrBytesByInt(-321, Bry_.Byte_NegSign, 3, 2, 1);
tst_XtoStrBytesByInt(Int_.Max_value, 2,1,4,7,4,8,3,6,4,7);
}
void tst_XtoStrBytesByInt(int val, int... expdAryAsInt) {
byte[] expd = new byte[expdAryAsInt.length];
for (int i = 0; i < expd.length; i++) {
int expdInt = expdAryAsInt[i];
expd[i] = expdInt == Bry_.Byte_NegSign ? Bry_.Byte_NegSign : AsciiByte.ToA7Str(expdAryAsInt[i]);
}
Tfds.Eq_ary(expd, Bry_.To_a7_bry(val, Int_.DigitCount(val)));
}
@Test public void Has_at_end() {
tst_HasAtEnd("a|bcd|e", "d" , 2, 5, true); // y_basic
tst_HasAtEnd("a|bcd|e", "bcd" , 2, 5, true); // y_many
tst_HasAtEnd("a|bcd|e", "|bcd" , 2, 5, false); // n_long
tst_HasAtEnd("a|bcd|e", "|bc" , 2, 5, false); // n_pos
tst_HasAtEnd("abc", "bc", true); // y
tst_HasAtEnd("abc", "bd", false); // n
tst_HasAtEnd("a", "ab", false); // exceeds_len
}
void tst_HasAtEnd(String src, String find, int bgn, int end, boolean expd) {Tfds.Eq(expd, Bry_.Has_at_end(Bry_.new_u8(src), Bry_.new_u8(find), bgn, end));}
void tst_HasAtEnd(String src, String find, boolean expd) {Tfds.Eq(expd, Bry_.Has_at_end(Bry_.new_u8(src), Bry_.new_u8(find)));}
@Test public void Has_at_bgn() {
tst_HasAtBgn("y_basic" , "a|bcd|e", "b" , 2, 5, true);
tst_HasAtBgn("y_many" , "a|bcd|e", "bcd" , 2, 5, true);
tst_HasAtBgn("n_long" , "a|bcd|e", "bcde" , 2, 5, false);
tst_HasAtBgn("n_pos" , "a|bcd|e", "|bc" , 2, 5, false);
} void tst_HasAtBgn(String tst, String src, String find, int bgn, int end, boolean expd) {Tfds.Eq(expd, Bry_.Has_at_bgn(Bry_.new_u8(src), Bry_.new_u8(find), bgn, end), tst);}
@Test public void Match() {
tst_Match("abc", 0, "abc", true);
tst_Match("abc", 2, "c", true);
tst_Match("abc", 0, "cde", false);
tst_Match("abc", 2, "abc", false); // bounds check
tst_Match("abc", 0, "abcd", false);
tst_Match("a" , 0, "", false);
tst_Match("" , 0, "a", false);
tst_Match("" , 0, "", true);
tst_Match("ab", 0, "a", false); // FIX: "ab" should not match "a" b/c .length is different
} void tst_Match(String src, int srcPos, String find, boolean expd) {Tfds.Eq(expd, Bry_.Match(Bry_.new_u8(src), srcPos, Bry_.new_u8(find)));}
@Test public void ReadCsvStr() {
tst_ReadCsvStr("a|" , "a");
tst_ReadCsvStr("|a|", 1 , "a");
Int_obj_ref bgn = Int_obj_ref.New_zero(); tst_ReadCsvStr("a|b|c|", bgn, "a"); tst_ReadCsvStr("a|b|c|", bgn, "b"); tst_ReadCsvStr("a|b|c|", bgn, "c");
tst_ReadCsvStr("|", "");
tst_ReadCsvStr_err("a");
tst_ReadCsvStr("'a'|" , "a");
tst_ReadCsvStr("'a''b'|" , "a'b");
tst_ReadCsvStr("'a|b'|" , "a|b");
tst_ReadCsvStr("''|", "");
tst_ReadCsvStr_err("''");
tst_ReadCsvStr_err("'a'b'");
tst_ReadCsvStr_err("'a");
tst_ReadCsvStr_err("'a|");
tst_ReadCsvStr_err("'a'");
}
@Test public void XtoIntBy4Bytes() { // test len=1, 2, 3, 4
tst_XtoIntBy4Bytes(32, (byte)32); // space
tst_XtoIntBy4Bytes(8707, (byte)34, (byte)3); // &exist;
tst_XtoIntBy4Bytes(6382179, AsciiByte.Ltr_a, AsciiByte.Ltr_b, AsciiByte.Ltr_c);
tst_XtoIntBy4Bytes(1633837924, AsciiByte.Ltr_a, AsciiByte.Ltr_b, AsciiByte.Ltr_c, AsciiByte.Ltr_d);
}
@Test public void XtoInt() {
tst_XtoInt("1", 1);
tst_XtoInt("123", 123);
tst_XtoInt("a", Int_.Min_value, Int_.Min_value);
tst_XtoInt("-1", Int_.Min_value, -1);
tst_XtoInt("-123", Int_.Min_value, -123);
tst_XtoInt("123-1", Int_.Min_value, Int_.Min_value);
tst_XtoInt("+123", Int_.Min_value, 123);
tst_XtoInt("", -1);
}
void tst_XtoInt(String val, int expd) {tst_XtoInt(val, -1, expd);}
void tst_XtoInt(String val, int or, int expd) {Tfds.Eq(expd, Bry_.To_int_or(Bry_.new_u8(val), or));}
void tst_XtoIntBy4Bytes(int expd, byte... ary) {Tfds.Eq(expd, Bry_.To_int_by_a7(ary), "XtoInt"); Tfds.Eq_ary(ary, Bry_.new_by_int(expd), "XbyInt");}
void tst_ReadCsvStr(String raw, String expd) {tst_ReadCsvStr(raw, Int_obj_ref.New_zero() , expd);}
void tst_ReadCsvStr(String raw, int bgn, String expd) {tst_ReadCsvStr(raw, Int_obj_ref.New(bgn), expd);}
void tst_ReadCsvStr(String raw, Int_obj_ref bgnRef, String expd) {
int bgn = bgnRef.Val();
boolean rawHasQuotes = String_.CharAt(raw, bgn) == '\'';
String actl = String_.Replace(Bry_.ReadCsvStr(Bry_.new_u8(String_.Replace(raw, "'", "\"")), bgnRef, (byte)'|'), "\"", "'");
Tfds.Eq(expd, actl, "rv");
if (rawHasQuotes) {
int quoteAdj = String_.Count(actl, "'");
Tfds.Eq(bgn + 1 + String_.Len(actl) + 2 + quoteAdj, bgnRef.Val(), "pos_quote"); // +1=lkp.Len; +2=bgn/end quotes
}
else
Tfds.Eq(bgn + 1 + String_.Len(actl), bgnRef.Val(), "pos"); // +1=lkp.Len
}
void tst_ReadCsvStr_err(String raw) {
try {Bry_.ReadCsvStr(Bry_.new_u8(String_.Replace(raw, "'", "\"")), Int_obj_ref.New_zero(), (byte)'|');}
catch (Exception e) {Err_.Noop(e); return;}
Tfds.Fail_expdError();
}
@Test public void ReadCsvDte() {
tst_ReadCsvDte("20110801 221435.987");
} void tst_ReadCsvDte(String raw) {Tfds.Eq_date(DateAdp_.parse_fmt(raw, Bry_.Fmt_csvDte), Bry_.ReadCsvDte(Bry_.new_u8(raw + "|"), Int_obj_ref.New_zero(), (byte)'|'));}
@Test public void ReadCsvInt() {
tst_ReadCsvInt("1234567890");
} void tst_ReadCsvInt(String raw) {Tfds.Eq(Int_.Parse(raw), Bry_.ReadCsvInt(Bry_.new_u8(raw + "|"), Int_obj_ref.New_zero(), (byte)'|'));}
@Test public void Trim() {
Trim_tst("a b c", 1, 4, "b");
Trim_tst("a c", 1, 3, "");
Trim_tst(" ", 0, 2, "");
} void Trim_tst(String raw, int bgn, int end, String expd) {Tfds.Eq(expd, String_.new_u8(Bry_.Trim(Bry_.new_u8(raw), bgn, end)));}
@Test public void Xto_int_lax() {
tst_Xto_int_lax("12a", 12);
tst_Xto_int_lax("1", 1);
tst_Xto_int_lax("123", 123);
tst_Xto_int_lax("a", 0);
tst_Xto_int_lax("-1", -1);
}
private void tst_Xto_int_lax(String val, int expd) {Tfds.Eq(expd, Bry_.To_int_or__lax(Bry_.new_u8(val), 0, String_.Len(val), 0));}
@Test public void To_int_or__trim_ws() {
tst_Xto_int_trim("123 " , 123);
tst_Xto_int_trim(" 123" , 123);
tst_Xto_int_trim(" 123 " , 123);
tst_Xto_int_trim(" 1 3 " , -1);
}
private void tst_Xto_int_trim(String val, int expd) {Tfds.Eq(expd, Bry_.To_int_or__trim_ws(Bry_.new_u8(val), 0, String_.Len(val), -1));}
@Test public void Compare() {
tst_Compare("abcde", 0, 1, "abcde", 0, 1, CompareAbleUtl.Same);
tst_Compare("abcde", 0, 1, "abcde", 1, 2, CompareAbleUtl.Less);
tst_Compare("abcde", 1, 2, "abcde", 0, 1, CompareAbleUtl.More);
tst_Compare("abcde", 0, 1, "abcde", 0, 2, CompareAbleUtl.Less);
tst_Compare("abcde", 0, 2, "abcde", 0, 1, CompareAbleUtl.More);
tst_Compare("abcde", 2, 3, "abçde", 2, 3, CompareAbleUtl.Less);
} void tst_Compare(String lhs, int lhs_bgn, int lhs_end, String rhs, int rhs_bgn, int rhs_end, int expd) {Tfds.Eq(expd, Bry_.Compare(Bry_.new_u8(lhs), lhs_bgn, lhs_end, Bry_.new_u8(rhs), rhs_bgn, rhs_end));}
@Test public void Increment_last() {
tst_IncrementLast(ary_(0), ary_(1));
tst_IncrementLast(ary_(0, 255), ary_(1, 0));
tst_IncrementLast(ary_(104, 111, 112, 101), ary_(104, 111, 112, 102));
}
byte[] ary_(int... ary) {
byte[] rv = new byte[ary.length];
for (int i = 0; i < ary.length; i++)
rv[i] = Byte_.By_int(ary[i]);
return rv;
}
void tst_IncrementLast(byte[] ary, byte[] expd) {Tfds.Eq_ary(expd, Bry_.Increment_last(Bry_.Copy(ary)));}
@Test public void Replace_between() {
tst_Replace_between("a[0]b" , "[", "]", "0", "a0b");
tst_Replace_between("a[0]b[1]c" , "[", "]", "0", "a0b0c");
tst_Replace_between("a[0b" , "[", "]", "0", "a[0b");
} public void tst_Replace_between(String src, String bgn, String end, String repl, String expd) {Tfds.Eq(expd, String_.new_a7(Bry_.Replace_between(Bry_.new_a7(src), Bry_.new_a7(bgn), Bry_.new_a7(end), Bry_.new_a7(repl))));}
@Test public void Replace() {
Bry_bfr tmp_bfr = Bry_bfr_.New();
tst_Replace(tmp_bfr, "a0b" , "0", "00", "a00b"); // 1 -> 1
tst_Replace(tmp_bfr, "a0b0c" , "0", "00", "a00b00c"); // 1 -> 2
tst_Replace(tmp_bfr, "a00b00c" , "00", "0", "a0b0c"); // 2 -> 1
tst_Replace(tmp_bfr, "a0b0" , "0", "00", "a00b00"); // 1 -> 2; EOS
tst_Replace(tmp_bfr, "a00b00" , "00", "0", "a0b0"); // 2 -> 1; EOS
tst_Replace(tmp_bfr, "a0b0" , "1", "2", "a0b0"); // no match
tst_Replace(tmp_bfr, "a0b0" , "b1", "b2", "a0b0"); // false match; EOS
}
public void tst_Replace(Bry_bfr tmp_bfr, String src, String bgn, String repl, String expd) {
Tfds.Eq(expd, String_.new_a7(Bry_.Replace(tmp_bfr, Bry_.new_a7(src), Bry_.new_a7(bgn), Bry_.new_a7(repl))));
}
@Test public void Split_bry() {
Split_bry_tst("a|b|c|" , "|" , String_.Ary("a", "b", "c"));
Split_bry_tst("a|" , "|" , String_.Ary("a"));
}
void Split_bry_tst(String src, String dlm, String[] expd) {
String[] actl = String_.Ary(Bry_split_.Split(Bry_.new_a7(src), Bry_.new_a7(dlm)));
Tfds.Eq_ary_str(expd, actl);
}
@Test public void Split_lines() {
Tst_split_lines("a\nb" , "a", "b"); // basic
Tst_split_lines("a\nb\n" , "a", "b"); // do not create empty trailing lines
Tst_split_lines("a\r\nb" , "a", "b"); // crlf
Tst_split_lines("a\rb" , "a", "b"); // cr only
}
void Tst_split_lines(String src, String... expd) {
Tfds.Eq_ary(expd, New_ary(Bry_split_.Split_lines(Bry_.new_a7(src))));
}
String[] New_ary(byte[][] lines) {
int len = lines.length;
String[] rv = new String[len];
for (int i = 0; i < len; i++)
rv[i] = String_.new_u8(lines[i]);
return rv;
}
@Test public void Match_bwd_any() {
Tst_match_bwd_any("abc", 2, 0, "c", true);
Tst_match_bwd_any("abc", 2, 0, "b", false);
Tst_match_bwd_any("abc", 2, 0, "bc", true);
Tst_match_bwd_any("abc", 2, 0, "abc", true);
Tst_match_bwd_any("abc", 2, 0, "zabc", false);
Tst_match_bwd_any("abc", 1, 0, "ab", true);
}
void Tst_match_bwd_any(String src, int src_end, int src_bgn, String find, boolean expd) {
Tfds.Eq(expd, Bry_.Match_bwd_any(Bry_.new_a7(src), src_end, src_bgn, Bry_.new_a7(find)));
}
@Test public void Trim_bgn() {
fxt.Test_trim_bgn(" a" , AsciiByte.Space, "a"); // trim.one
fxt.Test_trim_bgn(" a" , AsciiByte.Space, "a"); // trim.many
fxt.Test_trim_bgn("a" , AsciiByte.Space, "a"); // trim.none
fxt.Test_trim_bgn("" , AsciiByte.Space, ""); // empty
}
@Test public void Trim_end() {
fxt.Test_trim_end("a " , AsciiByte.Space, "a"); // trim.one
fxt.Test_trim_end("a " , AsciiByte.Space, "a"); // trim.many
fxt.Test_trim_end("a" , AsciiByte.Space, "a"); // trim.none
fxt.Test_trim_end("" , AsciiByte.Space, ""); // empty
}
@Test public void Mid_w_trim() {
fxt.Test_Mid_w_trim("abc", "abc"); // no ws
fxt.Test_Mid_w_trim(" a b c ", "a b c"); // ws at bgn and end
fxt.Test_Mid_w_trim("\r\n\t a\r\n\t b \r\n\t ", "a\r\n\t b"); // space at bgn and end
fxt.Test_Mid_w_trim("", ""); // handle 0 bytes
fxt.Test_Mid_w_trim(" ", ""); // handle all ws
}
@Test public void New_u8_nl_apos() {
fxt.Test__new_u8_nl_apos(String_.Ary("a"), "a");
fxt.Test__new_u8_nl_apos(String_.Ary("a", "b"), "a\nb");
fxt.Test__new_u8_nl_apos(String_.Ary("a", "b'c", "d"), "a\nb\"c\nd");
}
@Test public void Repeat_bry() {
fxt.Test__repeat_bry("abc" , 3, "abcabcabc");
}
@Test public void Xcase__build__all() {
fxt.Test__xcase__build__all(BoolUtl.N, "abc", "abc");
fxt.Test__xcase__build__all(BoolUtl.N, "aBc", "abc");
}
}
class Bry__fxt {
private final Bry_bfr tmp = Bry_bfr_.New();
public void Test_trim_end(String raw, byte trim, String expd) {
byte[] raw_bry = Bry_.new_a7(raw);
Tfds.Eq(expd, String_.new_u8(Bry_.Trim_end(raw_bry, trim, raw_bry.length)));
}
public void Test_trim_bgn(String raw, byte trim, String expd) {
byte[] raw_bry = Bry_.new_a7(raw);
Tfds.Eq(expd, String_.new_u8(Bry_.Trim_bgn(raw_bry, trim, 0)));
}
public void Test_new_u8(String raw, byte[] expd) {Tfds.Eq_ary(expd, Bry_.new_u8(raw));}
public void Test_new_a7(String raw, byte[] expd) {Tfds.Eq_ary(expd, Bry_.new_a7(raw));}
public void Test_add(String s, byte b, String expd) {Tfds.Eq_str(expd, String_.new_u8(Bry_.Add(Bry_.new_u8(s), b)));}
public void Test_add(byte b, String s, String expd) {Tfds.Eq_str(expd, String_.new_u8(Bry_.Add(b, Bry_.new_u8(s))));}
public void Test_add_w_dlm(String dlm, String[] itms, String expd) {Tfds.Eq(expd, String_.new_u8(Bry_.Add_w_dlm(Bry_.new_u8(dlm), Bry_.Ary(itms))));}
public void Test_add_w_dlm(byte dlm, String[] itms, String expd) {Tfds.Eq(expd, String_.new_u8(Bry_.Add_w_dlm(dlm, Bry_.Ary(itms))));}
public void Test_Mid_w_trim(String src, String expd) {byte[] bry = Bry_.new_u8(src); Tfds.Eq(expd, String_.new_u8(Bry_.Mid_w_trim(bry, 0, bry.length)));}
public void Test__new_u8_nl_apos(String[] ary, String expd) {
Tfds.Eq_str_lines(expd, String_.new_u8(Bry_.New_u8_nl_apos(ary)));
}
public void Test__repeat_bry(String s, int count, String expd) {
Gftest.Eq__str(expd, Bry_.Repeat_bry(Bry_.new_u8(s), count));
}
public void Test__xcase__build__all(boolean upper, String src, String expd) {
Gftest.Eq__str(expd, Bry_.Xcase__build__all(tmp, upper, Bry_.new_u8(src)));
}
}

@ -1,723 +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;
import gplx.core.primitives.*; import gplx.core.brys.*; import gplx.core.encoders.*;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.strings.AsciiByte;
public class Bry_bfr {
private Bry_bfr_mkr_mgr mkr_mgr; private int reset;
public byte[] Bfr() {return bfr;} private byte[] bfr;
public int Len() {return bfr_len;} private int bfr_len;
public boolean Len_eq_0() {return bfr_len == 0;}
public boolean Len_gt_0() {return bfr_len > 0;}
public void Bfr_init(byte[] bfr, int bfr_len) {
synchronized (this) {
this.bfr = bfr;
this.bfr_len = bfr_len;
this.bfr_max = bfr.length; // NOTE: must sync bfr_max, else will fail later during add; bfr will think bfr has .length of bfr_max, when it actually has .length of bfr_len; DATE:2014-03-09
}
}
public Bry_bfr Mkr_rls() {
if (mkr_mgr != null) {
synchronized (this) {
mkr_mgr.Rls(mkr_idx);
this.mkr_mgr = null;
this.mkr_idx = -1;
}
}
return this;
}
public void Clear_and_rls() {
this.Clear();
this.Mkr_rls();
}
public String To_str_and_rls() {return String_.new_u8(To_bry_and_rls());}
public byte[] To_bry_and_rls() {
byte[] rv = null;
synchronized (bfr) {
rv = To_bry();
this.Clear();
if (reset > 0) Reset_if_gt(reset);
synchronized (this) { // SAME: Mkr_rls()
mkr_mgr.Rls(mkr_idx);
mkr_idx = -1; // TS: DATE:2016-07-06
mkr_mgr = null;
}
}
return rv;
}
public Bry_bfr Reset_(int v) {reset = v; return this;}
public Bry_bfr Reset_if_gt(int limit) {
if (bfr_max > limit) {
this.bfr_max = limit;
this.bfr = new byte[limit];
}
bfr_len = 0;
return this;
}
public Bry_bfr Clear() {
synchronized (this) {
this.bfr_len = 0;
}
return this;
}
public Bry_bfr ClearAndReset() {bfr_len = 0; if (reset > 0) Reset_if_gt(reset); return this;}
public byte Get_at_last_or_nil_if_empty() {return bfr_len == 0 ? AsciiByte.Null : bfr[bfr_len - 1];}
public Bry_bfr Add_safe(byte[] val) {return val == null ? this : Add(val);}
public Bry_bfr Add(byte[] val) {
int val_len = val.length;
if (bfr_len + val_len > bfr_max) Resize((bfr_max + val_len) * 2);
Bry_.Copy_to(val, 0, val_len, bfr, bfr_len);
// ArrayUtl.Copy_to(val, 0, bfr, bfr_len, val_len);
bfr_len += val_len;
return this;
}
public Bry_bfr Add_mid(byte[] val, int bgn, int end) {
int len = end - bgn;
if (len < 0) throw Err_.new_wo_type("negative len", "bgn", bgn, "end", end, "excerpt", String_.new_u8__by_len(val, bgn, bgn + 16)); // NOTE: check for invalid end < bgn, else difficult to debug errors later; DATE:2014-05-11
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_to(val, bgn, end, bfr, bfr_len);
// ArrayUtl.Copy_to(val, bgn, bfr, bfr_len, len);
bfr_len += len;
return this;
}
public Bry_bfr Add_reverse_mid(byte[] val, int bgn, int end) {
int len = end - bgn;
if (len < 0) throw Err_.new_wo_type("negative len", "bgn", bgn, "end", end, "excerpt", String_.new_u8__by_len(val, bgn, bgn + 16)); // NOTE: check for invalid end < bgn, else difficult to debug errors later; DATE:2014-05-11
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_to_reversed(val, bgn, end, bfr, bfr_len);
// ArrayUtl.Copy_to(val, bgn, bfr, bfr_len, len);
bfr_len += len;
return this;
}
public Bry_bfr Add_mid_w_swap(byte[] val, int bgn, int end, byte swap_src, byte swap_trg) {
int len = end - bgn;
if (len < 0) throw Err_.new_wo_type("negative len", "bgn", bgn, "end", end, "excerpt", String_.new_u8__by_len(val, bgn, bgn + 16)); // NOTE: check for invalid end < bgn, else difficult to debug errors later; DATE:2014-05-11
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
int val_len = end - bgn;
for (int i = 0; i < val_len; ++i) {
byte b = val[i + bgn]; if (b == swap_src) b = swap_trg;
bfr[i + bfr_len] = b;
}
bfr_len += len;
return this;
}
public Bry_bfr Add_bry_ref_obj(Bry_obj_ref v) {v.Bfr_arg__add(this); return this;}
public Bry_bfr Add_bfr_and_preserve(Bry_bfr src) {
int len = src.bfr_len;
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_to(src.bfr, 0, len, bfr, bfr_len);
// ArrayUtl.Copy_to(src.bfr, 0, bfr, bfr_len, len);
bfr_len += len;
return this;
}
public Bry_bfr Add_bfr_and_clear(Bry_bfr src) {
Add_bfr_and_preserve(src);
src.ClearAndReset();
return this;
}
public Bry_bfr Add_bfr_or_mid(boolean escaped, Bry_bfr tmp_bfr, byte[] src, int src_bgn, int src_end) {
return escaped
? this.Add_bfr_and_clear(tmp_bfr)
: this.Add_mid(src, src_bgn, src_end);
}
public Bry_bfr Add_bfr_trim_and_clear(Bry_bfr src, boolean trim_bgn, boolean trim_end) {return Add_bfr_trim_and_clear(src, trim_bgn, trim_end, Bry_.Trim_ary_ws);}
public Bry_bfr Add_bfr_trim_and_clear(Bry_bfr src, boolean trim_bgn, boolean trim_end, byte[] trim_ary) {
int src_len = src.bfr_len;
if (bfr_len + src_len > bfr_max) Resize((bfr_max + src_len) * 2);
byte[] src_bry = src.Bfr();
int src_bgn = 0, src_end = src_len;
boolean all_ws = true;
if (trim_bgn) {
for (int i = 0; i < src_len; i++) {
byte b = src_bry[i];
if (trim_ary[b & 0xFF] == AsciiByte.Null) {
src_bgn = i;
i = src_len;
all_ws = false;
}
}
if (all_ws) return this;
}
if (trim_end) {
for (int i = src_len - 1; i > -1; i--) {
byte b = src_bry[i];
if (trim_ary[b & 0xFF] == AsciiByte.Null) {
src_end = i + 1;
i = -1;
all_ws = false;
}
}
if (all_ws) return this;
}
src_len = src_end - src_bgn;
Bry_.Copy_to(src.bfr, src_bgn, src_end, bfr, bfr_len);
// ArrayUtl.Copy_to(src.bfr, src_bgn, bfr, bfr_len, src_len);
bfr_len += src_len;
src.Clear();
return this;
}
public Bry_bfr Add_byte_as_a7(byte v) {return Add_byte((byte)(v + AsciiByte.Num0));}
public Bry_bfr Add_byte_eq() {return Add_byte(AsciiByte.Eq);}
public Bry_bfr Add_byte_pipe() {return Add_byte(AsciiByte.Pipe);}
public Bry_bfr Add_byte_comma() {return Add_byte(AsciiByte.Comma);}
public Bry_bfr Add_byte_semic() {return Add_byte(AsciiByte.Semic);}
public Bry_bfr Add_byte_apos() {return Add_byte(AsciiByte.Apos);}
public Bry_bfr Add_byte_slash() {return Add_byte(AsciiByte.Slash);}
public Bry_bfr Add_byte_backslash() {return Add_byte(AsciiByte.Backslash);}
public Bry_bfr Add_byte_quote() {return Add_byte(AsciiByte.Quote);}
public Bry_bfr Add_byte_space() {return Add_byte(AsciiByte.Space);}
public Bry_bfr Add_byte_nl() {return Add_byte(AsciiByte.Nl);}
public Bry_bfr Add_byte_dot() {return Add_byte(AsciiByte.Dot);}
public Bry_bfr Add_byte_colon() {return Add_byte(AsciiByte.Colon);}
public Bry_bfr Add_byte(byte val) {
int new_pos = bfr_len + 1;
if (new_pos > bfr_max) Resize(bfr_len * 2);
bfr[bfr_len] = val;
bfr_len = new_pos;
return this;
}
public Bry_bfr Add_byte_repeat(byte b, int len) {
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
for (int i = 0; i < len; i++)
bfr[i + bfr_len] = b;
bfr_len += len;
return this;
}
public Bry_bfr Add_byte_if_not_last(byte b) {
if (bfr_len == 0 || (bfr_len > 0 && bfr[bfr_len - 1] == b)) return this;
this.Add_byte(b);
return this;
}
public Bry_bfr Add_byte_variable(byte v) {return Add_int_variable(v);}
public Bry_bfr Add_short_variable(short v) {return Add_int_variable(v);}
public Bry_bfr Add_u8_int(int val) {
if (bfr_len + 4 > bfr_max) Resize((bfr_max + 4) * 2);
int utf8_len = gplx.core.intls.Utf16_.Encode_int(val, bfr, bfr_len);
bfr_len += utf8_len;
return this;
}
public Bry_bfr Add_bool(boolean v) {return Add(v ? BoolUtl.TrueBry : BoolUtl.FalseBry);}
public Bry_bfr Add_int_bool(boolean v) {return Add_int_fixed(v ? 1 : 0, 1);}
public Bry_bfr Add_int_variable(int val) {
if (val < 0) {
this.Add(Int_.To_bry(val));
return this;
}
int log10 = Int_.Log10(val);
int slots = val > -1 ? log10 + 1 : log10 * -1 + 2;
return Add_int(val, log10, slots);
}
public Bry_bfr Add_int_pad_bgn(byte pad_byte, int str_len, int val) {
int digit_len = Int_.DigitCount(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_byte_repeat(pad_byte, pad_len);
Add_int_fixed(val, digit_len);
return this;
}
public Bry_bfr Add_int_digits(int digits, int val) {return Add_int(val, Int_.Log10(val), digits);}
public Bry_bfr Add_int_fixed(int val, int digits) {return Add_int(val, Int_.Log10(val), digits);}
public Bry_bfr Add_int(int val, int valLog, int arySlots) {
int aryBgn = bfr_len, aryEnd = bfr_len + arySlots;
if (aryEnd > bfr_max) Resize((aryEnd) * 2);
if (val < 0) {
bfr[aryBgn++] = AsciiByte.Dash;
val *= -1; // make positive
valLog *= -1; // valLog will be negative; make positive
arySlots -= 1; // reduce slot by 1
}
if (valLog >= arySlots) {
val %= Int_.Log10Ary[arySlots];
}
for (int i = 0; i < arySlots; i++) {
int logIdx = arySlots - i - 1;
int div = logIdx < Int_.Log10AryLen ? Int_.Log10Ary[logIdx] : Int_.Max_value;
bfr[aryBgn + i] = (byte)((val / div) + 48);
val %= div;
}
bfr_len = aryEnd;
return this;
}
public Bry_bfr Add_long_variable(long v) {int digitCount = Long_.DigitCount(v); return Add_long(v, digitCount, digitCount);}
public Bry_bfr Add_long_fixed(long val, int digits) {return Add_long(val, Long_.DigitCount(val), digits);}
protected Bry_bfr Add_long(long val, int digitCount, int arySlots) {
int aryBgn = bfr_len, aryEnd = bfr_len + arySlots;
if (aryEnd > bfr_max) Resize((aryEnd) * 2);
if (val < 0) {
bfr[aryBgn++] = AsciiByte.Dash;
val *= -1; // make positive
arySlots -= 1; // reduce slot by 1
}
if (digitCount >= arySlots) {
val %= Long_.Log10Ary[arySlots];
}
for (int i = 0; i < arySlots; i++) {
int logIdx = arySlots - i - 1;
long div = logIdx < Long_.Log10Ary_len ? Long_.Log10Ary[logIdx] : Long_.Max_value;
bfr[aryBgn + i] = (byte)((val / div) + 48);
val %= div;
}
bfr_len = aryEnd;
return this;
}
public Bry_bfr Add_bry_comma(byte[] v) {return Add_bry(AsciiByte.Comma, v);}
public Bry_bfr Add_bry(byte dlm, byte[] v) {
if (v == null) return this;
int v_len = v.length;
for (int i = 0; i < v_len; i++) {
if (i != 0) this.Add_byte(dlm);
this.Add_int_variable(v[i]);
}
return this;
}
public Bry_bfr Add_bry_escape(byte quote_byte, byte[] escape, byte[] val, int bgn, int end) { // used for xml_wtr; DATE:2015-04-09
boolean clean = true; // add with chunks of bytes instead of one-by-one
for (int i = bgn; i < end; ++i) {
byte b = val[i];
if (clean) {
if (b == quote_byte) {
clean = false;
this.Add_mid(val, bgn, i);
this.Add(escape);
}
else {}
}
else {
if (b == quote_byte) this.Add(escape);
else this.Add_byte(b);
}
}
if (clean)
Add_mid(val, bgn, end);
return this;
}
public Bry_bfr Add_bry_many(byte[]... val) {
int len = val.length;
for (int i = 0; i < len; i++) {
byte[] bry = val[i];
if (bry != null && bry.length > 0)
this.Add(bry);
}
return this;
}
public Bry_bfr Add_bry_escape_html(byte[] val) {
if (val == null) return this;
return Add_bry_escape_html(val, 0, val.length);
}
public Bry_bfr Add_bry_escape_html(byte[] val, int bgn, int end) {
Bry_.Escape_html(this, BoolUtl.N, val, bgn, end);
return this;
}
public Bry_bfr Add_bry_escape_xml(byte[] val, int bgn, int end) {
Bry_.Escape_html(this, BoolUtl.Y, val, bgn, end);
return this;
}
public Bry_bfr Add_str_u8_w_nl(String s) {Add_str_u8(s); return Add_byte_nl();}
public Bry_bfr Add_str_u8_null(String s) {return Add_str_u8(s == null ? String_.Null_mark : s);}
public Bry_bfr Add_str_u8(String str) {
try {
int str_len = str.length();
int bry_len = Bry_.new_u8__by_len(str, str_len);
if (bfr_len + bry_len > bfr_max) Resize((bfr_max + bry_len) * 2);
Bry_.new_u8__write(str, str_len, bfr, bfr_len);
bfr_len += bry_len;
return this;
}
catch (Exception e) {throw Err_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);}
}
public Bry_bfr Add_str_u8_many(String... val) {
int len = val.length;
for (int i = 0; i < len; ++i)
Add_str_u8(val[i]);
return this;
}
public Bry_bfr Add_str_u8_fmt(String fmt, Object... args) {
Add_str_u8(String_.Format(fmt, args));
return this;
}
public Bry_bfr Add_str_a7_null(String s) {return Add_str_a7(s == null ? String_.Null_mark : s);}
public Bry_bfr Add_str_a7_w_nl(String s) {Add_str_a7(s); return Add_byte_nl();}
public Bry_bfr Add_str_a7(String str) {
try {
int bry_len = str.length();
if (bfr_len + bry_len > bfr_max) Resize((bfr_max + bry_len) * 2);
for (int i = 0; i < bry_len; ++i) {
char c = str.charAt(i);
if (c > 128) c = '?';
bfr[i + bfr_len] = (byte)c;
}
bfr_len += bry_len;
return this;
}
catch (Exception e) {throw Err_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);}
}
public Bry_bfr Add_str_mid(String src, int bgn, int end) {
this.Add_str_u8(String_.Mid(src, bgn, end));
return this;
}
public Bry_bfr Add_kv_dlm(boolean line, String key, Object val) {
this.Add_str_a7(key).Add_byte_colon().Add_byte_space();
this.Add(Bry_.new_u8(Object_.Xto_str_strict_or_null_mark(val)));
this.Add_byte(line ? AsciiByte.Nl : AsciiByte.Tab);
return this;
}
public Bry_bfr Add_float(float f) {Add_str_a7(Float_.To_str(f)); return this;}
public Bry_bfr Add_double(double v) {Add_str_a7(Double_.To_str(v)); return this;}
public Bry_bfr Add_dte(DateAdp val) {return Add_dte_segs(AsciiByte.Space , val.Year(), val.Month(),val.Day(), val.Hour(), val.Minute(), val.Second(), val.Frac());}
public Bry_bfr Add_dte_under(DateAdp val) {return Add_dte_segs(AsciiByte.Underline, val.Year(), val.Month(),val.Day(), val.Hour(), val.Minute(), val.Second(), val.Frac());}
private Bry_bfr Add_dte_segs(byte spr, int y, int M, int d, int H, int m, int s, int f) { // yyyyMMdd HHmmss.fff
if (bfr_len + 19 > bfr_max) Resize((bfr_len + 19) * 2);
bfr[bfr_len + 0] = (byte)((y / 1000) + Bry_.Ascii_zero); y %= 1000;
bfr[bfr_len + 1] = (byte)((y / 100) + Bry_.Ascii_zero); y %= 100;
bfr[bfr_len + 2] = (byte)((y / 10) + Bry_.Ascii_zero); y %= 10;
bfr[bfr_len + 3] = (byte)( y + Bry_.Ascii_zero);
bfr[bfr_len + 4] = (byte)((M / 10) + Bry_.Ascii_zero); M %= 10;
bfr[bfr_len + 5] = (byte)( M + Bry_.Ascii_zero);
bfr[bfr_len + 6] = (byte)((d / 10) + Bry_.Ascii_zero); d %= 10;
bfr[bfr_len + 7] = (byte)( d + Bry_.Ascii_zero);
bfr[bfr_len + 8] = spr;
bfr[bfr_len + 9] = (byte)((H / 10) + Bry_.Ascii_zero); H %= 10;
bfr[bfr_len + 10] = (byte)( H + Bry_.Ascii_zero);
bfr[bfr_len + 11] = (byte)((m / 10) + Bry_.Ascii_zero); m %= 10;
bfr[bfr_len + 12] = (byte)( m + Bry_.Ascii_zero);
bfr[bfr_len + 13] = (byte)((s / 10) + Bry_.Ascii_zero); s %= 10;
bfr[bfr_len + 14] = (byte)( s + Bry_.Ascii_zero);
bfr[bfr_len + 15] = AsciiByte.Dot;
bfr[bfr_len + 16] = (byte)((f / 100) + Bry_.Ascii_zero); f %= 100;
bfr[bfr_len + 17] = (byte)((f / 10) + Bry_.Ascii_zero); f %= 10;
bfr[bfr_len + 18] = (byte)( f + Bry_.Ascii_zero);
bfr_len += 19;
return this;
}
public Bry_bfr Add_dte_utc(int y, int M, int d, int H, int m, int s, int f) { // yyyy-MM-ddTHH:mm:ssZ
if (bfr_len + 20 > bfr_max) Resize((bfr_len + 20) * 2);
bfr[bfr_len + 0] = (byte)((y / 1000) + Bry_.Ascii_zero); y %= 1000;
bfr[bfr_len + 1] = (byte)((y / 100) + Bry_.Ascii_zero); y %= 100;
bfr[bfr_len + 2] = (byte)((y / 10) + Bry_.Ascii_zero); y %= 10;
bfr[bfr_len + 3] = (byte)( y + Bry_.Ascii_zero);
bfr[bfr_len + 4] = AsciiByte.Dash;
bfr[bfr_len + 5] = (byte)((M / 10) + Bry_.Ascii_zero); M %= 10;
bfr[bfr_len + 6] = (byte)( M + Bry_.Ascii_zero);
bfr[bfr_len + 7] = AsciiByte.Dash;
bfr[bfr_len + 8] = (byte)((d / 10) + Bry_.Ascii_zero); d %= 10;
bfr[bfr_len + 9] = (byte)( d + Bry_.Ascii_zero);
bfr[bfr_len + 10] = AsciiByte.Ltr_T;
bfr[bfr_len + 11] = (byte)((H / 10) + Bry_.Ascii_zero); H %= 10;
bfr[bfr_len + 12] = (byte)( H + Bry_.Ascii_zero);
bfr[bfr_len + 13] = AsciiByte.Colon;
bfr[bfr_len + 14] = (byte)((m / 10) + Bry_.Ascii_zero); m %= 10;
bfr[bfr_len + 15] = (byte)( m + Bry_.Ascii_zero);
bfr[bfr_len + 16] = AsciiByte.Colon;
bfr[bfr_len + 17] = (byte)((s / 10) + Bry_.Ascii_zero); s %= 10;
bfr[bfr_len + 18] = (byte)( s + Bry_.Ascii_zero);
bfr[bfr_len + 19] = AsciiByte.Ltr_Z;
bfr_len += 20;
return this;
}
public Bry_bfr Add_swap_ws(byte[] src) {return Add_swap_ws(src, 0, src.length);}
public Bry_bfr Add_swap_ws(byte[] src, int bgn, int end) {
int len = end - bgn;
if (bfr_len + (len * 2) > bfr_max) Resize((bfr_max + (len * 2)) * 2);
for (int i = bgn; i < end; i++) {
byte b = src[i];
switch (b) {
case AsciiByte.Nl: bfr[bfr_len] = AsciiByte.Backslash; bfr[bfr_len + 1] = AsciiByte.Ltr_n; bfr_len += 2; break;
case AsciiByte.Tab: bfr[bfr_len] = AsciiByte.Backslash; bfr[bfr_len + 1] = AsciiByte.Ltr_t; bfr_len += 2; break;
case AsciiByte.Backslash: bfr[bfr_len] = AsciiByte.Backslash; bfr[bfr_len + 1] = AsciiByte.Backslash; bfr_len += 2; break;
default: bfr[bfr_len] = b; ++bfr_len; break;
}
}
return this;
}
public Bry_bfr Add_str_pad_space_bgn(String v, int pad_max) {return Add_str_pad_space(v, pad_max, BoolUtl.N);}
public Bry_bfr Add_str_pad_space_end(String v, int pad_max) {return Add_str_pad_space(v, pad_max, BoolUtl.Y);}
Bry_bfr Add_str_pad_space(String v, int pad_max, boolean pad_end) {
byte[] v_bry = Bry_.new_u8(v);
if (pad_end) Add(v_bry);
int pad_len = pad_max - v_bry.length;
if (pad_len > 0)
Add_byte_repeat(AsciiByte.Space, pad_len);
if (!pad_end) Add(v_bry);
return this;
}
public Bry_bfr Add_obj(Object o) {
if (o == null) return this; // treat null as empty String;
Class<?> o_type = o.getClass();
if (o_type == byte[].class) Add((byte[])o);
else if (o_type == Integer.class) Add_int_variable(Int_.Cast(o));
else if (o_type == Byte.class) Add_byte(Byte_.Cast(o));
else if (o_type == Long.class) Add_long_variable(Long_.cast(o));
else if (o_type == String.class) Add_str_u8((String)o);
else if (o_type == Bry_bfr.class) Add_bfr_and_preserve((Bry_bfr)o);
else if (o_type == DateAdp.class) Add_dte((DateAdp)o);
else if (o_type == Io_url.class) Add(((Io_url)o).RawBry());
else if (o_type == Boolean.class) Add_yn(BoolUtl.Cast(o));
else if (o_type == Double.class) Add_double(Double_.cast(o));
else if (o_type == Float.class) Add_float(Float_.cast(o));
else ((Bfr_arg)o).Bfr_arg__add(this);
return this;
}
public Bry_bfr Add_obj_strict(Object o) {
if (o == null) return this; // treat null as empty String;
Class<?> o_type = o.getClass();
if (o_type == byte[].class) Add((byte[])o);
else if (o_type == Integer.class) Add_int_variable(Int_.Cast(o));
else if (o_type == Byte.class) Add_byte(Byte_.Cast(o));
else if (o_type == Long.class) Add_long_variable(Long_.cast(o));
else if (o_type == String.class) Add_str_u8((String)o);
else if (o_type == Bry_bfr.class) Add_bfr_and_preserve((Bry_bfr)o);
else if (o_type == DateAdp.class) Add_dte((DateAdp)o);
else if (o_type == Io_url.class) Add(((Io_url)o).RawBry());
else if (o_type == Boolean.class) Add_bool(BoolUtl.Cast(o));
else if (o_type == Double.class) Add_double(Double_.cast(o));
else if (o_type == Float.class) Add_float(Float_.cast(o));
else ((Bfr_arg)o).Bfr_arg__add(this);
return this;
}
public Bry_bfr Add_yn(boolean v) {Add_byte(v ? AsciiByte.Ltr_y : AsciiByte.Ltr_n); return this;}
public Bry_bfr Add_base85_len_5(int v) {return Add_base85(v, 5);}
public Bry_bfr Add_base85(int v, int pad) {
int new_len = bfr_len + pad;
if (new_len > bfr_max) Resize((new_len) * 2);
Base85_.Set_bry(v, bfr, bfr_len, pad);
bfr_len = new_len;
return this;
}
public boolean Match_end_byt(byte b) {return bfr_len == 0 ? false : bfr[bfr_len - 1] == b;}
public boolean Match_end_byt_nl_or_bos() {return bfr_len == 0 ? true : bfr[bfr_len - 1] == AsciiByte.Nl;}
public boolean Match_end_ary(byte[] val) {return Bry_.Match(bfr, bfr_len - val.length, bfr_len, val);}
public Bry_bfr Insert_at(int add_pos, byte[] add_bry) {return Insert_at(add_pos, add_bry, 0, add_bry.length);}
public Bry_bfr Insert_at(int add_pos, byte[] add_bry, int add_bgn, int add_end) {
int add_len = add_end - add_bgn;
int new_max = bfr_max + add_len;
byte[] new_bfr = new byte[new_max];
if (add_pos > 0)
Bry_.Copy_to (bfr , 0, add_pos, new_bfr, 0);
Bry_.Copy_to (add_bry, add_bgn, add_end, new_bfr, add_pos);
Bry_.Copy_to (bfr , add_pos, bfr_len, new_bfr, add_pos + add_len);
bfr = new_bfr;
bfr_len += add_len;
bfr_max = new_max;
return this;
}
public Bry_bfr Delete_rng_to_bgn(int pos) {return Delete_rng(0, pos);}
public Bry_bfr Delete_rng_to_end(int pos) {return Delete_rng(pos, bfr_len);}
public Bry_bfr Delete_rng(int rng_bgn, int rng_end) {
int rng_len = rng_end - rng_bgn;
Bry_.Copy_to(bfr, rng_end, bfr_len, bfr, rng_bgn);
bfr_len -= rng_len;
return this;
}
public Bry_bfr Del_by_1() {
bfr_len -= 1; bfr[bfr_len] = 0; return this;
}
public Bry_bfr Del_by(int count) {
int new_len = bfr_len - count;
if (new_len > -1) bfr_len = new_len;
return this;
}
public Bry_bfr Trim_end(byte trim_byte) {
if (bfr_len == 0) return this;
int count = 0;
for (int i = bfr_len - 1; i > -1; --i) {
byte b = bfr[i];
if (b == trim_byte)
++count;
else
break;
}
if (count > 0)
this.Del_by(count);
return this;
}
public Bry_bfr Trim_end_ws() {
if (bfr_len == 0) return this;
int count = 0;
for (int i = bfr_len - 1; i > -1; --i) {
byte b = bfr[i];
if (Trim_end_ws_ary[b])
++count;
else
break;
}
if (count > 0)
this.Del_by(count);
return this;
}
private static final boolean[] Trim_end_ws_ary = Trim_end_ws_new();
private static boolean[] Trim_end_ws_new() {
boolean[] rv = new boolean[256];
rv[32] = true;
rv[ 9] = true;
rv[10] = true;
rv[13] = true;
rv[11] = true;
return rv;
}
public Bry_bfr Concat_skip_empty(byte[] dlm, byte[]... val) {
int val_len = val.length;
for (int i = 0; i < val_len; i++) {
byte[] itm = val[i];
boolean itm_has_bytes = Bry_.Len_gt_0(itm);
if ( i != 0
&& itm_has_bytes
&& bfr_len > 0
)
this.Add(dlm);
if (itm_has_bytes)
this.Add(itm);
}
return this;
}
public boolean Eq(byte b) {return bfr_len == 1 && bfr[0] == b;}
public byte[] To_bry(int bgn, int end) {return bfr_len == 0 ? Bry_.Empty : Bry_.Mid(bfr, bgn, end);}
public byte[] To_bry() {return bfr_len == 0 ? Bry_.Empty : Bry_.Mid(bfr, 0, bfr_len);}
public byte[] To_bry_and_clear_and_trim() {return To_bry_and_clear_and_trim(true, true, Bry_.Trim_ary_ws);}
public byte[] To_bry_and_clear_and_trim(boolean trim_bgn, boolean trim_end, byte[] trim_bry) {
byte[] rv = Bry_.Trim(bfr, 0, bfr_len, trim_bgn, trim_end, trim_bry, false); // NOTE: must not reuse bry; ISSUE#:562; DATE:2019-09-02
this.Clear();
return rv;
}
public byte[] To_bry_and_clear() {
byte[] rv = To_bry();
this.Clear();
if (reset > 0) Reset_if_gt(reset);
return rv;
}
public byte[] To_bry_and_clear_and_rls() {
byte[] rv = To_bry_and_clear();
this.Mkr_rls();
return rv;
}
public byte[] To_reversed_bry_and_clear() {
int len = this.Len();
byte[] rv = new byte[len];
for (int i = 0; i < len; i++) {
rv[len - i - 1] = bfr[i];
}
this.Clear();
if (reset > 0) Reset_if_gt(reset);
return rv;
}
public String To_str() {return String_.new_u8(To_bry());}
public String To_str_by_pos(int bgn, int end) {return String_.new_u8(To_bry(), bgn, end);}
public String To_str_and_clear() {return String_.new_u8(To_bry_and_clear());}
public String To_str_and_clear_and_trim() {return String_.new_u8(To_bry_and_clear_and_trim());}
public int To_int_and_clear(int or) {int rv = To_int(or); this.Clear(); return rv;}
public int To_int(int or) {
switch (bfr_len) {
case 0: return or;
case 1: {
byte b = bfr[0];
return AsciiByte.IsNum(b) ? b - AsciiByte.Num0 : or;
}
default:
long rv = 0, mult = 1;
for (int i = bfr_len - 1; i > -1; i--) {
byte b = bfr[i];
if (!AsciiByte.IsNum(b)) return or;
long dif = (b - AsciiByte.Num0) * mult;
long new_val = rv + dif;
if (new_val > Int_.Max_value) return or; // if number is > 2^32 consider error (int overflow); return or; DATE:2014-06-10
rv = new_val;
mult *= 10;
}
return (int)rv;
}
}
public void Rls() {
bfr = null;
this.Mkr_rls();
}
public byte[][] To_bry_ary_and_clear() {
if (bfr_len == 0) return Bry_.Ary_empty;
Int_list line_ends = Find_all(AsciiByte.Nl);
// create lines
int lines_len = line_ends.Len();
byte[][] rv = new byte[lines_len][];
int line_bgn = 0;
for (int i = 0; i < lines_len; ++i) {
int line_end = line_ends.Get_at(i);
rv[i] = Bry_.Mid(bfr, line_bgn, line_end);
line_bgn = line_end + 1;
}
this.ClearAndReset();
return rv;
}
public String[] To_str_ary_and_clear() {
if (bfr_len == 0) return String_.Ary_empty;
Int_list line_ends = Find_all(AsciiByte.Nl);
// create lines
int lines_len = line_ends.Len();
String[] rv = new String[lines_len];
int line_bgn = 0;
for (int i = 0; i < lines_len; ++i) {
int line_end = line_ends.Get_at(i);
rv[i] = String_.new_u8(bfr, line_bgn, line_end);
line_bgn = line_end + 1;
}
this.ClearAndReset();
return rv;
}
private Int_list Find_all(byte find) {
Int_list rv = new Int_list();
// scan bfr for nl
int line_bgn = 0, line_end = 0;
while (line_bgn < bfr_len) {
line_end = Bry_find_.Find_fwd(bfr, find, line_bgn, bfr_len);
if (line_end == Bry_find_.Not_found) { // no more \n; add bfr_end
rv.Add(bfr_len);
break;
}
else { // \n found; add it
rv.Add(line_end);
line_bgn = line_end + 1;
}
}
return rv;
}
@Override public int hashCode() {return Bry_obj_ref.CalcHashCode(bfr, 0, bfr_len);}
@Override public boolean equals(Object obj) {
if (obj == null) return false; // NOTE: strange, but null check needed; throws null error; EX.WP: File:Eug<75>ne Delacroix - La libert<72> guidant le peuple.jpg
Bry_obj_ref comp = (Bry_obj_ref)obj;
return Bry_.Match(bfr, 0, bfr_len, comp.Val(), comp.Val_bgn(), comp.Val_end());
}
public void Resize(int v) {
bfr_max = v;
bfr = Bry_.Resize(bfr, 0, v);
}
public int Mkr_idx() {return mkr_idx;} private int mkr_idx = -1;
public boolean Mkr_idx_is_null() {return mkr_idx == -1;}
public int Bfr_max() {return bfr_max;} private int bfr_max;
public Bry_bfr Mkr_init(Bry_bfr_mkr_mgr mkr_mgr, int itm) {
synchronized (this) {
this.mkr_mgr = mkr_mgr; this.mkr_idx = itm;
}
return this;
}
protected Bry_bfr() {}
public Bry_bfr(int bfr_max) {
Init(bfr_max);
}
protected void Init(int bfr_max) {
this.bfr_max = bfr_max;
this.bfr = new byte[bfr_max];
}
}

@ -1,43 +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;
import gplx.core.brys.*;
public class Bry_bfr_ {
public static Bry_bfr New() {return new Bry_bfr(16);}
public static Bry_bfr New_w_size(int v) {return new Bry_bfr(v);}
public static Bry_bfr Reset(int v) {return new Bry_bfr(16).Reset_(v);} // PERF: set initial size to 16, not reset val; allows for faster "startup"; DATE:2014-06-14
public static final Bry_bfr[] Ary_empty = new Bry_bfr[0];
private static Bry_bfr_mkr_mgr dflt;
public static Bry_bfr Get() {if (dflt == null) dflt = new Bry_bfr_mkr_mgr(Bry_bfr_mkr.Tid_b128, 128); return dflt.Get();} // NOTE: lazy else "Object synchronization" error; DATE:2015-11-18
public static void Assert_at_end(Bry_bfr bfr, byte assert_byte) {
int len = bfr.Len(); if (len == 0) return;
int assert_count = 0;
byte[] bfr_bry = bfr.Bfr();
for (int i = len - 1; i > -1; --i) {
byte b = bfr_bry[i];
if (b == assert_byte)
++assert_count;
else
break;
}
switch (assert_count) {
case 0: bfr.Add_byte(assert_byte); break;
case 1: break;
default: bfr.Del_by(assert_count - 1); break;
}
}
}

@ -1,262 +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;
import gplx.objects.strings.AsciiByte;
import org.junit.*; import gplx.core.tests.*;
public class Bry_bfr_tst {
private Bry_bfr bb = Bry_bfr_.New();
@Before public void setup() {bb.Clear();} private ByteAryBfr_fxt fxt = new ByteAryBfr_fxt();
@Test public void AddByte() {
bb = Bry_bfr_.New_w_size(2); // NOTE: make sure auto-expands
tst_AddByte("a", "a", 2);
tst_AddByte("b", "ab", 2);
tst_AddByte("c", "abc", 4);
}
@Test public void AddAry() { // NOTE: make sure auto-expands
bb = Bry_bfr_.New_w_size(2);
tst_AddByte("abcd", "abcd", 12);
}
@Test public void Add_byte_repeat() { // NOTE: make sure auto-expands
bb = Bry_bfr_.New_w_size(2);
tst_Add_byte_repeat(AsciiByte.Space, 12, String_.Repeat(" ", 12));
} void tst_Add_byte_repeat(byte b, int len, String expd) {Tfds.Eq(expd, bb.Add_byte_repeat(b, len).To_str_and_clear());}
void tst_AddByte(String s, String expdStr, int expdLen) {
if (String_.Len(s) == 1)
bb.Add_byte((byte)String_.CharAt(s, 0));
else
bb.Add(Bry_.new_u8(s));
Tfds.Eq(expdStr, String_.new_u8(bb.To_bry()));
Tfds.Eq(expdLen, bb.Bfr_max());
}
@Test public void Add_dte() {
tst_AddDte("20110801 221435.987");
}
void tst_AddDte(String raw) {
bb.Add_dte(DateAdp_.parse_fmt(raw, Bry_.Fmt_csvDte));
Tfds.Eq(raw, String_.new_u8(bb.To_bry()));
}
@Test public void Add_int_variable() {
Add_int_variable(-1);
Add_int_variable(-12);
Add_int_variable(-1234);
Add_int_variable(2);
Add_int_variable(12);
Add_int_variable(1234);
Add_int_variable(123456789);
}
@Test public void Add_float() {
tst_Add_float(1 / 3);
tst_Add_float(-1 / 3);
}
void tst_Add_float(float v) {
bb.Add_float(v);
Tfds.Eq(v, Float_.parse(String_.new_u8(bb.To_bry())));
}
void Add_int_variable(int val) {
bb.Clear();
bb.Add_int_variable(val);
Tfds.Eq(val, Int_.Parse(String_.new_u8(bb.To_bry())));
}
@Test public void Add_int_fixed_len3() {tst_Add_int_fixed(123, 3, "123");}
@Test public void Add_int_fixed_pad_1() {tst_Add_int_fixed(2, 1, "2");}
@Test public void Add_int_fixed_pad_2() {tst_Add_int_fixed(2, 2, "02");}
@Test public void Add_int_fixed_pad_16() {tst_Add_int_fixed(2, 16, "0000000000000002");} // test overflows int
@Test public void Add_int_fixed_neg() {tst_Add_int_fixed(-2, 2, "-2");}
@Test public void Add_int_fixed_neg_pad1() {tst_Add_int_fixed(-2, 1, "-");}
@Test public void Add_int_fixed_chop_1() {tst_Add_int_fixed(123, 1, "3");}
@Test public void Add_int_fixed_chop_neg() {tst_Add_int_fixed(-21, 2, "-1");}
void tst_Add_int_fixed(int val, int digits, String expd) {Tfds.Eq(expd, String_.new_u8(bb.Add_int_fixed(val, digits).To_bry()));}
@Test public void Add_long_fixed_len3() {tst_Add_long_fixed(123, 3, "123");}
@Test public void Add_long_fixed_pad_1() {tst_Add_long_fixed(2, 1, "2");}
@Test public void Add_long_fixed_pad_2() {tst_Add_long_fixed(2, 2, "02");}
@Test public void Add_long_fixed_pad_16() {tst_Add_long_fixed(2, 16, "0000000000000002");} // test overflows long
@Test public void Add_long_fixed_neg() {tst_Add_long_fixed(-2, 2, "-2");}
@Test public void Add_long_fixed_neg_pad1() {tst_Add_long_fixed(-2, 1, "-");}
@Test public void Add_long_fixed_chop_1() {tst_Add_long_fixed(123, 1, "3");}
@Test public void Add_long_fixed_chop_neg() {tst_Add_long_fixed(-21, 2, "-1");}
@Test public void Add_long_fixed_large() {tst_Add_long_fixed(123456789012345L, 15, "123456789012345");}
void tst_Add_long_fixed(long val, int digits, String expd) {Tfds.Eq(expd, String_.new_u8(bb.Add_long_fixed(val, digits).To_bry()));}
@Test public void AddDte_short() {
tst_AddDte_short("2010-08-26T22:38:36Z");
}
void tst_AddDte_short(String raw) {
// byte[] ary = String_.XtoByteAryAscii(raw);
// Bry_fmtr_IntBldr ib = new Bry_fmtr_IntBldr();
// int y = 0, m = 0, d = 0, h = 0, n = 0, s = 0, aryLen = ary.length;
// for (int i = 0; i < aryLen; i++) {
// byte b = ary[i];
// switch (i) {
// case 4: y = ib.To_int_and_clear(); break;
// case 7: m = ib.To_int_and_clear(); break;
// case 10: d = ib.To_int_and_clear(); break;
// case 13: h = ib.To_int_and_clear(); break;
// case 16: n = ib.To_int_and_clear(); break;
// case 19: s = ib.To_int_and_clear(); break;
// default: ib.Add(b); break;
// }
// }
// long l = Pow38_to(y, m, d, h, n, s);
//// Base85_.Set_bry(l, bb.
// bb.Add_int(l);
}
// @Test public void InsertAt_str() {
// tst_InsertAt_str("", 0, "c", "c");
// tst_InsertAt_str("ab", 0, "c", "cab");
// tst_InsertAt_str("ab", 0, "cdefghij", "cdefghijab");
// }
// void tst_InsertAt_str(String orig, int insertAt, String insertStr, String expd) {
// bb = Bry_bfr_.New(16);
// bb.Add_str(orig);
// bb.InsertAt_str(insertAt, insertStr);
// String actl = bb.To_str_and_clear();
// Tfds.Eq(expd, actl);
// }
@Test public void To_bry_and_clear_and_trim() {
tst_XtoAryAndClearAndTrim("a" , "a");
tst_XtoAryAndClearAndTrim(" a " , "a");
tst_XtoAryAndClearAndTrim(" a b " , "a b");
tst_XtoAryAndClearAndTrim(" " , "");
}
void tst_XtoAryAndClearAndTrim(String raw, String expd) {
bb.Add_str_u8(raw);
Tfds.Eq(expd, String_.new_u8(bb.To_bry_and_clear_and_trim()));
}
@Test public void XtoInt() {
tst_XtoInt("123", 123);
tst_XtoInt("a", Int_.Min_value);
tst_XtoInt("9999999999", Int_.Min_value);
}
void tst_XtoInt(String raw, int expd) {
bb.Add_str_u8(raw);
Tfds.Eq(expd, bb.To_int_and_clear(Int_.Min_value));
}
static long Pow38_to(int year, int month, int day, int hour, int minute, int second, int frac) {
return ((long)year) << 26
| ((long)month & 0x0f) << 22 // 16
| ((long)day & 0x1f) << 17 // 32
| ((long)hour & 0x1f) << 12 // 32
| ((long)minute & 0x3f) << 6 // 64
| ((long)second & 0x3f) // 64
;
}
static DateAdp Pow38_by(long v) {
int year = (int) (v >> 26);
int month = (int)((v >> 22) & 0x0f);
int day = (int)((v >> 17) & 0x1f);
int hour = (int)((v >> 12) & 0x1f);
int minute = (int)((v >> 6) & 0x3f);
int second = (int)((v ) & 0x3f);
return DateAdp_.new_(year, month, day, hour, minute, second, 0);
}
@Test public void Add_bfr_trimEnd_and_clear() {
tst_Add_bfr_trimEnd_and_clear("a ", "a");
}
void tst_Add_bfr_trimEnd_and_clear(String raw, String expd) {
Bry_bfr tmp = Bry_bfr_.New().Add_str_u8(raw);
Tfds.Eq(expd, bb.Add_bfr_trim_and_clear(tmp, false, true).To_str_and_clear());
}
@Test public void Add_bfr_trimAll_and_clear() {
tst_Add_bfr_trimAll_and_clear(" a ", "a");
tst_Add_bfr_trimAll_and_clear(" a b ", "a b");
tst_Add_bfr_trimAll_and_clear("a", "a");
tst_Add_bfr_trimAll_and_clear("", "");
}
void tst_Add_bfr_trimAll_and_clear(String raw, String expd) {
Bry_bfr tmp = Bry_bfr_.New().Add_str_u8(raw);
Tfds.Eq(expd, bb.Add_bfr_trim_and_clear(tmp, true, true).To_str_and_clear());
}
@Test public void Add_int_pad_bgn() {
fxt.Test_Add_int_pad_bgn(AsciiByte.Num0, 3, 0, "000");
fxt.Test_Add_int_pad_bgn(AsciiByte.Num0, 3, 1, "001");
fxt.Test_Add_int_pad_bgn(AsciiByte.Num0, 3, 10, "010");
fxt.Test_Add_int_pad_bgn(AsciiByte.Num0, 3, 100, "100");
fxt.Test_Add_int_pad_bgn(AsciiByte.Num0, 3, 1000, "1000");
}
@Test public void Add_bry_escape() {
fxt.Test__add_bry_escape("abc" , "abc"); // nothing to escape
fxt.Test__add_bry_escape("a'bc" , "a''bc"); // single escape (code handles first quote differently)
fxt.Test__add_bry_escape("a'b'c" , "a''b''c"); // double escape (code handles subsequent quotes different than first)
fxt.Test__add_bry_escape("abc", 1, 2 , "b"); // nothing to escape
}
@Test public void Add_bry_escape_html() {
fxt.Test__add_bry_escape_html("abc" , "abc"); // escape=none
fxt.Test__add_bry_escape_html("a&\"'<>b" , "a&amp;&quot;&#39;&lt;&gt;b"); // escape=all; code handles first escape differently
fxt.Test__add_bry_escape_html("a&b&c" , "a&amp;b&amp;c"); // staggered; code handles subsequent escapes differently
fxt.Test__add_bry_escape_html("abc", 1, 2 , "b"); // by index; fixes bug in initial implementation
}
@Test public void Insert_at() {
fxt.Test_Insert_at("abcd", 0, "xyz" , "xyzabcd"); // bgn
fxt.Test_Insert_at("abcd", 4, "xyz" , "abcdxyz"); // end
fxt.Test_Insert_at("abcd", 2, "xyz" , "abxyzcd"); // mid
fxt.Test_Insert_at("abcd", 2, "xyz", 1, 2 , "abycd"); // mid
}
@Test public void Delete_rng() {
fxt.Test_Delete_rng("abcd", 0, 2 , "cd"); // bgn
fxt.Test_Delete_rng("abcd", 2, 4 , "ab"); // end
fxt.Test_Delete_rng("abcd", 1, 3 , "ad"); // mid
}
@Test public void Delete_rng_to_bgn() {
fxt.Test_Delete_rng_to_bgn("abcd", 2 , "cd");
}
@Test public void Delete_rng_to_end() {
fxt.Test_Delete_rng_to_end("abcd", 2 , "ab");
}
@Test public void To_bry_ary_and_clear() {
fxt.Test__to_bry_ary_and_clear("" ); // empty
fxt.Test__to_bry_ary_and_clear("a" , "a"); // lines=1
fxt.Test__to_bry_ary_and_clear("a\nb\nc" , "a", "b", "c"); // lines=n
fxt.Test__to_bry_ary_and_clear("a\n" , "a"); // nl at end
}
@Test public void To_bry_ary_and_clear_and_trim__memory_reference_bug() {// PURPOSE:test that bry isn't reused; ISSUE#:562; DATE:2019-09-02
String str_a = "aaaaaaaaaaaaaaaa" // NOTE: length is 16 b/c bry_bfr init's to 16 len
, str_b = "bbbbbbbbbbbbbbbb";
Bry_bfr bfr = Bry_bfr_.New();
bfr.Add_str_a7(str_a);
byte[] bry_a = bfr.To_bry_and_clear_and_trim();
Gftest.Eq__str(str_a, String_.new_u8(bry_a));
bfr.Add_str_a7(str_b);
byte[] bry_b = bfr.To_bry_and_clear_and_trim();
Gftest.Eq__str(str_b, String_.new_u8(bry_b));
Gftest.Eq__str(str_a, String_.new_u8(bry_a)); // fais if bry_b
}
}
class ByteAryBfr_fxt {
private final Bry_bfr bfr = Bry_bfr_.Reset(16);
public Bry_bfr Bfr() {return bfr;}
public void Clear() {
bfr.ClearAndReset();
}
public void Test_Add_int_pad_bgn(byte pad_byte, int str_len, int val, String expd) {Tfds.Eq(expd, bfr.Add_int_pad_bgn(pad_byte, str_len, val).To_str_and_clear());}
public void Test__add_bry_escape(String src, String expd) {Test__add_bry_escape(src, 0, String_.Len(src), expd);}
public void Test__add_bry_escape(String src, int src_bgn, int src_end, String expd) {
byte[] val_bry = Bry_.new_u8(src);
Tfds.Eq(expd, bfr.Add_bry_escape(AsciiByte.Apos, Byte_.Ary(AsciiByte.Apos, AsciiByte.Apos), val_bry, src_bgn, src_end).To_str_and_clear());
}
public void Test_Insert_at(String init, int pos, String val, String expd) {Tfds.Eq(expd, bfr.Add_str_u8(init).Insert_at(pos, Bry_.new_u8(val)).To_str_and_clear());}
public void Test_Insert_at(String init, int pos, String val, int val_bgn, int val_end, String expd) {Tfds.Eq(expd, bfr.Add_str_u8(init).Insert_at(pos, Bry_.new_u8(val), val_bgn, val_end).To_str_and_clear());}
public void Test_Delete_rng(String init, int bgn, int end, String expd) {Tfds.Eq(expd, bfr.Add_str_u8(init).Delete_rng(bgn, end).To_str_and_clear());}
public void Test_Delete_rng_to_bgn(String init, int pos, String expd) {Tfds.Eq(expd, bfr.Add_str_u8(init).Delete_rng_to_bgn(pos).To_str_and_clear());}
public void Test_Delete_rng_to_end(String init, int pos, String expd) {Tfds.Eq(expd, bfr.Add_str_u8(init).Delete_rng_to_end(pos).To_str_and_clear());}
public void Test__to_bry_ary_and_clear(String bfr_str, String... expd) {
Tfds.Eq_ary(expd, String_.Ary(bfr.Add_str_u8(bfr_str).To_bry_ary_and_clear()));
}
public void Test__add_bry_escape_html(String src, String expd) {Test__add_bry_escape_html(src, 0, String_.Len(src), expd);}
public void Test__add_bry_escape_html(String src, int src_bgn, int src_end, String expd) {
Gftest.Eq__bry(Bry_.new_u8(expd), bfr.Add_bry_escape_html(Bry_.new_u8(src), src_bgn, src_end).To_bry_and_clear());
}
}

@ -1,422 +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;
import gplx.objects.strings.AsciiByte;
public class Bry_find_ {
public static final int Not_found = -1;
public static int Find_fwd(byte[] src, byte lkp) {return Find_fwd(src, lkp, 0, src.length);}
public static int Find_fwd(byte[] src, byte lkp, int cur) {return Find_fwd(src, lkp, cur, src.length);}
public static int Find_fwd(byte[] src, byte lkp, int cur, int end) {
for (int i = cur; i < end; i++)
if (src[i] == lkp) return i;
return Bry_find_.Not_found;
}
public static int Find_fwd_or(byte[] src, byte lkp, int cur, int end, int or) {
int rv = Find_fwd(src, lkp, cur, end);
return rv == Bry_find_.Not_found ? or : rv;
}
public static int Find_fwd_or(byte[] src, byte[] lkp, int cur, int end, int or) {
int rv = Find_fwd(src, lkp, cur, end);
return rv == Bry_find_.Not_found ? or : rv;
}
public static int Find_bwd(byte[] src, byte lkp) {return Find_bwd(src, lkp, src.length, 0);}
public static int Find_bwd(byte[] src, byte lkp, int cur) {return Find_bwd(src, lkp, cur , 0);}
public static int Find_bwd(byte[] src, byte lkp, int cur, int end) {
--cur; // always subtract 1 from cur; allows passing in src_len or cur_pos without forcing caller to subtract - 1; DATE:2014-02-11
--end;
for (int i = cur; i > end; i--)
if (src[i] == lkp) return i;
return Bry_find_.Not_found;
}
public static int Find_bwd_or(byte[] src, byte lkp, int cur, int end, int or) {
int rv = Find_bwd(src, lkp, cur, end);
return rv == Bry_find_.Not_found ? or : rv;
}
public static int Move_fwd(byte[] src, byte lkp, int cur, int end) {
int rv = Find_fwd(src, lkp, cur, src.length);
return rv == Bry_find_.Not_found ? rv : rv + 1;
}
public static int Move_fwd(byte[] src, byte[] lkp, int cur) {return Move_fwd(src, lkp, cur, src.length);}
public static int Move_fwd(byte[] src, byte[] lkp, int cur, int end) {
int rv = Find_fwd(src, lkp, cur, src.length);
return rv == Bry_find_.Not_found ? rv : rv + lkp.length;
}
public static int Find_fwd(byte[] src, byte[] lkp) {return Find(src, lkp, 0 , src.length, true);}
public static int Find_fwd(byte[] src, byte[] lkp, int cur) {return Find(src, lkp, cur , src.length, true);}
public static int Find_fwd(byte[] src, byte[] lkp, int cur, int end) {return Find(src, lkp, cur , end, true);}
private static final int OffsetCompare = 1;// handle srcPos >= 1 -> srcPosChk > 0
public static int Find(byte[] src, byte[] lkp, int src_bgn, int src_end, boolean fwd) {
if (src_bgn < 0 || src.length == 0) return Bry_find_.Not_found;
int dif, lkp_len = lkp.length, lkp_bgn, lkp_end, src_end_chk;
if (fwd) {
if (src_bgn > src_end) return Bry_find_.Not_found;
dif = 1; lkp_bgn = 0; lkp_end = lkp_len; src_end_chk = src_end - OffsetCompare;
}
else {
if (src_bgn < src_end) return Bry_find_.Not_found;
dif = -1; lkp_bgn = lkp_len - 1; lkp_end = -1; src_end_chk = src.length - OffsetCompare; // src_end_chk needed when going bwd, b/c lkp_len may be > 1
}
while (src_bgn != src_end) { // while src is not done;
int lkp_cur = lkp_bgn;
while (lkp_cur != lkp_end) { // while lkp is not done
int pos = src_bgn + lkp_cur;
if ( pos > src_end_chk // outside bounds; occurs when lkp_len > 1
|| src[pos] != lkp[lkp_cur]) // srcByte doesn't match lkpByte
break;
else
lkp_cur += dif;
}
if (lkp_cur == lkp_end) return src_bgn; // lkp matches src; exit
src_bgn += dif;
}
return Bry_find_.Not_found;
}
public static int Find_bwd(byte[] src, byte[] lkp, int cur) {return Find_bwd(src, lkp, cur , 0);}
public static int Find_bwd(byte[] src, byte[] lkp, int cur, int end) {
if (cur < 1) return Bry_find_.Not_found;
--cur; // always subtract 1 from cur; allows passing in src_len or cur_pos without forcing caller to subtract - 1; DATE:2014-02-11
--end;
int src_len = src.length;
int lkp_len = lkp.length;
for (int i = cur; i > end; i--) {
if (i + lkp_len > src_len) continue; // lkp too small for pos; EX: src=abcde; lkp=bcd; pos=4
boolean match = true;
for (int j = 0; j < lkp_len; j++) {
if (lkp[j] != src[i + j]) {
match = false;
break;
}
}
if (match) return i;
}
return Bry_find_.Not_found;
}
public static int Find_bwd_last_ws(byte[] src, int cur) {
if (cur < 1) return Bry_find_.Not_found;
--cur;
int rv = Bry_find_.Not_found;
for (int i = cur; i > -1; i--) {
byte b = src[i];
switch (b) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
rv = i;
break;
default:
i = -1;
break;
}
}
return rv;
}
public static int Find_bwd_ws(byte[] src, int cur, int end) {
for (int i = cur; i > -1; --i) {
byte b = src[i];
switch (b) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
return i;
}
}
return Bry_find_.Not_found;
}
public static int Find_fwd_last_ws(byte[] src, int cur) {
int end = src.length;
if (cur >= end) return Bry_find_.Not_found;
int rv = Bry_find_.Not_found;
for (int i = cur; i < end; i++) {
byte b = src[i];
switch (b) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
rv = i;
break;
default:
i = -1;
break;
}
}
return rv;
}
public static int Find_bwd_non_ws_or_not_found(byte[] src, int cur, int end) { // get pos of 1st char that is not ws;
if (cur >= src.length) return Bry_find_.Not_found;
for (int i = cur; i >= end; i--) {
byte b = src[i];
switch (b) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
break;
default:
return i;
}
}
return Bry_find_.Not_found;
}
public static int Find_bwd__while_space_or_tab(byte[] src, int cur, int end) { // get pos of 1st char that is not \t or \s
if (cur < 0 || cur > src.length) return Bry_find_.Not_found;
for (int i = cur - 1; i >= end; i--) {
byte b = src[i];
switch (b) {
case AsciiByte.Space: case AsciiByte.Tab:
break;
default:
return i + 1;
}
}
return Bry_find_.Not_found;
}
public static int Find_bwd_non_ws_or_end(byte[] src, int cur, int end) {
if (cur >= src.length) return Bry_find_.Not_found;
for (int i = cur; i >= end; i--) {
byte b = src[i];
switch (b) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
break;
default:
return i;
}
}
return end;
}
public static int Find_bwd__skip_ws(byte[] src, int end, int bgn) {
int src_len = src.length;
if (end == src_len) return end;
if (end > src_len || end < 0) return Bry_find_.Not_found;
int pos = end - 1; // start from end - 1; handles situations where len is passed in
for (int i = pos; i >= bgn; --i) {
switch (src[i]) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
break;
default:
return i + 1;
}
}
return bgn;
}
public static int Find_bwd__skip(byte[] src, int end, int bgn, byte skip) {
int src_len = src.length; // if (end == src_len) return end;
if (end > src_len || end < 0) return Bry_find_.Not_found;
int pos = end - 1; // start from end - 1; handles situations where len is passed in
for (int i = pos; i >= bgn; --i) {
if (src[i] != skip)
return i + 1;
}
return bgn;
}
public static int Find_bwd__skip(byte[] src, int end, int bgn, byte[] skip) {
int src_len = src.length;
if (end > src_len || end < 0) return Bry_find_.Not_found;
int skip_len = skip.length;
int pos = end - skip_len; // start from end - 1; handles situations where len is passed in
for (int i = pos; i >= bgn; --i) {
if (!Bry_.Eq(src, i, i + skip_len, skip))
return i + skip_len;
}
return bgn;
}
public static int Find_bwd_while(byte[] src, int cur, int end, byte while_byte) {
--cur;
while (true) {
if ( cur < end
|| src[cur] != while_byte) return cur;
--cur;
}
}
public static int Find_bwd_while_in(byte[] src, int cur, int end, boolean[] while_ary) {
while (true) {
if (cur <= end || !while_ary[src[cur]]) return cur;
cur--;
}
}
public static int Find_bwd_while_v2(byte[] src, int cur, int end, byte while_byte) {
--cur;
while (true) {
if ( cur < end
|| src[cur] != while_byte) return cur + 1;
--cur;
}
}
public static int Find_fwd_while(byte[] src, int cur, int end, byte while_byte) {
while (true) {
if ( cur == end
|| src[cur] != while_byte) return cur;
cur++;
}
}
public static int Find_fwd_while(byte[] src, int cur, int end, byte[] while_bry) {
int while_len = while_bry.length;
while (true) {
if (cur == end) return cur;
for (int i = 0; i < while_len; i++) {
if (while_bry[i] != src[i + cur]) return cur;
}
cur += while_len;
}
}
public static int Find_fwd_while_in(byte[] src, int cur, int end, boolean[] while_ary) {
while (cur < end) {
if (cur == end || !while_ary[src[cur]]) return cur;
cur++;
}
return end;
}
public static boolean[] Find_fwd_while_in_gen(byte... ary) {
boolean[] rv = new boolean[256];
int len = ary.length;
for (int i = 0; i < len; i++) {
rv[ary[i]] = true;
}
return rv;
}
public static int Find_fwd_until(byte[] src, int cur, int end, byte until_byte) {
while (true) {
if ( cur == end
|| src[cur] == until_byte) return cur;
cur++;
}
}
public static int Find_fwd_until_space_or_tab(byte[] src, int cur, int end) {
while (true) {
if (cur == end) return Bry_find_.Not_found;
switch (src[cur]) {
case AsciiByte.Space: case AsciiByte.Tab:
return cur;
default:
++cur;
break;
}
}
}
public static int Find_fwd_until_ws(byte[] src, int cur, int end) {
while (true) {
if (cur == end) return Bry_find_.Not_found;
switch (src[cur]) {
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
return cur;
default:
++cur;
break;
}
}
}
public static int Find_fwd_while_space_or_tab(byte[] src, int cur, int end) {
while (true) {
if (cur == end) return cur;
switch (src[cur]) {
case AsciiByte.Space: case AsciiByte.Tab: ++cur; break;
default: return cur;
}
}
}
public static int Trim_fwd_space_tab(byte[] src, int cur, int end) {
while (true) {
if (cur == end) return cur;
switch (src[cur]) {
case AsciiByte.Space: case AsciiByte.Tab: ++cur; break;
default: return cur;
}
}
}
public static int Trim_bwd_space_tab(byte[] src, int cur, int bgn) {
while (true) {
int prv_cur = cur - 1; // check byte before cur; EX: "a b " will have len of 4, and pass cur=4;
if (prv_cur < bgn) return cur; // checking byte before prv; exit;
switch (src[prv_cur]) {
case AsciiByte.Space: case AsciiByte.Tab: --cur; break;
default: return cur;
}
}
}
public static int Find_fwd_while_ws(byte[] src, int cur, int end) {
while (true) {
if (cur == end) return cur;
try {
switch (src[cur]) {
case AsciiByte.Nl: case AsciiByte.Cr:
case AsciiByte.Space: case AsciiByte.Tab: ++cur; break;
default: return cur;
}
} catch (Exception e) {throw Err_.new_exc(e, "core", "idx is invalid", "cur", cur, "src", src);}
}
}
public static int Find_fwd_while_letter(byte[] src, int cur, int end) {
while (cur < end) {
switch (src[cur]) {
case AsciiByte.Ltr_A: case AsciiByte.Ltr_B: case AsciiByte.Ltr_C: case AsciiByte.Ltr_D: case AsciiByte.Ltr_E:
case AsciiByte.Ltr_F: case AsciiByte.Ltr_G: case AsciiByte.Ltr_H: case AsciiByte.Ltr_I: case AsciiByte.Ltr_J:
case AsciiByte.Ltr_K: case AsciiByte.Ltr_L: case AsciiByte.Ltr_M: case AsciiByte.Ltr_N: case AsciiByte.Ltr_O:
case AsciiByte.Ltr_P: case AsciiByte.Ltr_Q: case AsciiByte.Ltr_R: case AsciiByte.Ltr_S: case AsciiByte.Ltr_T:
case AsciiByte.Ltr_U: case AsciiByte.Ltr_V: case AsciiByte.Ltr_W: case AsciiByte.Ltr_X: case AsciiByte.Ltr_Y: case AsciiByte.Ltr_Z:
case AsciiByte.Ltr_a: case AsciiByte.Ltr_b: case AsciiByte.Ltr_c: case AsciiByte.Ltr_d: case AsciiByte.Ltr_e:
case AsciiByte.Ltr_f: case AsciiByte.Ltr_g: case AsciiByte.Ltr_h: case AsciiByte.Ltr_i: case AsciiByte.Ltr_j:
case AsciiByte.Ltr_k: case AsciiByte.Ltr_l: case AsciiByte.Ltr_m: case AsciiByte.Ltr_n: case AsciiByte.Ltr_o:
case AsciiByte.Ltr_p: case AsciiByte.Ltr_q: case AsciiByte.Ltr_r: case AsciiByte.Ltr_s: case AsciiByte.Ltr_t:
case AsciiByte.Ltr_u: case AsciiByte.Ltr_v: case AsciiByte.Ltr_w: case AsciiByte.Ltr_x: case AsciiByte.Ltr_y: case AsciiByte.Ltr_z:
break;
default:
return cur;
}
++cur;
}
return cur;
}
public static int Find_fwd_while_num(byte[] src) {return Find_fwd_while_num(src, 0, src.length);}
public static int Find_fwd_while_num(byte[] src, int cur, int end) {
while (cur < end) {
if (!AsciiByte.IsNum(src[cur]))
return cur;
++cur;
}
return cur;
}
public static int Find_fwd_while_not_ws(byte[] src, int cur, int end) {
while (true) {
if (cur == end) return cur;
switch (src[cur]) {
case AsciiByte.Space:
case AsciiByte.Nl:
case AsciiByte.Tab:
case AsciiByte.Cr:
++cur;
break;
default:
return cur;
}
}
}
public static int Find_bwd_while_alphanum(byte[] src, int cur) {return Find_bwd_while_alphanum(src, cur, -1);}
public static int Find_bwd_while_alphanum(byte[] src, int cur, int end) {
--cur;
while (cur > end) {
switch (src[cur]) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
case AsciiByte.Ltr_A: case AsciiByte.Ltr_B: case AsciiByte.Ltr_C: case AsciiByte.Ltr_D: case AsciiByte.Ltr_E:
case AsciiByte.Ltr_F: case AsciiByte.Ltr_G: case AsciiByte.Ltr_H: case AsciiByte.Ltr_I: case AsciiByte.Ltr_J:
case AsciiByte.Ltr_K: case AsciiByte.Ltr_L: case AsciiByte.Ltr_M: case AsciiByte.Ltr_N: case AsciiByte.Ltr_O:
case AsciiByte.Ltr_P: case AsciiByte.Ltr_Q: case AsciiByte.Ltr_R: case AsciiByte.Ltr_S: case AsciiByte.Ltr_T:
case AsciiByte.Ltr_U: case AsciiByte.Ltr_V: case AsciiByte.Ltr_W: case AsciiByte.Ltr_X: case AsciiByte.Ltr_Y: case AsciiByte.Ltr_Z:
case AsciiByte.Ltr_a: case AsciiByte.Ltr_b: case AsciiByte.Ltr_c: case AsciiByte.Ltr_d: case AsciiByte.Ltr_e:
case AsciiByte.Ltr_f: case AsciiByte.Ltr_g: case AsciiByte.Ltr_h: case AsciiByte.Ltr_i: case AsciiByte.Ltr_j:
case AsciiByte.Ltr_k: case AsciiByte.Ltr_l: case AsciiByte.Ltr_m: case AsciiByte.Ltr_n: case AsciiByte.Ltr_o:
case AsciiByte.Ltr_p: case AsciiByte.Ltr_q: case AsciiByte.Ltr_r: case AsciiByte.Ltr_s: case AsciiByte.Ltr_t:
case AsciiByte.Ltr_u: case AsciiByte.Ltr_v: case AsciiByte.Ltr_w: case AsciiByte.Ltr_x: case AsciiByte.Ltr_y: case AsciiByte.Ltr_z:
--cur;
break;
default:
return cur;
}
}
return 0; // always return a valid index
}
}

@ -1,91 +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;
import gplx.objects.strings.AsciiByte;
import org.junit.*; import gplx.core.tests.*;
public class Bry_find__tst {
private Bry_find__fxt fxt = new Bry_find__fxt();
@Test public void Find_fwd() {
fxt.Test_Find_fwd("abcba", "b", 0, 1);
fxt.Test_Find_fwd("abcba", "z", 0, -1);
fxt.Test_Find_fwd("abcba", "b", 1, 1);
fxt.Test_Find_fwd("abcba", "b", 2, 3);
fxt.Test_Find_fwd("abcba", "b", 4, -1);
fxt.Test_Find_fwd("abcba", "zb", 4, -1);
fxt.Test_Find_fwd("abcba", "a", 6, -1);
}
@Test public void Find_bwd() {
fxt.Test_Find_bwd("abcba", "b", 4, 3);
fxt.Test_Find_bwd("abcba", "z", 4, -1);
fxt.Test_Find_bwd("abcba", "b", 3, 1);
fxt.Test_Find_bwd("abcba", "b", 2, 1);
fxt.Test_Find_bwd("abcba", "b", 0, -1);
fxt.Test_Find_bwd("abcba", "zb", 4, -1);
fxt.Test_Find_fwd("abcba", "a", -1, -1);
fxt.Test_Find_bwd("abcba", "ab", 4, 0);
}
@Test public void Find_bwd_last_ws() {
fxt.Test_Find_bwd_1st_ws_tst("a b" , 2, 1); // basic
fxt.Test_Find_bwd_1st_ws_tst("a b" , 3, 1); // multiple
fxt.Test_Find_bwd_1st_ws_tst("ab" , 1, Bry_find_.Not_found); // none
}
@Test public void Trim_fwd_space_tab() {
fxt.Test_Trim_fwd_space_tab(" a b" , 1);
fxt.Test_Trim_fwd_space_tab("\ta b" , 1);
fxt.Test_Trim_fwd_space_tab(" \ta b" , 2);
fxt.Test_Trim_fwd_space_tab("a bc" , 0);
fxt.Test_Trim_fwd_space_tab("" , 0);
fxt.Test_Trim_fwd_space_tab(" \t" , 2);
}
@Test public void Trim_bwd_space_tab() {
fxt.Test_Trim_bwd_space_tab("a b " , 3);
fxt.Test_Trim_bwd_space_tab("a b\t" , 3);
fxt.Test_Trim_bwd_space_tab("a b\t " , 3);
fxt.Test_Trim_bwd_space_tab("a bc" , 4);
fxt.Test_Trim_bwd_space_tab("" , 0);
fxt.Test_Trim_bwd_space_tab(" \t" , 0);
}
@Test public void Find_fwd_while_in() {
boolean[] while_ary = fxt.Init__find_fwd_while_in(AsciiByte.Space, AsciiByte.Tab, AsciiByte.Nl);
fxt.Test__find_fwd_while_in(" \t\na", while_ary, 3);
}
}
class Bry_find__fxt {
public void Test_Find_fwd(String src, String lkp, int bgn, int expd) {Tfds.Eq(expd, Bry_find_.Find_fwd(Bry_.new_u8(src), Bry_.new_u8(lkp), bgn));}
public void Test_Find_bwd(String src, String lkp, int bgn, int expd) {Tfds.Eq(expd, Bry_find_.Find_bwd(Bry_.new_u8(src), Bry_.new_u8(lkp), bgn));}
public void Test_Find_bwd_1st_ws_tst(String src, int pos, int expd) {Tfds.Eq(expd, Bry_find_.Find_bwd_last_ws(Bry_.new_a7(src), pos));}
public void Test_Trim_bwd_space_tab(String raw_str, int expd) {
byte[] raw_bry = Bry_.new_u8(raw_str);
int actl = Bry_find_.Trim_bwd_space_tab(raw_bry, raw_bry.length, 0);
Tfds.Eq(expd, actl, raw_str);
}
public void Test_Trim_fwd_space_tab(String raw_str, int expd) {
byte[] raw_bry = Bry_.new_u8(raw_str);
int actl = Bry_find_.Trim_fwd_space_tab(raw_bry, 0, raw_bry.length);
Tfds.Eq(expd, actl, raw_str);
}
public boolean[] Init__find_fwd_while_in(byte... ary) {
boolean[] rv = new boolean[256];
int len = ary.length;
for (int i = 0; i < len; i++)
rv[ary[i]] = true;
return rv;
}
public void Test__find_fwd_while_in(String src, boolean[] ary, int expd) {
byte[] src_bry = Bry_.new_u8(src);
Gftest.Eq__int(expd, Bry_find_.Find_fwd_while_in(src_bry, 0, src_bry.length, ary));
}
}

@ -1,88 +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;
import gplx.core.brys.fmts.*;
import gplx.objects.strings.AsciiByte;
public class Bry_fmt {
private final Object thread_lock = new Object();
private byte[] src;
private Bry_fmt_itm[] itms; private int itms_len;
private Bfr_fmt_arg[] args = Bfr_fmt_arg.Ary_empty;
private byte[][] keys = Bry_.Ary_empty;
private Object[] vals = null;
private boolean dirty;
public Bry_fmt(byte[] src, byte[][] keys, Bfr_fmt_arg[] args) {
dirty = true;
this.src = src; this.keys = keys; this.args = args;
}
public byte[] Fmt() {return src;}
public Bry_fmt Fmt_(String v) {return Fmt_(Bry_.new_u8(v));}
public Bry_fmt Fmt_(byte[] v) {dirty = true; src = v; return this;}
public Bry_fmt Args_(Bfr_fmt_arg... v) {dirty = true; args = v; return this;}
public Bry_fmt Keys_(String... v) {return Keys_(Bry_.Ary(v));}
public Bry_fmt Keys_(byte[]... v) {dirty = true; keys = v; return this;}
public Bry_fmt Vals_(Object... v) {vals = v; return this;}
public String Bld_many_to_str_auto_bfr(Object... vals_ary) {
Bry_bfr bfr = Bry_bfr_.Get();
try {return Bld_many_to_str(bfr, vals_ary);}
finally {bfr.Mkr_rls();}
}
public String Bld_many_to_str(Bry_bfr bfr, Object... vals_ary) {
Bld_many(bfr, vals_ary);
return bfr.To_str_and_clear();
}
public byte[] Bld_many_to_bry(Bry_bfr bfr, Object... vals_ary) {
Bld_many(bfr, vals_ary);
return bfr.To_bry_and_clear();
}
public void Bld_many(Bry_bfr bfr, Object... vals_ary) {
if (dirty) Compile();
int vals_len = vals_ary.length;
for (int i = 0; i < itms_len; ++i) {
Bry_fmt_itm itm = itms[i];
switch (itm.Tid) {
case Bry_fmt_itm.Tid__txt: bfr.Add_mid(src, itm.Src_bgn, itm.Src_end); break;
case Bry_fmt_itm.Tid__arg: itm.Arg.Bfr_arg__add(bfr);break;
case Bry_fmt_itm.Tid__key:
int idx = itm.Key_idx;
if (idx > -1 && idx < vals_len)
bfr.Add_obj(vals_ary[idx]);
else
bfr.Add_mid(src, itm.Src_bgn, itm.Src_end);
break;
default: throw Err_.new_unhandled(itm.Tid);
}
}
}
public String To_str() {return Bld_many_to_str_auto_bfr(vals);}
private void Compile() {
synchronized (thread_lock) {
dirty = false;
this.itms = Bry_fmt_parser_.Parse(AsciiByte.Tilde, AsciiByte.CurlyBgn, AsciiByte.CurlyEnd, args, keys, src);
this.itms_len = itms.length;
}
}
public static Bry_fmt New(String fmt, String... keys) {return new Bry_fmt(Bry_.new_u8(fmt), Bry_.Ary(keys), Bfr_fmt_arg.Ary_empty);}
public static Bry_fmt New(byte[] fmt, String... keys) {return new Bry_fmt(fmt , Bry_.Ary(keys), Bfr_fmt_arg.Ary_empty);}
public static String Make_str(String fmt_str, Object... vals) {return Auto(fmt_str).Vals_(vals).To_str();}
public static Bry_fmt Auto_nl_apos(String... lines) {return Auto(Bry_.New_u8_nl_apos(lines));}
public static Bry_fmt Auto_nl_skip_last(String... lines) {return Auto(Bry_.new_u8(String_.Concat_lines_nl_skip_last(lines)));}
public static Bry_fmt Auto(String fmt_str) {return Auto(Bry_.new_u8(fmt_str));}
public static Bry_fmt Auto(byte[] fmt_bry) {
byte[][] keys_bry = Bry_fmt_parser_.Parse_keys(fmt_bry);
return new Bry_fmt(fmt_bry, keys_bry, Bfr_fmt_arg.Ary_empty);
}
}

@ -1,92 +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;
import gplx.core.tests.Gftest;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.strings.AsciiByte;
import org.junit.Test;
public class Bry_split__tst {
private final Bry_split__fxt fxt = new Bry_split__fxt();
@Test public void Split() {
fxt.Test_split("a" , AsciiByte.Pipe, BoolUtl.N, "a"); // no trim
fxt.Test_split("a|" , AsciiByte.Pipe, BoolUtl.N, "a");
fxt.Test_split("|a" , AsciiByte.Pipe, BoolUtl.N, "", "a");
fxt.Test_split("|" , AsciiByte.Pipe, BoolUtl.N, "");
fxt.Test_split("" , AsciiByte.Pipe, BoolUtl.N);
fxt.Test_split("a|b|c" , AsciiByte.Pipe, BoolUtl.N, "a", "b", "c");
fxt.Test_split(" a " , AsciiByte.Pipe, BoolUtl.Y, "a"); // trim
fxt.Test_split(" a |" , AsciiByte.Pipe, BoolUtl.Y, "a");
fxt.Test_split("| a " , AsciiByte.Pipe, BoolUtl.Y, "", "a");
fxt.Test_split(" | " , AsciiByte.Pipe, BoolUtl.Y, "");
fxt.Test_split(" " , AsciiByte.Pipe, BoolUtl.Y);
fxt.Test_split(" a | b | c " , AsciiByte.Pipe, BoolUtl.Y, "a", "b", "c");
fxt.Test_split(" a b | c d " , AsciiByte.Pipe, BoolUtl.Y, "a b", "c d");
fxt.Test_split(" a \n b " , AsciiByte.Nl , BoolUtl.N, " a ", " b "); // ws as dlm
fxt.Test_split(" a \n b " , AsciiByte.Nl , BoolUtl.Y, "a", "b"); // ws as dlm; trim
fxt.Test_split("a|extend|b" , AsciiByte.Pipe, BoolUtl.Y, "a", "extend|b"); // extend
fxt.Test_split("extend|a" , AsciiByte.Pipe, BoolUtl.Y, "extend|a"); // extend
fxt.Test_split("a|cancel|b" , AsciiByte.Pipe, BoolUtl.Y, "a"); // cancel
}
@Test public void Split__bry() {
fxt.Test_split("a|b|c|d" , 2, 6, "|", "b", "c");
fxt.Test_split("a|b|c|d" , 2, 4, "|", "b");
}
@Test public void Empty() {
fxt.Test_split("a\n\nb" , AsciiByte.Nl, BoolUtl.N, "a", "", "b");
}
@Test public void Split_w_max() {
fxt.Test__split_w_max("a|b|c|d" , AsciiByte.Pipe, 2, "a", "b"); // max is less
fxt.Test__split_w_max("a" , AsciiByte.Pipe, 2, "a", null); // max is more
fxt.Test__split_w_max("|" , AsciiByte.Pipe, 2, "", ""); // empty itms
}
@Test public void Split_ws() {
fxt.Test__split_ws("a b", "a", "b");
fxt.Test__split_ws(" a ", "a");
fxt.Test__split_ws(" abc def ", "abc", "def");
}
}
class Bry_split__fxt {
private final Bry_split_wkr__example wkr = new Bry_split_wkr__example();
public void Test_split(String raw_str, byte dlm, boolean trim, String... expd) {
byte[] src = Bry_.new_a7(raw_str);
Bry_split_.Split(src, 0, src.length, dlm, trim, wkr);
byte[][] actl_ary = wkr.To_ary();
Tfds.Eq_ary_str(expd, String_.Ary(actl_ary));
}
public void Test_split(String src, int src_bgn, int src_end, String dlm, String... expd) {
Tfds.Eq_ary_str(Bry_.Ary(expd), Bry_split_.Split(Bry_.new_u8(src), src_bgn, src_end, Bry_.new_u8(dlm)));
}
public void Test__split_w_max(String src, byte dlm, int max, String... expd) {
Gftest.Eq__ary(expd, String_.Ary(Bry_split_.Split_w_max(Bry_.new_u8(src), dlm, max)));
}
public void Test__split_ws(String raw, String... expd) {
byte[][] actl = Bry_split_.Split_ws(Bry_.new_u8(raw));
Gftest.Eq__ary(Bry_.Ary(expd), actl, raw);
}
}
class Bry_split_wkr__example implements gplx.core.brys.Bry_split_wkr {
private final List_adp list = List_adp_.New();
public int Split(byte[] src, int itm_bgn, int itm_end) {
byte[] bry = itm_end == itm_bgn ? Bry_.Empty : Bry_.Mid(src, itm_bgn, itm_end);
if (Bry_.Eq(bry, Bry_.new_a7("extend"))) return Bry_split_.Rv__extend;
else if (Bry_.Eq(bry, Bry_.new_a7("cancel"))) return Bry_split_.Rv__cancel;
list.Add(bry);
return Bry_split_.Rv__ok;
}
public byte[][] To_ary() {
return (byte[][])list.ToAryAndClear(byte[].class);
}
}

@ -1,69 +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;
import gplx.objects.lists.CompareAbleUtl;
public class Byte_ {//RF:2017-10-08
public static final String Cls_val_name = "byte";
public static final Class<?> Cls_ref_type = Byte.class;
public static final byte
Zero = 0
, Min_value = Byte.MIN_VALUE
, Max_value_127 = 127
, Val_128 = -128
, Val_255 = -1
;
public static byte By_int(int v) {return v > 127 ? (byte)(v - 256) : (byte)v;} // PERF?: (byte)(v & 0xff)
public static int To_int(byte v) {return v < 0 ? (int)v + 256 : v;}
public static String To_str(byte v) {return new Byte(v).toString();}
public static byte[] To_bry(byte v) {return new byte[] {v};}
public static byte Cast(Object o) {try {return (Byte)o;} catch (Exception e) {throw Err_.new_type_mismatch_w_exc(e, byte.class, o);}}
public static byte Parse(String raw) {return Byte.parseByte(raw);}
public static byte Parse_or(String raw, byte or) {
if (raw == null) return or;
try {return Parse(raw);}
catch (Exception e) {Err_.Noop(e); return or;}
}
public static boolean Match_any(byte v, byte... ary) {
for (byte itm : ary)
if (v == itm) return true;
return false;
}
public static boolean Match_all(byte v, byte... ary) {
for (byte itm : ary)
if (v != itm) return false;
return true;
}
public static int Compare(byte lhs, byte rhs) {
if (lhs == rhs) return CompareAbleUtl.Same;
else if (lhs < rhs) return CompareAbleUtl.Less;
else return CompareAbleUtl.More;
}
public static byte[] Ary(byte... ary) {return ary;}
public static byte[] Ary_by_ints(int... ary) {
int ary_len = ary.length;
byte[] rv = new byte[ary_len];
for (int i = 0; i < ary_len; i++) {
rv[i] = By_int(ary[i]);
}
return rv;
}
}

@ -1,168 +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;
import gplx.objects.lists.CompareAble;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
public class DateAdp implements CompareAble, Gfo_invk {
public int compareTo(Object obj) {DateAdp comp = (DateAdp)obj; return under.compareTo(comp.under);}
@Override public String toString() {return XtoStr_gplx_long();}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_XtoStr_fmt)) return XtoStr_fmt("yyyy-MM-dd HH:mm:ss");
else if (ctx.Match(k, Invk_AddDays)) {
int days = m.ReadInt("days");
if (ctx.Deny()) return this;
return this.Add_day(days);
}
else return Gfo_invk_.Rv_unhandled;
} public static final String Invk_XtoStr_fmt = "XtoStr_fmt", Invk_AddDays = "Add_day";
public int Segment(int segmentIdx) {
switch (segmentIdx) {
case DateAdp_.SegIdx_year: return this.Year();
case DateAdp_.SegIdx_month: return this.Month();
case DateAdp_.SegIdx_day: return this.Day();
case DateAdp_.SegIdx_hour: return this.Hour();
case DateAdp_.SegIdx_minute: return this.Minute();
case DateAdp_.SegIdx_second: return this.Second();
case DateAdp_.SegIdx_frac: return this.Frac();
case DateAdp_.SegIdx_dayOfWeek: return this.DayOfWeek();
case DateAdp_.SegIdx_weekOfYear: return this.WeekOfYear();
case DateAdp_.SegIdx_dayOfYear: return this.DayOfYear();
default: throw Err_.new_unhandled(segmentIdx);
}
}
public int[] XtoSegAry() {
int[] rv = new int[7];
rv[DateAdp_.SegIdx_year] = this.Year();
rv[DateAdp_.SegIdx_month] = this.Month();
rv[DateAdp_.SegIdx_day] = this.Day();
rv[DateAdp_.SegIdx_hour] = this.Hour();
rv[DateAdp_.SegIdx_minute] = this.Minute();
rv[DateAdp_.SegIdx_second] = this.Second();
rv[DateAdp_.SegIdx_frac] = this.Frac();
return rv;
}
public String XtoStr_gplx() {return XtoStr_fmt("yyyyMMdd_HHmmss.fff");}
public String XtoStr_gplx_long() {return XtoStr_fmt("yyyy-MM-dd HH:mm:ss.fff");}
public String XtoStr_fmt_HHmmss() {return XtoStr_fmt("HH:mm:ss");}
public String XtoStr_fmt_HHmm() {return XtoStr_fmt("HH:mm");}
public String XtoStr_fmt_yyyy_MM_dd() {return XtoStr_fmt("yyyy-MM-dd");}
public String XtoStr_fmt_yyyyMMdd_HHmmss() {return XtoStr_fmt("yyyyMMdd_HHmmss");}
public String XtoStr_fmt_yyyyMMdd_HHmmss_fff() {return XtoStr_fmt("yyyyMMdd_HHmmss.fff");}
public String XtoStr_fmt_yyyyMMdd_HHmm() {return XtoStr_fmt("yyyyMMdd_HHmm");}
public String XtoStr_fmt_yyyy_MM_dd_HH_mm() {return XtoStr_fmt("yyyy-MM-dd HH:mm");}
public String XtoStr_fmt_yyyy_MM_dd_HH_mm_ss() {return XtoStr_fmt("yyyy-MM-dd HH:mm:ss");}
public String XtoStr_fmt_iso_8561() {return XtoStr_fmt("yyyy-MM-dd HH:mm:ss");}
public String XtoStr_fmt_iso_8561_w_tz() {return XtoStr_fmt("yyyy-MM-dd'T'HH:mm:ss'Z'");}
public static int Timezone_offset_test = Int_.Min_value;
public Calendar UnderDateTime() {return under;} Calendar under;
public int Year() {return under.get(Calendar.YEAR);}
public int Month() {return under.get(Calendar.MONTH) + Month_base0adj;}
public int Day() {return under.get(Calendar.DAY_OF_MONTH);}
public int Hour() {return under.get(Calendar.HOUR_OF_DAY);}
public int Minute() {return under.get(Calendar.MINUTE);}
public int Second() {return under.get(Calendar.SECOND);}
public int DayOfWeek() {return under.get(Calendar.DAY_OF_WEEK) - 1;} // -1 : Base0; NOTE: dotnet/php is also Sunday=0
public int DayOfYear() {return under.get(Calendar.DAY_OF_YEAR);}
public int Timezone_offset() {
return Timezone_offset_test == Int_.Min_value // Timezone_offset_test not over-ridden
? 0
// ? under.getTimeZone().getOffset(this.Timestamp_unix()) / 1000 // divide by 1000 to convert from ms to seconds
: Timezone_offset_test
;
}
public String Timezone_id() {
return "UTC"; // under.getTimeZone().getID(); // NOTE: timezone is always UTC, unless over-ridden by tests
}
public DateAdp XtoUtc() {
java.util.Date date = under.getTime();
java.util.TimeZone tz = under.getTimeZone();
long msFromEpochGmt = date.getTime();
int offsetFromUTC = tz.getOffset(msFromEpochGmt);
Calendar gmtCal = Calendar.getInstance();
gmtCal.setTimeInMillis(msFromEpochGmt + -offsetFromUTC);
return new DateAdp(gmtCal);
}
public DateAdp XtoLocal() {
java.util.Date date = under.getTime();
java.util.TimeZone tz = under.getTimeZone();
long msFromEpochGmt = date.getTime();
int offsetFromUTC = tz.getOffset(msFromEpochGmt);
Calendar gmtCal = Calendar.getInstance();
gmtCal.setTimeInMillis(msFromEpochGmt + offsetFromUTC);
return new DateAdp(gmtCal);
}
public long Timestamp_unix() {
long offsetFromUTC = (under.getTimeZone().getOffset(0));
boolean dst = TimeZone.getDefault().inDaylightTime(under.getTime());
long dst_adj = dst ? 3600000 : 0;
return (under.getTimeInMillis() + offsetFromUTC + dst_adj) / 1000;
}
public int WeekOfYear() {return under.get(Calendar.WEEK_OF_YEAR);}
public int Frac() {return under.get(Calendar.MILLISECOND);}
public DateAdp Add_frac(int val) {return CloneAndAdd(Calendar.MILLISECOND, val);}
public DateAdp Add_second(int val) {return CloneAndAdd(Calendar.SECOND, val);}
public DateAdp Add_minute(int val) {return CloneAndAdd(Calendar.MINUTE, val);}
public DateAdp Add_hour(int val) {return CloneAndAdd(Calendar.HOUR, val);}
public DateAdp Add_day(int val) {return CloneAndAdd(Calendar.DAY_OF_MONTH, val);}
public DateAdp Add_month(int val) {return CloneAndAdd(Calendar.MONTH, val);}
public DateAdp Add_year(int val) {return CloneAndAdd(Calendar.YEAR, val);}
DateAdp CloneAndAdd(int field, int val) {
Calendar clone = (Calendar)under.clone();
clone.add(field, val);
return new DateAdp(clone);
}
public String XtoStr_fmt(String fmt) {
fmt = fmt.replace("f", "S");
SimpleDateFormat sdf = new SimpleDateFormat(fmt);
return sdf.format(under.getTime());
}
public String XtoStr_tz() {
SimpleDateFormat sdf = new SimpleDateFormat("Z");
String time_zone = sdf.format(under.getTime());
return String_.Mid(time_zone, 0, 3) + ":" + String_.Mid(time_zone, 3, String_.Len(time_zone));
}
public boolean Eq(DateAdp v) {DateAdp comp = v; return Object_.Eq(under.getTimeInMillis(), comp.under.getTimeInMillis());}
public int Diff_days(DateAdp prev) {
long diff = this.under.getTimeInMillis() - prev.under.getTimeInMillis();
return (int)(diff / (1000 * 60 * 60 * 24));
}
public Time_span Diff(DateAdp earlier) {
long diff = this.under.getTimeInMillis() - earlier.under.getTimeInMillis();
return Time_span_.fracs_(diff);
}
protected DateAdp(Calendar under) {this.under = under;}
protected DateAdp(int year, int month, int day, int hour, int minute, int second, int frac) {
this.under = new GregorianCalendar(year, month - Month_base0adj, day, hour, minute, second);
under.set(Calendar.MILLISECOND, frac);
}
protected DateAdp(int year, int month, int day, int hour, int minute, int second, int frac, TimeZone timeZone) {
this.under = new GregorianCalendar(timeZone);
under.set(year, month - Month_base0adj, day, hour, minute, second);
under.set(Calendar.MILLISECOND, frac);
}
public void SetTzOffset(int offset) {
java.util.Date date = under.getTime();
long msFromEpochGmt = date.getTime();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(msFromEpochGmt - offset*1000);
under = cal;
}
public static final int Month_base0adj = 1;
}

@ -1,148 +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;
import gplx.core.times.DateAdp_parser;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
public class DateAdp_ implements Gfo_invk {
public static final String Cls_ref_name = "Date";
public static final Class<?> Cls_ref_type = DateAdp.class;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_Now)) return Datetime_now.Get();
else return Gfo_invk_.Rv_unhandled;
} public static final String Invk_Now = "Now";
public static final DateAdp MinValue = new DateAdp( 1, 1, 1, 0, 0, 0, 0);
public static final DateAdp MaxValue = new DateAdp(9999, 12, 31, 23, 59, 59, 999);
// public static DateAdp Now() {return Tfds.Now_enabled() ? Tfds.Now() : new DateAdp(new GregorianCalendar());}
public static DateAdp new_(int year, int month, int day, int hour, int minute, int second, int frac) {return new DateAdp(year, month, day, hour, minute, second, frac);}
public static DateAdp seg_(int[] ary) {
int ary_len = ary.length;
int y = ary_len > 0 ? ary[0] : 1;
int M = ary_len > 1 ? ary[1] : 1;
int d = ary_len > 2 ? ary[2] : 1;
int h = ary_len > 3 ? ary[3] : 0;
int m = ary_len > 4 ? ary[4] : 0;
int s = ary_len > 5 ? ary[5] : 0;
int f = ary_len > 6 ? ary[6] : 0;
return new DateAdp(y, M, d, h, m, s, f);
}
public static DateAdp cast(Object arg) {try {return (DateAdp)arg;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, DateAdp.class, arg);}}
public static DateAdp parse_iso8561_or(String raw, DateAdp or) {
try {return parse_iso8561(raw);}
catch (Exception e) {Err_.Noop(e); return or;}
}
public static DateAdp parse_iso8561(String raw) { // NOTE: for now, same as parse_gplx
int[] ary = date_parser.Parse_iso8651_like(raw);
if (ary[1] < 1 || ary[1] > 12) return DateAdp_.MinValue; // guard against invalid month
if (ary[2] < 1 || ary[2] > 31) return DateAdp_.MinValue;
return new DateAdp(ary[0], ary[1], ary[2], ary[3], ary[4], ary[5], ary[6]);
}
public static DateAdp parse_gplx(String raw) {
int[] ary = date_parser.Parse_iso8651_like(raw);
if (ary[1] < 1 || ary[1] > 12) return DateAdp_.MinValue; // guard against invalid month
if (ary[2] < 1 || ary[2] > 31) return DateAdp_.MinValue;
return new DateAdp(ary[0], ary[1], ary[2], ary[3], ary[4], ary[5], ary[6]);
} static DateAdp_parser date_parser = DateAdp_parser.new_();
public static DateAdp dateTime_(GregorianCalendar v) {return new DateAdp(v);}
public static DateAdp dateTime_obj_(Object v) {return new DateAdp((GregorianCalendar)v);}
public static final DateAdp_ Gfs = new DateAdp_();
public static int DaysInMonth(DateAdp date) {return DaysInMonth(date.Month(), date.Year());}
public static int DaysInMonth(int month, int year) {
int rv = DaysInMonth_ary[month - Int_.Base1];
if (rv == 28 && IsLeapYear(year)) rv = 29;
return rv;
}
private static int [] DaysInMonth_ary = {31,28,31,30,31,30,31,31,30,31,30,31};
public static boolean IsLeapYear(int year) {
if (year % 4 != 0) return false;
else if (year % 400 == 0) return true;
else if (year % 100 == 0) return false;
else return true;
}
public static DateAdp unixtime_utc_seconds_(long v) {return unixtime_utc_ms_(v * 1000);}
public static DateAdp parse_fmt_or(String raw, String fmt, DateAdp or) {
try {return parse_fmt(raw, fmt);}
catch (Exception e) {Err_.Noop(e); return or;}
}
public static DateAdp db_(Object v) {
if (v instanceof String) {
return DateAdp_.parse_iso8561((String)v);
}
Timestamp ts = (Timestamp)v;
Calendar gc = Calendar.getInstance();
gc.setTimeInMillis(ts.getTime());
return new DateAdp(gc);
}
public static DateAdp parse_(String raw) {
SimpleDateFormat sdf = new SimpleDateFormat();
Date d = null;
try {d = sdf.parse(raw);}
catch (ParseException e) {throw Err_.new_("parse", "failed to parse to DateAdp", "raw", raw);}
GregorianCalendar cal = (GregorianCalendar)Calendar.getInstance();
cal.setTime(d);
return dateTime_(cal);
}
public static DateAdp parse_fmt(String raw, String fmt) {
fmt = fmt.replace('t', 'a'); // AM/PM
fmt = fmt.replace('f', 'S'); // milliseconds
SimpleDateFormat sdf = new SimpleDateFormat(fmt, Locale.US);
Date d = null;
try {d = sdf.parse(raw);}
catch (ParseException e) {throw Err_.new_("parse", "failed to parse to DateAdp", "raw", raw, "fmt", fmt);}
GregorianCalendar cal = (GregorianCalendar)Calendar.getInstance();
cal.setTime(d);
return dateTime_(cal);
}
public static DateAdp unixtime_utc_ms_(long v) {return unixtime_lcl_ms_(v).XtoUtc();}
public static DateAdp unixtime_lcl_ms_(long v) {
GregorianCalendar c = new GregorianCalendar();
c.setTimeInMillis(v);
return new DateAdp(c);
}
public static DateAdp New_w_tz(int y, int m, int d, int h, int i, int s, int us, String tz_id) {
TimeZone tz = String_.Eq(tz_id, "UTC") ? TIME_ZONE__UTC : TimeZone.getTimeZone(tz_id);
return new DateAdp(y, m, d, h, i, s, us/1000, tz);
}
private static TimeZone TIME_ZONE__UTC = TimeZone.getTimeZone("UTC");
public static final int
SegIdx_year = 0, SegIdx_month = 1, SegIdx_day = 2, SegIdx_hour = 3, SegIdx_minute = 4, SegIdx_second = 5
, SegIdx_frac = 6, SegIdx_dayOfWeek = 7, SegIdx_weekOfYear = 8, SegIdx_dayOfYear = 9, SegIdx_tz = 10, SegIdx__max = 11;
public static String Xto_str_fmt_or(DateAdp v, String fmt, String or) {
return v == null ? or : v.XtoStr_fmt(fmt);
}
public static DateAdp FirstDayofYear(int year) {
return new DateAdp(year, 1, 1, 0, 0, 0, 0);
}
public static DateAdp DateByDayofYear(int year, int day) {
return new DateAdp(year, 1, day, 0, 0, 0, 0);
}
public static DateAdp DateByBits(int y, int m, int d, int h, int i, int s, int us, int tz_ofs, byte[] tz_abbr) {
DateAdp dte = new DateAdp(y, m, d, h, i, s, us/1000);
if (tz_ofs != 0)
dte.SetTzOffset(tz_ofs);
return dte;
}
public static final String
Fmt_iso8561_date_time = "yyyy-MM-dd HH:mm:ss"
, Fmt__yyyyMMdd = "yyyyMMdd";
}

@ -1,92 +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;
import org.junit.*; import gplx.core.tests.*;
public class DateAdp__tst {
private final DateAdp__fxt fxt = new DateAdp__fxt();
@Test public void Parse_gplx() {
fxt.Test__parse_gplx("99991231_235959.999" , "99991231_235959.999");
fxt.Test__parse_gplx("20090430_213200.123" , "20090430_213200.123");
fxt.Test__parse_gplx("20090430_213200" , "20090430_213200.000");
fxt.Test__parse_gplx("20090430" , "20090430_000000.000");
}
@Test public void Parse_separators() {
fxt.Test__parse_gplx("2009-04-30 21:32:00.123" , "20090430_213200.123");
fxt.Test__parse_gplx("2009-04-30 21:32:00" , "20090430_213200.000");
fxt.Test__parse_gplx("2009-04-30" , "20090430_000000.000");
}
@Test public void Parse_utc() {
fxt.Test__parse_gplx("2015-12-26T10:03:53Z" , "20151226_100353.000");
}
@Test public void DayOfWeek() {
fxt.Test__day_of_week("2012-01-18", 3); //3=Wed
}
@Test public void WeekOfYear() {
fxt.Test__week_of_year("2006-02-01", 5); // 1-1:Sun;2-1:Wed
fxt.Test__week_of_year("2007-02-01", 5); // 1-1:Mon;2-1:Thu
fxt.Test__week_of_year("2008-02-01", 5); // 1-1:Tue;2-1:Fri
fxt.Test__week_of_year("2009-02-01", 6); // 1-1:Thu;2-1:Sun
fxt.Test__week_of_year("2010-02-01", 6); // 1-1:Fri;2-1:Mon
fxt.Test__week_of_year("2011-02-01", 6); // 1-1:Sat;2-1:Tue
}
@Test public void DayOfYear() {
fxt.Test__day_of_year("2012-01-01", 1);
fxt.Test__day_of_year("2012-02-29", 60);
fxt.Test__day_of_year("2012-12-31", 366);
}
@Test public void Timestamp_unix() {
fxt.Test__timestamp_unix("1970-01-01 00:00:00", 0);
fxt.Test__timestamp_unix("2012-01-01 00:00:00", 1325376000);
}
@Test public void DaysInMonth() {
fxt.Test__days_in_month("2012-01-01", 31);
fxt.Test__days_in_month("2012-02-01", 29);
fxt.Test__days_in_month("2012-04-01", 30);
fxt.Test__days_in_month("2011-02-01", 28);
}
@Test public void XtoUtc() {
fxt.Test__to_utc("2012-01-01 00:00", "2012-01-01 05:00"); //4=Wed
}
@Test public void Timezone_id() {
fxt.Test__timezone_id("2015-12-26T10:03:53Z", "UTC");
}
}
class DateAdp__fxt {
public void Test__parse_gplx(String raw, String expd) {
Gftest.Eq__str(expd, DateAdp_.parse_gplx(raw).XtoStr_gplx());
}
public void Test__day_of_week(String raw, int expd) {
Gftest.Eq__int(expd, DateAdp_.parse_gplx(raw).DayOfWeek());
}
public void Test__week_of_year(String raw, int expd) {
Gftest.Eq__int(expd, DateAdp_.parse_gplx(raw).WeekOfYear());
}
public void Test__day_of_year(String raw, int expd) {
Gftest.Eq__int(expd, DateAdp_.parse_gplx(raw).DayOfYear());
}
public void Test__days_in_month(String raw, int expd) {
Gftest.Eq__int(expd, DateAdp_.DaysInMonth(DateAdp_.parse_gplx(raw)));
}
public void Test__timestamp_unix(String raw, long expd) {
Gftest.Eq__long(expd, DateAdp_.parse_gplx(raw).Timestamp_unix());
}
public void Test__to_utc(String raw, String expd) {
Tfds.Eq(expd, DateAdp_.parse_gplx(raw).XtoUtc().XtoStr_fmt_yyyy_MM_dd_HH_mm());
}
public void Test__timezone_id(String raw, String expd) {
Gftest.Eq__str(expd, DateAdp_.parse_gplx(raw).XtoUtc().Timezone_id());
}
}

@ -1,67 +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;
import java.util.GregorianCalendar;
public class Datetime_now {
private static final DateAdp dflt = DateAdp_.parse_gplx("2001-01-01 00:00:00.000");
private static DateAdp manual;
private static boolean autoincrement = true;
public static void Manual_y_() {
manual = dflt;
}
public static void Manual_n_() {
manual = null;
autoincrement = true;
}
public static void Manual_and_freeze_(DateAdp v) {
manual = v;
autoincrement = false;
}
public static void Manual_(DateAdp v) {
manual = v;
}
public static void Autoincrement_n_() {
autoincrement = false;
}
public static DateAdp Dflt_add_min_(int v) {
return dflt.Add_minute(v);
}
public static DateAdp Get() {
if (manual == null) return new DateAdp(new GregorianCalendar());
DateAdp rv = manual;
if (autoincrement) manual = rv.Add_minute(1); // simulate passage of manual by increasing manual by 1 minute with each call
return rv;
}
public static DateAdp Get_force() { // ignore manual and force get of real time
return new DateAdp(new GregorianCalendar());
}
// private static final DateAdp manual_time_dflt = DateAdp_.parse_gplx("2001-01-01 00:00:00.000");
// private static DateAdp manual_time;
// static boolean Now_enabled() {return now_enabled;} private static boolean now_enabled;
// static void Now_enabled_y_() {now_enabled = BoolUtl.Y; manual_time = manual_time_dflt;}
// static void Now_enabled_n_() {now_enabled = BoolUtl.N; now_freeze = false;}
// public static void Now_set(DateAdp date) {now_enabled = true; manual_time = date;}
// public static void Now_freeze_y_() {now_freeze = true;}
// private static boolean now_freeze;
// public static DateAdp Now_time0_add_min(int minutes) {return manual_time_dflt.Add_minute(minutes);}
// @gplx.Internal protected static DateAdp Now() {
// DateAdp rv = manual_time;
// if (!now_freeze) manual_time = rv.Add_minute(1);
// return rv;
// }
}

@ -1,94 +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;
import gplx.objects.lists.CompareAble;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class Decimal_adp implements CompareAble {
public int compareTo(Object obj) {Decimal_adp comp = (Decimal_adp)obj; return under.compareTo(comp.under);}
public Decimal_adp Floor() {return Decimal_adp_.int_(this.To_int());}
protected Decimal_adp(BigDecimal v) {this.under = v;} private final BigDecimal under;
protected Decimal_adp(int v) {this.under = new BigDecimal(v);}
public Object Under() {return under;}
public BigDecimal Under_as_native() {return under;}
public int Precision() {return under.precision();}
public int Frac_1000() {return (int)(under.movePointRight(3).floatValue() % 1000);}
public boolean Eq(Decimal_adp v) {return v.under.doubleValue() == under.doubleValue();}
public boolean Eq(int v) {return under.doubleValue() == v;}
public String To_str() {
BigDecimal tmp = under;
int tmp_scale = tmp.scale();
if (tmp_scale <= -14) return tmp.toString(); // NOTE: if large number, call .toString which will return exponential notaion (1E##) instead of literal (1000....); 14 matches MW code; DATE:2015-04-10
if (tmp_scale > 14)
tmp = tmp.setScale(14, RoundingMode.DOWN); // NOTE: if small number, round down to remove excessive zeroes; 14 matches PHP/C# values more closely; RoundingMode.Down for same reason; see E, Pi tests
return tmp .stripTrailingZeros() // NOTE: stripTrailingZeros for exp tests; EX: 120.0 -> 120; 0.01200000000000 -> .012
.toPlainString(); // NOTE: toPlainString b/c stripTrailingZeros now converts 120 to 1.2E+2 (and any other value that is a multiple of 10)
}
public String To_str(String fmt) {
return new DecimalFormat(fmt).format(under);
}
@Override public String toString() {return under.toString();}
public int To_int() {return (int)under.doubleValue();}
public long To_long() {return (long)under.doubleValue();}
public long To_long_mult_1000() {return under.movePointRight(3).longValue();}
public double To_double() {return under.doubleValue();}
public Decimal_adp Add(Decimal_adp v) {return new Decimal_adp(under.add(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Subtract(Decimal_adp v) {return new Decimal_adp(under.subtract(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Multiply(Decimal_adp v) {return new Decimal_adp(under.multiply(v.under));}
public Decimal_adp Multiply(double v) {return new Decimal_adp(under.multiply(new BigDecimal(v, Decimal_adp_.Gplx_rounding_context)));}
public Decimal_adp Multiply(long v) {return new Decimal_adp(under.multiply(new BigDecimal(v)));}
public Decimal_adp Divide(Decimal_adp v) {return new Decimal_adp(under.divide(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Mod(Decimal_adp v) {return new Decimal_adp(under.remainder(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Abs() {return new Decimal_adp(under.abs(Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Pow(int v) {return new Decimal_adp(under.pow(v, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Sqrt() {return new Decimal_adp(new BigDecimal(Math_.Sqrt(under.doubleValue())));}
public Decimal_adp Truncate() {return new Decimal_adp(under.intValue());}
public Decimal_adp Round_old(int v) {return new Decimal_adp(under.setScale(v, RoundingMode.HALF_UP));}
public Decimal_adp Round(int v) {
BigDecimal new_val = null;
if (v > 0) {
new_val = under.setScale(v, RoundingMode.HALF_UP);
}
else {
int actl_places = under.precision() - under.scale();
int reqd_places = -v;
if (reqd_places < actl_places)
new_val = under.round(new java.math.MathContext(actl_places - reqd_places, RoundingMode.HALF_UP));
else if (reqd_places == actl_places) {
int base_10 = (int)Math_.Pow(10, reqd_places - 1);
if (under.intValue() / base_10 < 5)
new_val = BigDecimal.ZERO;
else
new_val = new BigDecimal(Math_.Pow(10, reqd_places));
}
else
new_val = BigDecimal.ZERO;
}
return new Decimal_adp(new_val);
}
public Decimal_adp Round_to_default_precision() {
return new Decimal_adp(under.round(Decimal_adp_.Gplx_rounding_context));
}
public boolean Comp_gte(Decimal_adp v) {return under.doubleValue() >= v.under.doubleValue();}
public boolean Comp_gte(int v) {return under.doubleValue() >= v;}
public boolean Comp_lte(Decimal_adp v) {return under.doubleValue() <= v.under.doubleValue();}
public boolean Comp_lte(int v) {return under.doubleValue() <= v;}
public boolean Comp_gt(Decimal_adp v) {return under.doubleValue() > v.under.doubleValue();}
public boolean Comp_gt(int v) {return under.doubleValue() > v;}
public boolean Comp_lt(Decimal_adp v) {return under.doubleValue() < v.under.doubleValue();}
public boolean Comp_lt(int v) {return under.doubleValue() < v;}
}

@ -1,91 +0,0 @@
/*
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;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class Decimal_adp_ {
public static final String Cls_val_name = "decimal";
public static final Class<?> Cls_ref_type = Decimal_adp.class;
public static Decimal_adp as_(Object obj) {return obj instanceof Decimal_adp ? (Decimal_adp)obj : null;}
public static final Decimal_adp Zero = new Decimal_adp(0);
public static final Decimal_adp One = new Decimal_adp(1);
public static final Decimal_adp Neg1 = new Decimal_adp(-1);
public static final Decimal_adp Const_e = Decimal_adp_.double_(Math_.E);
public static final Decimal_adp Const_pi = Decimal_adp_.double_(Math_.Pi);
public static Decimal_adp base1000_(long v) {return divide_(v, 1000);}
public static Decimal_adp parts_1000_(long num, int frc) {return divide_((num * (1000)) + frc, 1000);}
public static Decimal_adp parts_(long num, int frc) {
// int log10 = frc == 0 ? 0 : (Math_.Log10(frc) + 1);
// int pow10 = (int)Math_.Pow(10, log10);
int pow10 = XtoPow10(frc);
return divide_((num * (pow10)) + frc, pow10);
}
public static Decimal_adp cast(Object obj) {return (Decimal_adp)obj;}
static int XtoPow10(int v) {
if (v > -1 && v < 10) return 10;
else if (v > 9 && v < 100) return 100;
else if (v > 99 && v < 1000) return 1000;
else if (v > 999 && v < 10000) return 10000;
else if (v > 9999 && v < 100000) return 100000;
else if (v > 99999 && v < 1000000) return 1000000;
else if (v > 999999 && v < 10000000) return 10000000;
else if (v > 9999999 && v < 100000000) return 100000000;
else if (v > 99999999 && v < 1000000000) return 1000000000;
else throw Err_.new_wo_type("value must be between 0 and 1 billion", "v", v);
}
public static String CalcPctStr(long dividend, long divisor, String fmt) {
if (divisor == 0) return "%ERR";
return Decimal_adp_.float_(Float_.Div(dividend, divisor) * 100).To_str(fmt) + "%";
}
public static Decimal_adp divide_safe_(long lhs, long rhs) {return rhs == 0 ? Zero : divide_(lhs, rhs);}
public static Decimal_adp divide_(long lhs, long rhs) {
return new Decimal_adp(new BigDecimal(lhs).divide(new BigDecimal(rhs), Gplx_rounding_context));
}
public static Decimal_adp int_(int v) {return new Decimal_adp(new BigDecimal(v));}
public static Decimal_adp long_(long v) {return new Decimal_adp(new BigDecimal(v));}
public static Decimal_adp float_(float v) {return new Decimal_adp(new BigDecimal(v));}
public static Decimal_adp double_(double v) {return new Decimal_adp(new BigDecimal(v));}
public static Decimal_adp double_thru_str_(double v) {return new Decimal_adp(BigDecimal.valueOf(v));}
public static Decimal_adp db_(Object v) {return new Decimal_adp((BigDecimal)v);}
public static Decimal_adp parse(String raw) {
try {
DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(Locale.US); // always parse as US format; EX:".9" should not be ",9" in german; DATE:2016-01-31
nf.setParseBigDecimal(true);
// 2020-08-27|ISSUE#:565|Parse 'e' as 'E'; PAGE:en.w:Huntington_Plaza
if (raw.contains("e")) {
raw = raw.replace("e", "E");
}
// 2021-02-13|ISSUE#:838|Parse '.' as '0.'; PAGE:en.w:2019_FIVB_Volleyball_Women%27s_Challenger_Cup#Pool_A
if (raw.startsWith(".")) {
raw = "0" + raw;
}
BigDecimal bd = (BigDecimal)nf.parse(raw);
return new Decimal_adp(bd);
} catch (ParseException e) {
throw Err_.new_("Decimal_adp_", "parse to decimal failed", "raw", raw);
}
}
public static Decimal_adp pow_10_(int v) {return new Decimal_adp(new BigDecimal(1).scaleByPowerOfTen(v));}
public static final MathContext RoundDownContext = new MathContext(0, RoundingMode.DOWN);
public static final MathContext Gplx_rounding_context = new MathContext(14, RoundingMode.HALF_UP); // changed from 28 to 14; DATE:2015-07-31
}

@ -1,93 +0,0 @@
/*
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;
import org.junit.*;
public class Decimal_adp__tst {
private final Decimal_adp__fxt fxt = new Decimal_adp__fxt();
@Test public void divide_() {
fxt.Test_divide(1, 1000, "0.001");
fxt.Test_divide(1, 3, "0.33333333333333");
fxt.Test_divide(1, 7, "0.14285714285714");
}
@Test public void base1000_() {
fxt.Test_base_1000(1000, "1");
fxt.Test_base_1000(1234, "1.234");
fxt.Test_base_1000(123, "0.123");
}
@Test public void parts_() {
fxt.Test_parts(1, 0, "1");
fxt.Test_parts(1, 2, "1.2");
fxt.Test_parts(1, 23, "1.23");
fxt.Test_parts(123, 4567, "123.4567");
}
@Test public void parse() {
fxt.Test_parse("1", "1");
fxt.Test_parse("1.2", "1.2");
fxt.Test_parse("0.1", "0.1");
fxt.Test_parse("1.2E1", "12");
fxt.Test_parse("1.2e1", "12"); // 2020-08-27|ISSUE#:565|Parse 'e' as 'E'; PAGE:en.w:Huntington_Plaza
}
@Test public void parse_dot() {
fxt.Test_parse(".", "0"); // 2021-02-13|ISSUE#:838|Parse '.' as '0.'; PAGE:en.w:2019_FIVB_Volleyball_Women%27s_Challenger_Cup#Pool_A
}
@Test public void Truncate_decimal() {
fxt.Test_truncate_decimal("1", "1");
fxt.Test_truncate_decimal("1.1", "1");
fxt.Test_truncate_decimal("1.9", "1");
}
@Test public void Fraction1000() {
fxt.Test_frac_1000(1, 1000, 1); // 0.001
fxt.Test_frac_1000(1, 3, 333); // 0.33333333
fxt.Test_frac_1000(1234, 1000, 234); // 1.234
fxt.Test_frac_1000(12345, 10000, 234); // 1.2345
}
@Test public void Lt() {
fxt.Test_comp_lt(1,123, 2, true);
fxt.Test_comp_lt(1,99999999, 2, true);
}
@Test public void To_str_fmt() {
fxt.Test_to_str_fmt(1, 2, "0.0", "0.5");
fxt.Test_to_str_fmt(1, 3, "0.0", "0.3");
fxt.Test_to_str_fmt(10000, 7, "0,000.000", "1,428.571");
fxt.Test_to_str_fmt(1, 2, "00.00", "00.50");
}
@Test public void Round() {
fxt.Test_round("123.456", 3, "123.456");
fxt.Test_round("123.456", 2, "123.46");
fxt.Test_round("123.456", 1, "123.5");
fxt.Test_round("123.456", 0, "123");
fxt.Test_round("123.456", -1, "120");
fxt.Test_round("123.456", -2, "100");
fxt.Test_round("123.456", -3, "0");
fxt.Test_round("6", -1, "10");
fxt.Test_round("5", -1, "10");
fxt.Test_round("6", -2, "0");
}
}
class Decimal_adp__fxt {
public void Test_divide(int lhs, int rhs, String expd) {Tfds.Eq(expd, Decimal_adp_.divide_(lhs, rhs).To_str());}
public void Test_base_1000(int val, String expd) {Tfds.Eq(expd, Decimal_adp_.base1000_(val).To_str());}
public void Test_parts(int num, int fracs, String expd) {Tfds.Eq(expd, Decimal_adp_.parts_(num, fracs).To_str());}
public void Test_parse(String raw, String expd) {Tfds.Eq(expd, Decimal_adp_.parse(raw).To_str());}
public void Test_truncate_decimal(String raw, String expd) {Tfds.Eq(Decimal_adp_.parse(expd).To_str(), Decimal_adp_.parse(raw).Truncate().To_str());}
public void Test_frac_1000(int lhs, int rhs, int expd) {Tfds.Eq(expd, Decimal_adp_.divide_(lhs, rhs).Frac_1000());}
public void Test_comp_lt(int lhsNum, int lhsFrc, int rhs, boolean expd) {Tfds.Eq(expd, Decimal_adp_.parts_(lhsNum, lhsFrc).Comp_lt(rhs));}
public void Test_to_str_fmt(int l, int r, String fmt, String expd) {Tfds.Eq(expd, Decimal_adp_.divide_(l, r).To_str(fmt));}
public void Test_round(String raw, int places, String expd) {Tfds.Eq_str(expd, Decimal_adp_.parse(raw).Round(places).To_str(), "round");}
}

@ -1,56 +0,0 @@
/*
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;
import gplx.objects.lists.CompareAbleUtl;
import gplx.objects.primitives.DoubleUtl;
public class Double_ {
public static final String Cls_val_name = "double";
public static final Class<?> Cls_ref_type = Double.class;
public static final double
MinValue = Double.MIN_VALUE
, NaN = Double.NaN
, Inf_pos = Double.POSITIVE_INFINITY
;
public static final byte[]
NaN_bry = Bry_.new_a7("NaN")
, Inf_pos_bry = Bry_.new_a7("INF")
;
public static boolean IsNaN(double v) {return Double.isNaN(v);}
public static double cast(Object o) {try {return (Double)o;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, double.class, o);}}
public static double parse(String raw) {try {return Double.parseDouble(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, double.class, raw);}}
public static double parse_or(String raw, double v) {try {return Double.parseDouble(raw);} catch(Exception e) {Err_.Noop(e); return v;}}
public static double coerce_(Object v) {
try {String s = String_.as_(v); return s == null ? Double_.cast(v) : Double_.parse(s);}
catch (Exception e) {throw Err_.new_cast(e, double.class, v);}
}
public static String To_str(double v) {
int v_int = (int)v;
return v - v_int == 0 ? Int_.To_str(v_int) : Double.toString(v);
}
public static String To_str_loose(double v) {
int v_as_int = (int)v;
return v == v_as_int
? Int_.To_str(v_as_int) // convert to int, and call print String to eliminate any trailing decimal places
// DATE:2014-07-29; calling ((float)v).toString is better at removing trailing 0s than String.format("%g", v). note that .net .toString() handles it better; EX:2449.600000000000d
// DATE:2020-08-12; calling ToStrByPrintF b/c better at removing trailing 0s; ISSUE#:697;
: DoubleUtl.ToStrByPrintF(v);
}
public static int Compare(double lhs, double rhs) {
if (lhs == rhs) return CompareAbleUtl.Same;
else if (lhs < rhs) return CompareAbleUtl.Less;
else return CompareAbleUtl.More;
}
}

@ -1,27 +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;
import org.junit.*;
public class Double__tst {
private Double__fxt fxt = new Double__fxt();
@Test public void Xto_str_loose() {
fxt.Test_Xto_str_loose(2449.6000000d , "2449.6");
fxt.Test_Xto_str_loose(623.700d , "623.7");
}
}
class Double__fxt {
public void Test_Xto_str_loose(double v, String expd) {Tfds.Eq(expd, Double_.To_str_loose(v));}
}

@ -1,20 +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;
public class Enm_ {
public static int To_int(Object enm) {return Ordinal_lang(enm);}
private static int Ordinal_lang(Object v) {return ((Enum)v).ordinal();}
}

@ -1,91 +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;
import gplx.core.errs.Err_msg;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.primitives.BoolUtl;
public class Err extends RuntimeException {
private final boolean is_gplx;
private final String trace;
private Err_msg[] msgs_ary = new Err_msg[8]; private int msgs_len = 8, msgs_idx = 0;
public Err(boolean is_gplx, String trace, String type, String msg, Object... args) {
this.is_gplx = is_gplx;
// NOTE: Err_ factory methods pass in null stack trace for gplx excs; call Stack_trace here, note that trace will not show constructor
this.trace = is_gplx ? Err_.Trace_lang(this) : trace;
Msgs_add(type, msg, args);
}
// marks messages logged so they can be ignored; used by Gfh_utl
public boolean Logged() {return logged;} public Err Logged_y_() {logged = true; return this;} private boolean logged;
// ignores current frame for reporting messages
public int Trace_ignore() {return trace_ignore;} public Err Trace_ignore_add_1_() {++trace_ignore; return this;} private int trace_ignore = 0;
public Err Args_add(Object... args) {msgs_ary[msgs_idx - 1].Args_add(args); return this;} // i - 1 to get current
public String To_str__full() {return To_str(BoolUtl.N, BoolUtl.Y);}
public String To_str__log() {return To_str(BoolUtl.Y, BoolUtl.Y);}
public String To_str__msg_only(){
return msgs_idx == 0 ? "<<MISSING ERROR MESSAGE>>" : msgs_ary[0].To_str_wo_type(); // take 1st message only
}
public String To_str__top_wo_args() {
return msgs_idx == 0 ? "<<MISSING ERROR MESSAGE>>" : msgs_ary[0].To_str_wo_args();
}
private String To_str(boolean called_by_log, boolean include_trace) {
String nl_str = called_by_log ? "\t" : "\n";
String rv = "";
for (int i = 0; i < msgs_idx; ++i) {
rv += "[err " + Int_.To_str(i) + "] " + String_.Replace(msgs_ary[i].To_str(), "\n", nl_str) + nl_str;
}
if (include_trace)
rv += "[trace]:" + Trace_to_str(is_gplx, called_by_log, trace_ignore, trace == null ? Err_.Trace_lang(this) : trace);
return rv;
}
@Override public String getMessage() {return To_str__msg_only();}
public static String Trace_to_str(boolean is_gplx, boolean called_by_log, int ignore_lines, String trace) {
if (trace == null) return ""; // WORKAROUND:.NET: StackTrace is only available when error is thrown; can't do "Console.Write(new Exception().StackTrace);
String[] lines = String_.Split_lang(trace, '\n'); int lines_len = lines.length;
int line_bgn = 0;
if (is_gplx) { // remove Err_.new_wo_type lines from trace for gplx exceptions
for (int i = 0; i < lines_len; ++i) {
String line = lines[i];
if (String_.Has_at_bgn(line, "gplx.Err_.new")) continue; // ignore trace frames with "gplx.Err_.new"; EX: throw Err_.new_unimplemented
line_bgn = i + ignore_lines;
break;
}
}
// concat lines
String rv = "";
String line_bgn_dlm = called_by_log ? "\t " : "\n "; // "\n " indents
for (int i = line_bgn; i < lines_len; ++i)
rv += line_bgn_dlm + lines[i];
return rv;
}
@gplx.Internal protected void Msgs_add(String type, String msg, Object[] args) {
if (msgs_idx == msgs_len) {
int new_len = msgs_len * 2;
Err_msg[] new_ary = new Err_msg[new_len];
ArrayUtl.CopyTo(msgs_ary, new_ary, 0);
this.msgs_ary = new_ary;
this.msgs_len = new_len;
}
msgs_ary[msgs_idx] = new Err_msg(type, msg, args);
++msgs_idx;
}
}

@ -1,79 +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;
import gplx.objects.primitives.BoolUtl;
public class Err_ {
private static String Type__gplx = "gplx", Trace_null = null;
public static void Noop(Exception e) {}
public static Err New(String msg, Object... args) {return new Err(BoolUtl.Y, Trace_null, "", String_.Format(msg, args));}
public static Err new_(String type, String msg, Object... args) {return new Err(BoolUtl.Y, Trace_null, type, msg, args);}
public static Err new_wo_type(String msg, Object... args) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, msg, args);}
public static Err new_exc(Exception e, String type, String msg, Object... args) {
Err rv = Cast_or_make(e);
rv.Msgs_add(type, msg, args);
return rv;
}
public static Err new_unhandled(Object val) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "val is not in switch/if", "val", val);}
public static Err new_unhandled_default(Object val) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "val is not in switch", "val", val);}
public static Err new_unhandled_default_w_msg(Object val, String msg) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "val is not in switch", "val", val, "msg", msg);}
public static Err new_unsupported() {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "method not supported");}
public static Err new_unimplemented() {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "method not implemented");}
public static Err new_unimplemented_w_msg(String msg, Object... args) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, msg, args);}
public static Err new_deprecated(String s) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "deprecated", "method", s);}
public static Err new_parse_type(Class<?> c, String raw) {return new_parse(Type_.Canonical_name(c), raw);}
public static Err new_parse_exc(Exception e, Class<?> c, String raw) {return new_parse(Type_.Canonical_name(c), raw).Args_add("e", Err_.Message_lang(e));}
public static Err new_parse(String type, String raw) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "parse failed", "type", type, "raw", raw);}
public static Err new_null() {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "null obj");}
public static Err new_null(String arg) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "null obj", "arg", arg);}
public static Err new_missing_idx(int idx, int len) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "index is out of bounds", "idx", idx, "len", len);}
public static Err new_missing_key(String key) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "key not found", "key", key);}
public static Err new_invalid_op(String msg) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, msg);}
public static Err new_invalid_arg(String msg, Object... args) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, msg, args);}
public static Err new_op_canceled() {return new Err(BoolUtl.Y, Trace_null, Type__op_canceled, "canceled by usr");}
public static Err new_type_mismatch_w_exc(Exception ignore, Class<?> t, Object o) {return new_type_mismatch(t, o);}
public static Err new_type_mismatch(Class<?> t, Object o) {return new Err(BoolUtl.Y, Trace_null, Type__gplx, "type mismatch", "expdType", Type_.Canonical_name(t), "actlType", Type_.Name_by_obj(o), "actlObj", Object_.Xto_str_strict_or_null_mark(o));}
public static Err new_cast(Exception ignore, Class<?> t, Object o) {
String o_str = "";
try {o_str = Object_.Xto_str_strict_or_null_mark(o);}
catch (Exception e) {o_str = "<ERROR>"; Err_.Noop(e);}
return new Err(BoolUtl.Y, Trace_null, Type__gplx, "cast failed", "type", Type_.Name(t), "obj", o_str);
}
public static String Message_gplx_full(Exception e) {return Cast_or_make(e).To_str__full();}
public static String Message_gplx_log(Exception e) {return Cast_or_make(e).To_str__log();}
public static String Message_lang(Throwable e) {
return Error.class.isAssignableFrom(e.getClass())
? e.toString() // error has null for "getMessage()" return "toString()" instead
: e.getMessage();
}
public static String Trace_lang(Throwable e) {return Trace_lang_exec(e.getStackTrace());}
private static String Trace_lang_exec(StackTraceElement[] ary) {
String rv = "";
int len = ary.length;
for (int i = 0; i < len; i++) {
if (i != 0) rv += "\n";
rv += ary[i].toString();
}
return rv;
}
public static Err Cast_or_null(Exception e) {return Type_.Eq_by_obj(e, Err.class) ? (Err)e : null;}
public static Err Cast_or_make(Throwable e) {return Type_.Eq_by_obj(e, Err.class) ? (Err)e : new Err(BoolUtl.N, Err_.Trace_lang(e), Type_.Name_by_obj(e), Err_.Message_lang(e));}
public static final String Type__op_canceled = "gplx.op_canceled";
}

@ -1,46 +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;
import gplx.objects.primitives.BoolUtl;
import org.junit.Test;
public class Err_Utl_tst {
private final Err_fxt fxt = new Err_fxt();
@Test public void Trace_to_str__gplx() {
fxt.Test_Trace_to_str(BoolUtl.Y, BoolUtl.N, 0, String_.Concat_lines_nl_skip_last
( "gplx.Err_.new_wo_type(Err_.java:1)" // ignore this line
, "gplx.String_.Len(String_.java:2)"
), String_.Concat_lines_nl_skip_last
( ""
, " gplx.String_.Len(String_.java:2)"
));
}
@Test public void Trace_to_str__gplx_ignore() {
fxt.Test_Trace_to_str(BoolUtl.Y, BoolUtl.N, 1, String_.Concat_lines_nl_skip_last
( "gplx.Err_.new_wo_type(Err_.java:1)" // ignore this line
, "gplx.String_.Fail(String_.java:2)" // ignore this line also
, "gplx.String_.Len(String_.java:3)"
), String_.Concat_lines_nl_skip_last
( ""
, " gplx.String_.Len(String_.java:3)"
));
}
}
class Err_fxt {
public void Test_Trace_to_str(boolean is_gplx, boolean called_by_log, int ignore_lines, String trace, String expd) {
String actl = Err.Trace_to_str(is_gplx, called_by_log, ignore_lines, trace);
Tfds.Eq_str_lines(expd, actl);
}
}

@ -1,40 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx;
import gplx.objects.lists.CompareAbleUtl;
public class Float_ {
public static final String Cls_val_name = "float";
public static final Class<?> Cls_ref_type = Float.class;
public static final float NaN = Float.NaN;;
public static boolean IsNaN(float v) {return Float.isNaN(v);}
public static float cast(Object obj) {try {return (Float)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, float.class, obj);}}
public static float parse(String raw) {try {return Float.parseFloat(raw);} catch(Exception exc) {throw Err_.new_parse_exc(exc, float.class, raw);}}
public static int Compare(float lhs, float rhs) {
if ( lhs == rhs) return CompareAbleUtl.Same;
else if ( lhs < rhs) return CompareAbleUtl.Less;
else /*lhs > rhs*/ return CompareAbleUtl.More;
}
public static String To_str(float v) {
int v_int = (int)v;
return v - v_int == 0 ? Int_.To_str(v_int) : Float.toString(v);
}
public static float Div(int val, int divisor) {return (float)val / (float)divisor;}
public static float Div(long val, long divisor) {return (float)val / (float)divisor;}
public static int RoundUp(float val) {
int rv = (int)val;
return (rv == val) ? rv : rv + 1;
}
}

@ -1,70 +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;
import gplx.core.interfaces.*;
public interface GfoMsg {
String Key();
GfoMsg CloneNew();
String To_str();
GfoMsg Clear();
GfoMsg Parse_(boolean v);
int Args_count();
Keyval Args_getAt(int i);
GfoMsg Args_ovr(String k, Object v);
void Args_reset();
GfoMsg Add(String k, Object v);
int Subs_count();
GfoMsg Subs_getAt(int i);
GfoMsg Subs_add(GfoMsg m);
GfoMsg Subs_(GfoMsg... ary);
boolean ReadBool(String k);
boolean ReadBoolOr(String k, boolean or);
boolean ReadBoolOrFalse(String k);
boolean ReadBoolOrTrue(String k);
int ReadInt(String k);
int ReadIntOr(String k, int or);
long ReadLong(String k);
long ReadLongOr(String k, long or);
float ReadFloat(String k);
float ReadFloatOr(String k, float or);
double ReadDouble(String k);
double ReadDoubleOr(String k, double or);
DateAdp ReadDate(String k);
DateAdp ReadDateOr(String k, DateAdp or);
Decimal_adp ReadDecimal(String k);
Decimal_adp ReadDecimalOr(String k, Decimal_adp or);
String ReadStr(String k);
String ReadStrOr(String k, String or);
Io_url ReadIoUrl(String k);
Io_url ReadIoUrlOr(String k, Io_url url);
boolean ReadYn(String k);
boolean ReadYn_toggle(String k, boolean cur);
boolean ReadYnOrY(String k);
byte ReadByte(String k);
byte[] ReadBry(String k);
byte[] ReadBryOr(String k, byte[] or);
Object ReadObj(String k);
Object ReadObj(String k, ParseAble parseAble);
Object ReadObjOr(String k, ParseAble parseAble, Object or);
String[]ReadStrAry(String k, String spr);
String[]ReadStrAryIgnore(String k, String spr, String ignore);
byte[][]ReadBryAry(String k, byte spr);
Object ReadValAt(int i);
Object CastObj(String k);
Object CastObjOr(String k, Object or);
}

@ -1,283 +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;
import gplx.core.interfaces.ParseAble;
import gplx.core.primitives.String_obj_val;
import gplx.core.strings.String_bldr;
import gplx.core.strings.String_bldr_;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.primitives.BoolUtl;
public class GfoMsg_ {
public static GfoMsg as_(Object obj) {return obj instanceof GfoMsg ? (GfoMsg)obj : null;}
public static final GfoMsg Null = new GfoMsg_base().ctor_("<<NULL MSG>>", false);
public static GfoMsg new_parse_(String key) {return new GfoMsg_base().ctor_(key, true);}
public static GfoMsg new_cast_(String key) {return new GfoMsg_base().ctor_(key, false);}
public static GfoMsg srl_(GfoMsg owner, String key) {
GfoMsg rv = new_parse_(key);
owner.Subs_add(rv);
return rv;
}
public static GfoMsg root_(String... ary) {return root_leafArgs_(ary);}
public static GfoMsg root_leafArgs_(String[] ary, Keyval... kvAry) {
int len = ArrayUtl.Len(ary); if (len == 0) throw Err_.new_invalid_arg("== 0", "@len", len);
GfoMsg root = new GfoMsg_base().ctor_(ary[0], false);
GfoMsg owner = root;
for (int i = 1; i < len; i++) {
String key = ary[i];
GfoMsg cur = new GfoMsg_base().ctor_(key, false);
owner.Subs_add(cur);
owner = cur;
}
for (int i = 0; i < kvAry.length; i++) {
Keyval kv = kvAry[i];
owner.Add(kv.Key(), kv.Val());
}
return root;
}
public static GfoMsg chain_(GfoMsg owner, String key) {
GfoMsg sub = owner;
List_adp list = List_adp_.New();
list.Add(sub.Key());
while (sub != null) {
if (sub.Subs_count() == 0) break;
sub = (GfoMsg)sub.Subs_getAt(0);
list.Add(sub.Key());
}
list.Add(key);
GfoMsg root = GfoMsg_.new_parse_((String)list.Get_at(0));
GfoMsg cur = root;
for (int i = 1; i < list.Len(); i++) {
String k = (String)list.Get_at(i);
GfoMsg mm = GfoMsg_.new_parse_(k);
cur.Subs_add(mm);
cur = mm;
}
return root;
}
public static GfoMsg wtr_() {return new GfoMsg_wtr().ctor_("", false);}
public static GfoMsg rdr_(String cmd) {return new GfoMsg_rdr().ctor_(cmd, false);}
public static GfoMsg basic_(String cmd, Object... vals) {
GfoMsg rv = new_cast_(cmd);
int len = vals.length;
for (int i = 0; i < len; i++)
rv.Add("", vals[i]);
return rv;
}
public static Hash_adp Read_str_ary_as_hash(GfoMsg m, String k) {
String[] ary = m.ReadStrAry(k, "|");
int ary_len = ary.length;
if (ary_len == 0) return Hash_adp_.Noop;
Hash_adp rv = Hash_adp_.New();
for (int i = 0; i < ary_len; i++) {
rv.AddIfDupeUse1st(ary[i], ary[i]);
}
return rv;
}
}
class GfoMsg_wtr extends GfoMsg_base {
@Override protected Object ReadOr(String k, Object defaultOr) {
if (args == null) args = List_adp_.New();
args.Add(Keyval_.new_(k, null));
return defaultOr;
}
}
class GfoMsg_rdr extends GfoMsg_base {
@Override protected Object ReadOr(String k, Object defaultOr) {
if (args == null) args = List_adp_.New();
args.Add(Keyval_.new_(k, defaultOr));
return defaultOr;
}
}
class GfoMsg_base implements GfoMsg {
public String Key() {return key;} private String key;
public int Subs_count() {return subs == null ? 0 : subs.Len();}
public GfoMsg Subs_getAt(int i) {return subs == null ? null : (GfoMsg)subs.Get_at(i);}
public GfoMsg Subs_add(GfoMsg m) {if (subs == null) subs = List_adp_.New(); subs.Add(m); return this;}
public GfoMsg Subs_(GfoMsg... ary) {for (GfoMsg m : ary) Subs_add(m); return this;}
public int Args_count() {return args == null ? 0 : args.Len();}
public void Args_reset() {
counter = 0;
Args_reset(this);
}
public GfoMsg Clear() {
this.Args_reset();
if (subs != null) subs.Clear();
if (args != null) args.Clear();
return this;
}
static void Args_reset(GfoMsg owner) {
int len = owner.Subs_count();
for (int i = 0; i < len; i++) {
GfoMsg sub = owner.Subs_getAt(i);
sub.Args_reset();
}
}
public Keyval Args_getAt(int i) {return args == null ? null : (Keyval)args.Get_at(i);}
public GfoMsg Args_ovr(String k, Object v) {
if (args == null) args = List_adp_.New();
for (int i = 0; i < args.Len(); i++) {
Keyval kv = (Keyval)args.Get_at(i);
if (String_.Eq(k, kv.Key())) {
kv.Val_(v);
return this;
}
}
args.Add(Keyval_.new_(k, v));
return this;
}
public GfoMsg Parse_(boolean v) {parse = v; return this;}
public GfoMsg Add(String k, Object v) {
if (args == null) args = List_adp_.New();
args.Add(Keyval_.new_(k, v));
return this;
}
public boolean ReadBool(String k) {Object rv = ReadOr(k,false); if (rv == Nil) ThrowNotFound(k); return parse ? Yn.parse_or((String)rv, false) : BoolUtl.Cast(rv);}
public int ReadInt(String k) {Object rv = ReadOr(k, 0) ; if (rv == Nil) ThrowNotFound(k); return parse ? Int_.Parse((String)rv) : Int_.Cast(rv);}
public byte ReadByte(String k) {Object rv = ReadOr(k, 0) ; if (rv == Nil) ThrowNotFound(k); return parse ? Byte_.Parse((String)rv) : Byte_.Cast(rv);}
public long ReadLong(String k) {Object rv = ReadOr(k, 0) ; if (rv == Nil) ThrowNotFound(k); return parse ? Long_.parse((String)rv) : Long_.cast(rv);}
public float ReadFloat(String k) {Object rv = ReadOr(k, 0) ; if (rv == Nil) ThrowNotFound(k); return parse ? Float_.parse((String)rv) : Float_.cast(rv);}
public double ReadDouble(String k) {Object rv = ReadOr(k, 0) ; if (rv == Nil) ThrowNotFound(k); return parse ? Double_.parse((String)rv) : Double_.cast(rv);}
public Decimal_adp ReadDecimal(String k) {Object rv = ReadOr(k, 0) ; if (rv == Nil) ThrowNotFound(k); return parse ? Decimal_adp_.parse((String)rv) : Decimal_adp_.cast(rv);}
public String ReadStr(String k) {Object rv = ReadOr(k, null); if (rv == Nil) ThrowNotFound(k); return (String)rv;}
public DateAdp ReadDate(String k) {Object rv = ReadOr(k, null); if (rv == Nil) ThrowNotFound(k); return parse ? DateAdp_.parse_gplx((String)rv) : DateAdp_.cast(rv);}
public Io_url ReadIoUrl(String k) {Object rv = ReadOr(k, null); if (rv == Nil) ThrowNotFound(k); return parse ? Io_url_.new_any_((String)rv) : Io_url_.cast(rv);}
public Object CastObj(String k) {Object rv = ReadOr(k, null); if (rv == Nil) ThrowNotFound(k); return rv;}
public boolean ReadBoolOr(String k, boolean or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? Yn.parse_or((String)rv, or) : BoolUtl.Cast(rv);}
public int ReadIntOr(String k, int or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? Int_.Parse((String)rv) : Int_.Cast(rv);}
public long ReadLongOr(String k, long or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? Long_.parse((String)rv) : Long_.cast(rv);}
public float ReadFloatOr(String k, float or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? Float_.parse((String)rv) : Float_.cast(rv);}
public double ReadDoubleOr(String k,double or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? Double_.parse((String)rv) : Double_.cast(rv);}
public Decimal_adp ReadDecimalOr(String k,Decimal_adp or) {Object rv = ReadOr(k, or); if (rv == Nil) return or ; return parse ? Decimal_adp_.parse((String)rv) : Decimal_adp_.cast(rv);}
public String ReadStrOr(String k, String or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return (String)rv;}
public DateAdp ReadDateOr(String k, DateAdp or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? DateAdp_.parse_gplx((String)rv) : DateAdp_.cast(rv);}
public Io_url ReadIoUrlOr(String k, Io_url or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? Io_url_.new_any_((String)rv) : Io_url_.cast(rv);}
public boolean ReadBoolOrFalse(String k) {Object rv = ReadOr(k,false); if (rv == Nil) return false ; return parse ? Yn.parse_or((String)rv, false) : BoolUtl.Cast(rv);}
public boolean ReadBoolOrTrue(String k) {Object rv = ReadOr(k, true); if (rv == Nil) return true ; return parse ? Yn.parse_or((String)rv, true) : BoolUtl.Cast(rv);}
public boolean ReadYnOrY(String k) {Object rv = ReadOr(k, true); if (rv == Nil) return true ; return parse ? Yn.parse_or((String)rv, true) : BoolUtl.Cast(rv);}
public boolean ReadYn(String k) {Object rv = ReadOr(k,false); if (rv == Nil) ThrowNotFound(k); return parse ? Yn.parse_or((String)rv, false) : Yn.coerce_(rv);}
public boolean ReadYn_toggle(String k, boolean cur) {
Object rv = ReadOr(k, "!");
if (rv == Nil) ThrowNotFound(k);
if (!parse) throw Err_.new_wo_type("only parse supported");
String rv_str = (String)rv;
return (String_.Eq(rv_str, "!")) ? !cur : Yn.parse(rv_str);
}
public byte[] ReadBry(String k) {Object rv = ReadOr(k,false); if (rv == Nil) ThrowNotFound(k); return parse ? Bry_.new_u8((String)rv) : (byte[])rv;}
public byte[] ReadBryOr(String k, byte[] or) {Object rv = ReadOr(k, or); if (rv == Nil) return or; return parse ? Bry_.new_u8((String)rv) : (byte[])rv;}
public Object CastObjOr(String k, Object or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return rv;}
public Object ReadObj(String k) {Object rv = ReadOr(k, null); if (rv == Nil) ThrowNotFound(k); return rv;}
public Object ReadObj(String k, ParseAble parseAble) {Object rv = ReadOr(k, null); if (rv == Nil) ThrowNotFound(k); return parse ? parseAble.ParseAsObj((String)rv) : rv;}
public Object ReadObjOr(String k, ParseAble parseAble, Object or) {Object rv = ReadOr(k, or) ; if (rv == Nil) return or ; return parse ? parseAble.ParseAsObj((String)rv) : rv;}
public String[] ReadStrAry(String k, String spr) {return String_.Split(ReadStr(k), spr);}
public byte[][] ReadBryAry(String k, byte spr) {return Bry_split_.Split(ReadBry(k), spr);}
public String[] ReadStrAryIgnore(String k, String spr, String ignore) {return String_.Split(String_.Replace(ReadStr(k), ignore, ""), spr);}
public Object ReadValAt(int i) {return Args_getAt(i).Val();}
protected Object ReadOr(String k, Object defaultOr) {
if (args == null) return Nil; // WORKAROUND.gfui: args null for DataBndr_whenEvt_execCmd
if (!String_.Eq(k, "")) {
for (int i = 0; i < args.Len(); i++) {
Keyval kv = (Keyval)args.Get_at(i);
if (String_.Eq(k, kv.Key())) return kv.Val();
}
}
if (counter >= args.Len()) return Nil;
for (int i = 0; i < args.Len(); i++) {
Keyval kv = (Keyval)args.Get_at(i);
if (String_.Eq(kv.Key(), "") && i >= counter) {
counter++;
return kv.Val();
}
}
return Nil;
} int counter = 0;
void ThrowNotFound(String k) {throw Err_.new_wo_type("arg not found in msg", "k", k, "counter", counter, "args", args);}
String ArgsXtoStr() {
if (this.Args_count() == 0) return "<<EMPTY>>";
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < this.Args_count(); i++) {
Keyval rv = (Keyval)this.Args_getAt(i);
sb.Add_fmt("{0};", rv.Key());
}
return sb.To_str();
}
public GfoMsg CloneNew() {
GfoMsg_base rv = new GfoMsg_base().ctor_(key, parse);
if (args != null) {
rv.args = List_adp_.New();
for (int i = 0; i < args.Len(); i++)
rv.args.Add(args.Get_at(i));
}
if (subs != null) {
rv.subs = List_adp_.New();
for (int i = 0; i < args.Len(); i++) {
GfoMsg sub = (GfoMsg)args.Get_at(i);
rv.subs.Add(sub.CloneNew()); // NOTE: recursion
}
}
return rv;
}
protected List_adp args;
List_adp subs;
public String To_str() {
String_bldr sb = String_bldr_.new_();
To_str(sb, new XtoStrWkr_gplx(), this);
return sb.To_str_and_clear();
}
void To_str(String_bldr sb, XtoStrWkr wkr, GfoMsg m) {
sb.Add(m.Key());
if (m.Subs_count() == 0) {
sb.Add(":");
boolean first = true;
for (int i = 0; i < m.Args_count(); i++) {
Keyval kv = m.Args_getAt(i);
if (kv.Val() == null) continue;
if (!first) sb.Add(" ");
sb.Add(kv.Key());
sb.Add("='");
sb.Add(wkr.To_str(kv.Val()));
sb.Add("'");
first = false;
}
sb.Add(";");
}
else {
sb.Add(".");
To_str(sb, wkr, m.Subs_getAt(0));
}
}
public GfoMsg_base ctor_(String key, boolean parse) {this.key = key; this.parse = parse; return this;} private boolean parse;
@gplx.Internal protected GfoMsg_base(){}
static final String_obj_val Nil = String_obj_val.new_("<<NOT FOUND>>");
}
interface XtoStrWkr {
String To_str(Object o);
}
class XtoStrWkr_gplx implements XtoStrWkr {
public String To_str(Object o) {
if (o == null) return "<<NULL>>";
Class<?> type = Type_.Type_by_obj(o);
String rv = null;
if (Type_.Eq(type, String_.Cls_ref_type)) rv = String_.cast(o);
else if (Type_.Eq(type, Int_.Cls_ref_type)) return Int_.To_str(Int_.Cast(o));
else if (Type_.Eq(type, BoolUtl.ClsRefType)) return Yn.To_str(BoolUtl.Cast(o));
else if (Type_.Eq(type, DateAdp_.Cls_ref_type)) return DateAdp_.cast(o).XtoStr_gplx();
else rv = Object_.Xto_str_strict_or_empty(o);
return String_.Replace(rv, "'", "''");
}
}

@ -1,25 +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;
public interface Gfo_log {
List_adp Itms();
Gfo_log Itms_(List_adp v);
void Warn(String msg, Object... args);
void Note(String msg, Object... args);
void Info(String msg, Object... args);
void Prog(String msg, Object... args);
void Flush();
}

@ -1,33 +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;
public interface Gfo_usr_dlg extends Cancelable {
void Canceled_y_(); void Canceled_n_();
Gfo_usr_dlg__log Log_wkr(); void Log_wkr_(Gfo_usr_dlg__log v);
Gfo_usr_dlg__gui Gui_wkr(); void Gui_wkr_(Gfo_usr_dlg__gui v);
String Log_many(String grp_key, String msg_key, String fmt, Object... args);
String Warn_many(String grp_key, String msg_key, String fmt, Object... args);
Err Fail_many(String grp_key, String msg_key, String fmt, Object... args);
String Prog_many(String grp_key, String msg_key, String fmt, Object... args);
String Prog_none(String grp_key, String msg_key, String fmt);
String Note_many(String grp_key, String msg_key, String fmt, Object... args);
String Note_none(String grp_key, String msg_key, String fmt);
String Note_gui_none(String grp_key, String msg_key, String fmt);
String Prog_one(String grp_key, String msg_key, String fmt, Object arg);
String Prog_direct(String msg);
String Log_direct(String msg);
String Plog_many(String grp_key, String msg_key, String fmt, Object... args);
}

@ -1,64 +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;
import gplx.core.brys.fmtrs.*;
public class Gfo_usr_dlg_base implements Gfo_usr_dlg {
private final Bry_bfr tmp_bfr = Bry_bfr_.Reset(255);
private final Bry_fmtr tmp_fmtr = Bry_fmtr.New__tmp().Fail_when_invalid_escapes_(false); // do not fail b/c msgs may contain excerpt of random text; EX:[[User:A|~A~]] DATE:2014-11-28
public Gfo_usr_dlg_base(Gfo_usr_dlg__log log_wkr, Gfo_usr_dlg__gui gui_wkr) {this.log_wkr = log_wkr; this.gui_wkr = gui_wkr;}
public Gfo_usr_dlg__log Log_wkr() {return log_wkr;} public void Log_wkr_(Gfo_usr_dlg__log v) {log_wkr = v;} private Gfo_usr_dlg__log log_wkr;
public Gfo_usr_dlg__gui Gui_wkr() {return gui_wkr;} public void Gui_wkr_(Gfo_usr_dlg__gui v) {gui_wkr = v;} private Gfo_usr_dlg__gui gui_wkr;
public boolean Canceled() {return canceled;} public void Canceled_y_() {canceled = true;} public void Canceled_n_() {canceled = false;} private boolean canceled;
public void Cancel() {canceled = true;}
public String Log_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wkr.Log_to_session(rv); return rv;}
public String Warn_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wkr.Log_to_err(rv); gui_wkr.Write_warn(rv); return rv;}
public String Prog_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); gui_wkr.Write_prog(rv); return rv;}
public String Prog_one(String grp_key, String msg_key, String fmt, Object arg) {String rv = Bld_msg_one (grp_key, msg_key, fmt, arg ); gui_wkr.Write_prog(rv); return rv;}
public String Prog_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); gui_wkr.Write_prog(rv); return rv;}
public String Prog_direct(String msg) { gui_wkr.Write_prog(msg); return msg;}
public String Log_direct(String msg) { log_wkr.Log_to_session(msg); return msg;}
public String Note_many(String grp_key, String msg_key, String fmt, Object... args) {String rv = Bld_msg_many(grp_key, msg_key, fmt, args ); log_wkr.Log_to_session(rv); gui_wkr.Write_note(rv); return rv;}
public String Note_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); log_wkr.Log_to_session(rv); gui_wkr.Write_note(rv); return rv;}
public String Note_gui_none(String grp_key, String msg_key, String fmt) {String rv = Bld_msg_none(grp_key, msg_key, fmt ); gui_wkr.Write_note(rv); return rv;}
public String Plog_many(String grp_key, String msg_key, String fmt, Object... args) {
String rv = Log_many(grp_key, msg_key, fmt, args);
return Prog_direct(rv);
}
public Err Fail_many(String grp_key, String msg_key, String fmt, Object... args) {
Err rv = Err_.new_wo_type(Bld_msg_many(grp_key, msg_key, fmt, args));
log_wkr.Log_to_err(rv.To_str__full());
return rv;
}
private String Bld_msg_many(String grp_key, String msg_key, String fmt, Object[] args) {
synchronized (tmp_fmtr) {
try {
tmp_fmtr.Fmt_(fmt).Bld_bfr_many(tmp_bfr, args);
return tmp_bfr.To_str_and_clear();
}
catch (Exception e) { // NOTE: can fail if fmt has ~{}; callers should proactively remove, but for now, just return fmt if fails; EX:Page_sync and en.w:Web_crawler; DATE:2016-11-17
Err_.Noop(e);
return fmt;
}
}
}
private String Bld_msg_one(String grp_key, String msg_key, String fmt, Object val) {
synchronized (tmp_fmtr) {
tmp_fmtr.Fmt_(fmt).Bld_bfr_one(tmp_bfr, val);
return tmp_bfr.To_str_and_clear();
}
}
private String Bld_msg_none(String grp_key, String msg_key, String fmt) {return fmt;}
}

@ -1,20 +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;
public class Guid_adp {
public Guid_adp(java.util.UUID guid) {this.guid = guid;} java.util.UUID guid;
public String To_str() {return guid.toString();}
}

@ -1,26 +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;
import org.junit.*;
public class Guid_adp__tst {
@Test public void parse() {
tst_parse_("467ffb41-cdfe-402f-b22b-be855425784b");
}
void tst_parse_(String s) {
Guid_adp uuid = Guid_adp_.Parse(s);
Tfds.Eq(uuid.To_str(), s);
}
}

@ -1,205 +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;
import gplx.core.primitives.*;
import gplx.core.intls.*;
public class Hash_adp_bry extends gplx.core.lists.Hash_adp_base implements Hash_adp {
private final Hash_adp_bry_itm_base proto, key_ref;
Hash_adp_bry(Hash_adp_bry_itm_base proto) {
this.proto = proto;
this.key_ref = proto.New();
}
@Override protected Object Fetch_base(Object key) {synchronized (key_ref) {return super.Fetch_base(key_ref.Init((byte[])key));}} // TS: DATE:2016-07-06
@Override protected void Del_base(Object key) {synchronized (key_ref) {super.Del_base(key_ref.Init((byte[])key));}}// TS: DATE:2016-07-06
@Override protected boolean Has_base(Object key) {synchronized (key_ref) {return super.Has_base(key_ref.Init((byte[])key));}}// TS: DATE:2016-07-06
public int Get_as_int(byte[] key) {return Get_as_int(key, 0, key.length);}
public int Get_as_int(byte[] key, int bgn, int end) {
int rv = Get_as_int_or(key, bgn, end, Int_.Min_value); if (rv == Int_.Min_value) throw Err_.new_("core", "unknown key", "key", key);
return rv;
}
public int Get_as_int_or(byte[] key, int or) {return Get_as_int_or(key, 0, key.length, or);}
public int Get_as_int_or(byte[] key, int bgn, int end, int or) {
Object o = Get_by_mid(key, bgn, end);
return (o == null) ? or : ((Int_obj_val)o).Val();
}
public byte Get_as_byte_or(byte[] key, byte or) {return Get_as_byte_or(key, 0, key.length, or);}
public byte Get_as_byte_or(byte[] key, int bgn, int end, byte or) {
Object o = Get_by_mid(key, bgn, end);
return o == null ? or : ((Byte_obj_val)o).Val();
}
public Object Get_by_bry(byte[] src) {synchronized (key_ref) {return super.Fetch_base(key_ref.Init(src));}} // TS: DATE:2016-07-06
public Object Get_by_mid(byte[] src, int bgn, int end) {synchronized (key_ref) {return super.Fetch_base(key_ref.Init(src, bgn, end));}}// TS: DATE:2016-07-06
public Hash_adp_bry Add_byte_int(byte key, int val) {this.Add_base(new byte[]{key}, new Int_obj_val(val)); return this;}
public Hash_adp_bry Add_bry_byte(byte[] key, byte val) {this.Add_base(key, Byte_obj_val.new_(val)); return this;}
public Hash_adp_bry Add_bry_int(byte[] key, int val) {this.Add_base(key, new Int_obj_val(val)); return this;}
public Hash_adp_bry Add_bry_bry(byte[] key) {this.Add_base(key, key); return this;}
public Hash_adp_bry Add_str_byte(String key, byte val) {this.Add_base(Bry_.new_u8(key), Byte_obj_val.new_(val)); return this;}
public Hash_adp_bry Add_str_int(String key, int val) {this.Add_base(Bry_.new_u8(key), new Int_obj_val(val)); return this;}
public Hash_adp_bry Add_str_obj(String key, Object val) {this.Add_base(Bry_.new_u8(key), val); return this;}
public Hash_adp_bry Add_bry_obj(byte[] key, Object val) {this.Add_base(key, val); return this;}
public Hash_adp_bry Add_many_str(String... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
String itm = ary[i];
byte[] bry = Bry_.new_u8(itm);
Add_bry_bry(bry);
}
return this;
}
public Hash_adp_bry Add_many_bry(byte[]... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
Add_bry_bry(ary[i]);
return this;
}
@Override protected void Add_base(Object key, Object val) {
byte[] key_bry = (byte[])key;
Hash_adp_bry_itm_base key_itm = proto.New();
key_itm.Init(key_bry, 0, key_bry.length);
super.Add_base(key_itm, val);
}
public static Hash_adp_bry cs() {return new Hash_adp_bry(Hash_adp_bry_itm_cs.Instance);}
public static Hash_adp_bry ci_a7() {return new Hash_adp_bry(Hash_adp_bry_itm_ci_a7.Instance);}
public static Hash_adp_bry ci_u8(Gfo_case_mgr case_mgr) {return new Hash_adp_bry(Hash_adp_bry_itm_ci_u8.get_or_new(case_mgr));}
public static Hash_adp_bry c__u8(boolean case_match, Gfo_case_mgr case_mgr) {return case_match ? cs() : ci_u8(case_mgr);}
}
abstract class Hash_adp_bry_itm_base {
public abstract Hash_adp_bry_itm_base New();
public Hash_adp_bry_itm_base Init(byte[] src) {return this.Init(src, 0, src.length);}
public abstract Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end);
}
class Hash_adp_bry_itm_cs extends Hash_adp_bry_itm_base {
private byte[] src; int src_bgn, src_end;
@Override public Hash_adp_bry_itm_base New() {return new Hash_adp_bry_itm_cs();}
@Override public Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end) {this.src = src; this.src_bgn = src_bgn; this.src_end = src_end; return this;}
@Override public int hashCode() {
int rv = 0;
for (int i = src_bgn; i < src_end; i++) {
int b_int = src[i] & 0xFF; // JAVA: patch
rv = (31 * rv) + b_int;
}
return rv;
}
@Override public boolean equals(Object obj) {
if (obj == null) return false;
Hash_adp_bry_itm_cs comp = (Hash_adp_bry_itm_cs)obj;
byte[] comp_src = comp.src; int comp_bgn = comp.src_bgn, comp_end = comp.src_end;
int comp_len = comp_end - comp_bgn, src_len = src_end - src_bgn;
if (comp_len != src_len) return false;
for (int i = 0; i < comp_len; i++) {
int src_pos = src_bgn + i;
if (src_pos >= src_end) return false; // ran out of src; exit; EX: src=ab; find=abc
if (src[src_pos] != comp_src[i + comp_bgn]) return false;
}
return true;
}
public static final Hash_adp_bry_itm_cs Instance = new Hash_adp_bry_itm_cs(); Hash_adp_bry_itm_cs() {}
}
class Hash_adp_bry_itm_ci_a7 extends Hash_adp_bry_itm_base {
private byte[] src; int src_bgn, src_end;
@Override public Hash_adp_bry_itm_base New() {return new Hash_adp_bry_itm_ci_a7();}
@Override public Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end) {this.src = src; this.src_bgn = src_bgn; this.src_end = src_end; return this;}
@Override public int hashCode() {
int rv = 0;
for (int i = src_bgn; i < src_end; i++) {
int b_int = src[i] & 0xFF; // JAVA: patch
if (b_int > 64 && b_int < 91) // 64=before A; 91=after Z; NOTE: lowering upper-case on PERF assumption that there will be more lower-case letters than upper-case
b_int += 32;
rv = (31 * rv) + b_int;
}
return rv;
}
@Override public boolean equals(Object obj) {
if (obj == null) return false;
Hash_adp_bry_itm_ci_a7 comp = (Hash_adp_bry_itm_ci_a7)obj;
byte[] comp_src = comp.src; int comp_bgn = comp.src_bgn, comp_end = comp.src_end;
int comp_len = comp_end - comp_bgn, src_len = src_end - src_bgn;
if (comp_len != src_len) return false;
for (int i = 0; i < comp_len; i++) {
int src_pos = src_bgn + i;
if (src_pos >= src_end) return false; // ran out of src; exit; EX: src=ab; find=abc
byte src_byte = src[src_pos];
if (src_byte > 64 && src_byte < 91) src_byte += 32;
byte comp_byte = comp_src[i + comp_bgn];
if (comp_byte > 64 && comp_byte < 91) comp_byte += 32;
if (src_byte != comp_byte) return false;
}
return true;
}
public static final Hash_adp_bry_itm_ci_a7 Instance = new Hash_adp_bry_itm_ci_a7(); Hash_adp_bry_itm_ci_a7() {}
}
class Hash_adp_bry_itm_ci_u8 extends Hash_adp_bry_itm_base {
private final Gfo_case_mgr case_mgr;
Hash_adp_bry_itm_ci_u8(Gfo_case_mgr case_mgr) {this.case_mgr = case_mgr;}
private byte[] src; int src_bgn, src_end;
@Override public Hash_adp_bry_itm_base New() {return new Hash_adp_bry_itm_ci_u8(case_mgr);}
@Override public Hash_adp_bry_itm_base Init(byte[] src, int src_bgn, int src_end) {this.src = src; this.src_bgn = src_bgn; this.src_end = src_end; return this;}
@Override public int hashCode() {
int rv = 0;
for (int i = src_bgn; i < src_end; i++) {
byte b = src[i];
int b_int = b & 0xFF; // JAVA: patch
Gfo_case_itm itm = case_mgr.Get_or_null(b, src, i, src_end);
if (itm == null) { // unknown itm; byte is a number, symbol, or unknown; just use the existing byte
}
else { // known itm; use its hash_code
b_int = itm.Hashcode_lo();
int b_len = Utf8_.Len_of_char_by_1st_byte(b); // NOTE: must calc b_len for langs with asymmetric upper / lower; PAGE:tr.w:Zvishavane DATE:2015-09-07
i += b_len - 1;
}
rv = (31 * rv) + b_int;
}
return rv;
}
@Override public boolean equals(Object obj) {
if (obj == null) return false;
Hash_adp_bry_itm_ci_u8 trg_itm = (Hash_adp_bry_itm_ci_u8)obj;
byte[] trg = trg_itm.src; int trg_bgn = trg_itm.src_bgn, trg_end = trg_itm.src_end;
int src_c_bgn = src_bgn;
int trg_c_bgn = trg_bgn;
while ( src_c_bgn < src_end
&& trg_c_bgn < trg_end) { // exit once one goes out of bounds
byte src_c = src[src_c_bgn];
byte trg_c = trg[trg_c_bgn];
int src_c_len = Utf8_.Len_of_char_by_1st_byte(src_c);
int trg_c_len = Utf8_.Len_of_char_by_1st_byte(trg_c);
int src_c_end = src_c_bgn + src_c_len;
int trg_c_end = trg_c_bgn + trg_c_len;
Gfo_case_itm src_c_itm = case_mgr.Get_or_null(src_c, src, src_c_bgn, src_c_end);
Gfo_case_itm trg_c_itm = case_mgr.Get_or_null(trg_c, trg, trg_c_bgn, trg_c_end);
if (src_c_itm != null && trg_c_itm == null) return false; // src == ltr; trg != ltr; EX: a, 1
else if (src_c_itm == null && trg_c_itm != null) return false; // src != ltr; trg == ltr; EX: 1, a
else if (src_c_itm == null && trg_c_itm == null) { // src != ltr; trg != ltr; EX: 1, 2; _, Ⓐ
if (!Bry_.Match(src, src_c_bgn, src_c_end, trg, trg_c_bgn, trg_c_end)) return false;// syms do not match; return false;
}
else {
if (src_c_itm.Utf8_id_lo() != trg_c_itm.Utf8_id_lo()) return false; // lower-case utf8-ids don't match; return false; NOTE: using utf8-ids instead of hash-code to handle asymmetric brys; DATE:2015-09-07
}
src_c_bgn = src_c_end;
trg_c_bgn = trg_c_end;
}
return src_c_bgn == src_end && trg_c_bgn == trg_end; // only return true if both src and trg read to end of their brys, otherwise "a","ab" will match
}
public static Hash_adp_bry_itm_ci_u8 get_or_new(Gfo_case_mgr case_mgr) {
switch (case_mgr.Tid()) {
case Gfo_case_mgr_.Tid_a7: if (Itm_a7 == null) Itm_a7 = new Hash_adp_bry_itm_ci_u8(case_mgr); return Itm_a7;
case Gfo_case_mgr_.Tid_u8: if (Itm_u8 == null) Itm_u8 = new Hash_adp_bry_itm_ci_u8(case_mgr); return Itm_u8;
case Gfo_case_mgr_.Tid_custom: return new Hash_adp_bry_itm_ci_u8(case_mgr);
default: throw Err_.new_unhandled(case_mgr.Tid());
}
}
private static Hash_adp_bry_itm_ci_u8 Itm_a7, Itm_u8;
}

@ -1,246 +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;
import gplx.objects.lists.CompareAbleUtl;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.strings.AsciiByte;
public class Int_ {
// -------- BASELIB_COPY --------
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)
, Zero = 0
;
public static int Cast(Object obj) {
try {
return (Integer)obj;
}
catch(Exception exc) {
throw Err_.new_type_mismatch_w_exc(exc, int.class, obj);
}
}
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_.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 * power_of_10);
power_of_10 *= 10;
}
return rv;
}
public static int[] Log10Ary = new int[] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, Int_.Max_value};
public static int Log10AryLen = 11;
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 rv = Log10AryLen - 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 < Log10AryLen; i++) {
if (v < Log10Ary[i]) {rv = i - 1; break;}
}
return rv * sign;
}
public static int DigitCount(int v) {
int log10 = Log10(v);
return v > -1 ? log10 + 1 : log10 * -1 + 2;
}
// -------- TO_MIGRATE --------
public static int Cast_or(Object obj, int or) {
try {
return (Integer)obj;
}
catch(Exception e) {
Err_.Noop(e);
return or;
}
}
public static int Coerce(Object v) {
try {
String s = String_.as_(v);
return s == null ? Int_.Cast(v) : Int_.Parse(s);
}
catch (Exception e) {throw Err_.new_cast(e, int.class, v);}
}
public static int Parse(String raw) {try {return Integer.parseInt(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, int.class, raw);}}
public static int By_double(double v) {return (int)v;}
public static int By_hex_bry(byte[] src) {return By_hex_bry(src, 0, src.length);}
public static int By_hex_bry(byte[] src, int bgn, int end) {
int rv = 0; int factor = 1;
for (int i = end - 1; i >= bgn; i--) {
int val = By_hex_byte(src[i]);
rv += (val * factor);
factor *= 16;
}
return rv;
}
public static int By_hex_byte(byte b) {
switch (b) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
return b - AsciiByte.Num0;
case AsciiByte.Ltr_A: case AsciiByte.Ltr_B: case AsciiByte.Ltr_C: case AsciiByte.Ltr_D: case AsciiByte.Ltr_E: case AsciiByte.Ltr_F:
return b - AsciiByte.Ltr_A + 10;
case AsciiByte.Ltr_a: case AsciiByte.Ltr_b: case AsciiByte.Ltr_c: case AsciiByte.Ltr_d: case AsciiByte.Ltr_e: case AsciiByte.Ltr_f:
return b - AsciiByte.Ltr_a + 10;
default:
return -1;
}
}
public static byte[] To_bry(int v) {return Bry_.new_a7(To_str(v));}
public static String To_str_fmt(int v, String fmt) {return new java.text.DecimalFormat(fmt).format(v);}
public static String To_str_pad_bgn_space(int val, int reqd_len) {return To_str_pad(val, reqd_len, BoolUtl.Y, AsciiByte.Space);} // EX: 1, 3 returns " 1"
public static String To_str_pad_bgn_zero (int val, int reqd_len) {return To_str_pad(val, reqd_len, BoolUtl.Y, AsciiByte.Num0);} // EX: 1, 3 returns "001"
private static String To_str_pad(int val, int reqd_len, boolean bgn, byte pad_chr) {
// get val_len and pad_len; exit early, if no padding needed
int val_len = DigitCount(val);
int pad_len = reqd_len - val_len;
if (pad_len < 0)
return Int_.To_str(val);
// padding needed
Bry_bfr bfr = Bry_bfr_.New();
// handle negative numbers; EX: -1 -> "-001", not "00-1"
if (val < 0) {
bfr.Add_byte(AsciiByte.Dash);
val *= -1;
--val_len;
}
// build outpt
if (!bgn)
bfr.Add_int_fixed(val, val_len);
bfr.Add_byte_repeat(pad_chr, pad_len);
if (bgn)
bfr.Add_int_fixed(val, val_len);
return bfr.To_str();
}
public static String To_str_hex(int v) {return To_str_hex(BoolUtl.Y, BoolUtl.Y, v);}
public static String To_str_hex(boolean zero_pad, boolean upper, int v) {
String rv = Integer.toHexString(v);
int rv_len = String_.Len(rv);
if (zero_pad && rv_len < 8) rv = String_.Repeat("0", 8 - rv_len) + rv;
return upper ? String_.Upper(rv) : rv;
}
public static int Compare(int lhs, int rhs) {
if (lhs == rhs) return CompareAbleUtl.Same;
else if (lhs < rhs) return CompareAbleUtl.Less;
else return CompareAbleUtl.More;
}
public static boolean In(int v, int comp0, int comp1) {return v == comp0 || v == comp1;}
public static boolean In(int v, int... ary) {
for (int itm : ary)
if (v == itm) return true;
return false;
}
public static boolean Between(int v, int lhs, int rhs) {
int lhsCompare = v == lhs ? 0 : (v < lhs ? -1 : 1);
int rhsCompare = v == rhs ? 0 : (v < rhs ? -1 : 1);
return (lhsCompare * rhsCompare) != 1; // 1 when v is (a) greater than both or (b) less than both
}
public static boolean RangeCheck(int v, int max) {return v >= 0 && v < max;}
public static void RangeCheckOrFail_list(int v, int max, String s) {if (v < 0 || v >= max) throw Err_.new_wo_type("bounds check failed", "msg", s, "v", v, "min", 0, "max", max - 1);}
public static boolean Bounds_chk(int bgn, int end, int len) {return bgn > -1 && end < len;}
public static int BoundEnd(int v, int end) {return v >= end ? end - 1 : v;}
public static int EnsureLessThan(int v, int max) {return v >= max ? max : v;}
public static int Min(int lhs, int rhs) {return lhs < rhs ? lhs : rhs;}
public static int Max(int lhs, int rhs) {return lhs > rhs ? lhs : rhs;}
public static int Min_many(int... ary) {
int len = ary.length; if (len == 0) throw Err_.new_wo_type("Min_many requires at least 1 value");
boolean init = true;
int min = Int_.Min_value;
for (int i = 0; i < len; ++i) {
int val = ary[i];
if (init) {
min = val;
init = false;
}
else {
if (val < min)
min = val;
}
}
return min;
}
public static int Subtract_long(long lhs, long rhs) {return (int)(lhs - rhs);}
public static int Div(int v, float divisor) {return (int)((float)v / divisor);}
public static int DivAndRoundUp(int v, int divisor) {
int whole = v / divisor;
int partial = v % divisor == 0 ? 0 : 1;
return whole + partial;
}
public static int Mult(int v, float multiplier) {
float product = ((float)v * multiplier); // WORKAROUND (DotNet): (int)((float)v * multiplier) returns 0 for 100 and .01f
return (int)product;
}
}

@ -1,35 +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;
import org.junit.*;
public class Int__tst {
@Test public void XtoStr_PadBgn() {
tst_XtoStr_PadLeft_Zeroes(1 , 3, "001"); // pad
tst_XtoStr_PadLeft_Zeroes(123 , 3, "123"); // no pad
tst_XtoStr_PadLeft_Zeroes(1234 , 3, "1234"); // val exceeds pad; confirm noop
tst_XtoStr_PadLeft_Zeroes(-1 , 3, "-01"); // negative
tst_XtoStr_PadLeft_Zeroes(-12 , 3, "-12"); // negative
tst_XtoStr_PadLeft_Zeroes(-123 , 3, "-123"); // negative
tst_XtoStr_PadLeft_Zeroes(-1234 , 3, "-1234"); // negative
} void tst_XtoStr_PadLeft_Zeroes(int val, int zeros, String expd) {Tfds.Eq(expd, Int_.To_str_pad_bgn_zero(val, zeros));}
@Test public void Xto_fmt() {
tst_XtoStr_fmt(1, "1");
tst_XtoStr_fmt(1000, "1,000");
} void tst_XtoStr_fmt(int v, String expd) {Tfds.Eq(expd, Int_.To_str_fmt(v, "#,###"));}
@Test public void Xto_int_hex_tst() {
Xto_int_hex("007C", 124);
} void Xto_int_hex(String raw, int expd) {Tfds.Eq(expd, Int_.By_hex_bry(Bry_.new_a7(raw)));}
}

@ -1,173 +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;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.strings.AsciiByte;
public class Int_ary_ {//RF:DATE:2017-10-09
public static int[] Empty = new int[0];
public static int[] New(int... v) {return v;}
public static void Copy_to(int[] src, int src_len, int[] trg) {
for (int i = 0; i < src_len; ++i)
trg[i] = src[i];
}
public static int[] Mid(int[] src, int bgn, int end) {
int len = end - bgn + 1;
int[] rv = new int[len];
for (int i = 0; i < len; i++) {
rv[i] = src[i + bgn];
}
return rv;
}
public static String To_str(String spr, int... ary) {
Bry_bfr bfr = Bry_bfr_.New();
int len = ary.length;
for (int i = 0; i < len; ++i) {
if (i != 0) bfr.Add_str_u8(spr);
int itm = ary[i];
bfr.Add_int_variable(itm);
}
return bfr.To_str_and_clear();
}
public static int[] Parse(String raw, String spr) {
String[] ary = String_.Split(raw, spr);
int len = ary.length;
int[] rv = new int[len];
for (int i = 0; i < len; i++)
rv[i] = Int_.Parse(ary[i]);
return rv;
}
// parses to a reqd len; EX: "1" -> "[1, 0]"
public static int[] Parse(String raw_str, int reqd_len, int[] or) {
byte[] raw_bry = Bry_.new_a7(raw_str);
int raw_bry_len = raw_bry.length;
int[] rv = new int[reqd_len];
int cur_val = 0, cur_mult = 1, cur_idx = reqd_len - 1; boolean signed = false;
for (int i = raw_bry_len - 1; i > -2; i--) {
byte b = i == -1 ? AsciiByte.Comma : raw_bry[i];
switch (b) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
if (signed) return or;
cur_val += (b - AsciiByte.Num0) * cur_mult;
cur_mult *= 10;
break;
case AsciiByte.Space: case AsciiByte.Nl: case AsciiByte.Cr: case AsciiByte.Tab:
break;
case AsciiByte.Comma:
if (cur_idx < 0) return or;
rv[cur_idx--] = cur_val;
cur_val = 0; cur_mult = 1;
signed = false;
break;
case AsciiByte.Dash:
if (signed) return or;
cur_val *= -1;
signed = true;
break;
case AsciiByte.Plus: // noop; all values positive by default
if (signed) return or;
signed = true;
break;
default:
return or;
}
}
return cur_idx == -1 ? rv : or; // cur_idx == -1 checks for unfilled; EX: Ary_parse("1,2", 3, null) is unfilled
}
// optimizes parse
public static int[] Parse_or(byte[] src, int[] or) {
try {
if (Bry_.Len_eq_0(src)) return or; // null, "" should return [0]
int raw_len = src.length;
int[] rv = null; int rv_idx = 0, rv_len = 0;
int pos = 0;
int num_bgn = -1, num_end = -1;
boolean itm_done = false, itm_is_rng = false;
int rng_bgn = Int_.Min_value;
while (true) {
boolean pos_is_last = pos == raw_len;
if ( itm_done
|| pos_is_last
) {
if (num_bgn == -1) return or; // empty itm; EX: "1,"; "1,,2"
int num = Bry_.To_int_or(src, num_bgn, num_end, Int_.Min_value);
if (num == Int_.Min_value) return or; // not a number; parse failed
if (rv_len == 0) { // rv not init'd
rv_len = (raw_len / 2) + 1; // default rv_len to len of String / 2; + 1 to avoid fraction rounding down
rv = new int[rv_len];
}
int add_len = 1;
if (itm_is_rng) {
add_len = num - rng_bgn + List_adp_.Base1;
if (add_len == 0) return or; // bgn >= end;
}
if (add_len + rv_idx > rv_len) { // ary out of space; resize
rv_len = (add_len + rv_idx) * 2;
rv = (int[])ArrayUtl.Resize(rv, rv_len);
}
if (itm_is_rng) {
for (int i = rng_bgn; i <= num; i++)
rv[rv_idx++] = i;
}
else {
rv[rv_idx++] = num;
}
num_bgn = num_end = -1;
itm_done = itm_is_rng = false;
rng_bgn = Int_.Min_value;
if (pos_is_last) break;
}
byte b = src[pos];
switch (b) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
if (num_bgn == -1) // num_bgn not set
num_bgn = pos;
num_end = pos + 1; // num_end is always after pos; EX: "9": num_end = 1; "98,7": num_end=2
break;
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr: // NOTE: parseNumList replaces ws with '', so "1 1" will become "11"
break;
case AsciiByte.Comma:
if (pos == raw_len -1) return or; // eos; EX: "1,"
if (num_bgn == -1) return or; // empty itm; EX: ","; "1,,2"
itm_done = true;
break;
case AsciiByte.Dash:
if (pos == raw_len -1) return or; // eos; EX: "1-"
if (num_bgn == -1) return or; // no rng_bgn; EX: "-2"
rng_bgn = Bry_.To_int_or(src, num_bgn, pos, Int_.Min_value);
if (rng_bgn == Int_.Min_value) return or;
num_bgn = -1;
itm_is_rng = true;
break;
default:
return or;
}
++pos;
}
return (rv_idx == rv_len) // on the off-chance that rv_len == rv_idx; EX: "1"
? rv
: (int[])ArrayUtl.Resize(rv, rv_idx);
} catch (Exception e) {Err_.Noop(e); return or;}
}
}

@ -1,58 +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;
import org.junit.*; import gplx.core.tests.*;
public class Int_ary__tst {
private Int_ary__fxt fxt = new Int_ary__fxt();
@Test public void Parse() {
fxt.Test__Parse("1,2,3" , 3, Int_ary_.Empty, 1, 2, 3);
fxt.Test__Parse("123,321,213" , 3, Int_ary_.Empty, 123, 321, 213);
fxt.Test__Parse(" 1, 2,3" , 3, Int_ary_.Empty, 1, 2, 3);
fxt.Test__Parse("-1,+2,-3" , 3, Int_ary_.Empty, -1, 2, -3);
fxt.Test__Parse(Int_.To_str(Int_.Min_value) , 1, Int_ary_.Empty, Int_.Min_value);
fxt.Test__Parse(Int_.To_str(Int_.Max_value) , 1, Int_ary_.Empty, Int_.Max_value);
fxt.Test__Parse("1,2" , 1, Int_ary_.Empty);
fxt.Test__Parse("1" , 2, Int_ary_.Empty);
fxt.Test__Parse("a" , 1, Int_ary_.Empty);
fxt.Test__Parse("1-2," , 1, Int_ary_.Empty);
}
@Test public void Parse_list_or_() {
fxt.Test__Parse_or("1", 1);
fxt.Test__Parse_or("123", 123);
fxt.Test__Parse_or("1,2,123", 1, 2, 123);
fxt.Test__Parse_or("1,2,12,123", 1, 2, 12, 123);
fxt.Test__Parse_or("1-5", 1, 2, 3, 4, 5);
fxt.Test__Parse_or("1-1", 1);
fxt.Test__Parse_or("1-3,7,11-13,21", 1, 2, 3, 7, 11, 12, 13, 21);
fxt.Test__Parse_or__empty("1 2"); // NOTE: MW would gen 12; treat as invalid
fxt.Test__Parse_or__empty("1,"); // eos
fxt.Test__Parse_or__empty("1,,2"); // empty comma
fxt.Test__Parse_or__empty("1-"); // eos
fxt.Test__Parse_or__empty("3-1"); // bgn > end
fxt.Test__Parse_or__empty("1,a,2");
fxt.Test__Parse_or__empty("a-1,2");
fxt.Test__Parse_or__empty("-1"); // no rng bgn
}
}
class Int_ary__fxt {
public void Test__Parse_or__empty(String raw) {Tfds.Eq_ary(Int_ary_.Empty, Int_ary_.Parse_or(Bry_.new_a7(raw), Int_ary_.Empty));}
public void Test__Parse_or(String raw, int... expd) {Tfds.Eq_ary(expd, Int_ary_.Parse_or(Bry_.new_a7(raw), Int_ary_.Empty));}
public void Test__Parse(String raw, int reqd_len, int[] or, int... expd) {Gftest.Eq__ary(expd, Int_ary_.Parse(raw, reqd_len, or), "failed to parse: {0}", raw);}
}

@ -1,206 +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;
import gplx.core.ios.IoEngine;
import gplx.core.ios.IoEnginePool;
import gplx.core.ios.IoEngineUtl;
import gplx.core.ios.IoEngine_;
import gplx.core.ios.IoEngine_xrg_deleteDir;
import gplx.core.ios.IoEngine_xrg_deleteFil;
import gplx.core.ios.IoEngine_xrg_downloadFil;
import gplx.core.ios.IoEngine_xrg_loadFilStr;
import gplx.core.ios.IoEngine_xrg_openRead;
import gplx.core.ios.IoEngine_xrg_openWrite;
import gplx.core.ios.IoEngine_xrg_queryDir;
import gplx.core.ios.IoEngine_xrg_saveFilStr;
import gplx.core.ios.IoEngine_xrg_xferDir;
import gplx.core.ios.IoEngine_xrg_xferFil;
import gplx.core.ios.IoItmAttrib;
import gplx.core.ios.IoItmDir;
import gplx.core.ios.IoItmFil;
import gplx.core.ios.IoRecycleBin;
import gplx.core.ios.IoUrlInfoRegy;
import gplx.core.ios.IoUrlInfo_;
import gplx.core.ios.Io_fil;
import gplx.core.ios.atrs.Io_itm_atr_req;
import gplx.core.ios.loaders.Io_loader;
import gplx.core.ios.streams.IoStream;
import gplx.core.ios.streams.IoStream_;
import gplx.core.primitives.Int_obj_ref;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.primitives.BoolUtl;
public class Io_mgr implements Gfo_evt_mgr_owner { // exists primarily to gather all cmds under gplx namespace; otherwise need to use gplx.core.ios whenever copying/deleting file
public Io_mgr() {evt_mgr = new Gfo_evt_mgr(this);}
public Gfo_evt_mgr Evt_mgr() {return evt_mgr;} private final Gfo_evt_mgr evt_mgr;
public boolean Exists(Io_url url) {return url.Type_dir() ? ExistsDir(url) : ExistsFil(url);}
public boolean ExistsFil(Io_url url) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).ExistsFil_api(url);}
public void ExistsFilOrFail(Io_url url) {if (!ExistsFil(url)) throw Err_.new_wo_type("could not find file", "url", url);}
public void SaveFilStr(String url, String text) {SaveFilStr_args(Io_url_.new_fil_(url), text).Exec();}
public void SaveFilStr(Io_url url, String text) {SaveFilStr_args(url, text).Exec();}
public IoEngine_xrg_saveFilStr SaveFilStr_args(Io_url url, String text) {return IoEngine_xrg_saveFilStr.new_(url, text);}
public void AppendFilStr(String url, String text) {AppendFilStr(Io_url_.new_fil_(url), text);}
public void AppendFilStr(Io_url url, String text) {SaveFilStr_args(url, text).Append_(true).Exec();}
public void DeleteFil(Io_url url) {DeleteFil_args(url).Exec();}
public IoEngine_xrg_deleteFil DeleteFil_args(Io_url url) {return IoEngine_xrg_deleteFil.new_(url);}
public void MoveFil(Io_url src, Io_url trg) {IoEngine_xrg_xferFil.move_(src, trg).Exec();}
public IoEngine_xrg_xferFil MoveFil_args(Io_url src, Io_url trg, boolean overwrite) {return IoEngine_xrg_xferFil.move_(src, trg).Overwrite_(overwrite);}
public void CopyFil(Io_url src, Io_url trg, boolean overwrite) {IoEngine_xrg_xferFil.copy_(src, trg).Overwrite_(overwrite).Exec();}
public IoEngine_xrg_xferFil CopyFil_args(Io_url src, Io_url trg, boolean overwrite) {return IoEngine_xrg_xferFil.copy_(src, trg).Overwrite_(overwrite);}
public IoRecycleBin RecycleBin() {return recycleBin;} private IoRecycleBin recycleBin = IoRecycleBin.Instance;
public Io_loader Loader() {return loader;} public void Loader_(Io_loader v) {this.loader = v;} private Io_loader loader;
public IoStream OpenStreamWrite(Io_url url) {return OpenStreamWrite_args(url).Exec();}
public IoEngine_xrg_openWrite OpenStreamWrite_args(Io_url url) {return IoEngine_xrg_openWrite.new_(url);}
public IoItmFil QueryFil(Io_url url) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).QueryFil(url);}
public void UpdateFilAttrib(Io_url url, IoItmAttrib attrib) {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).UpdateFilAttrib(url, attrib);}
public void UpdateFilModifiedTime(Io_url url, DateAdp modified) {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).UpdateFilModifiedTime(url, modified);}
public boolean ExistsDir(Io_url url) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).ExistsDir(url);}
public void CreateDir(Io_url url) {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).CreateDir(url);}
public boolean CreateDirIfAbsent(Io_url url) {
boolean exists = ExistsDir(url);
if (!exists) {
CreateDir(url);
return true;
}
return false;
}
public void Create_fil_ary(Io_fil[] fil_ary) {
for (Io_fil fil : fil_ary)
SaveFilStr(fil.Url(), fil.Data());
}
public Io_url[] QueryDir_fils(Io_url dir) {return QueryDir_args(dir).ExecAsUrlAry();}
public IoEngine_xrg_queryDir QueryDir_args(Io_url dir) {return IoEngine_xrg_queryDir.new_(dir);}
public Io_itm_atr_req Query_itm_atrs(Io_url url, Io_itm_atr_req req) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).Query_itm_atrs(url, req);}
public void DeleteDirSubs(Io_url url) {IoEngine_xrg_deleteDir.new_(url).Exec();}
public IoEngine_xrg_deleteDir DeleteDir_cmd(Io_url url) {return IoEngine_xrg_deleteDir.new_(url);}
public void DeleteDirDeep(Io_url url) {IoEngine_xrg_deleteDir.new_(url).Recur_().Exec();}
public void DeleteDirDeep_ary(Io_url... urls) {for (Io_url url : urls) IoEngine_xrg_deleteDir.new_(url).Recur_().Exec();}
public int Delete_dir_empty(Io_url url) {return Io_mgr_.Delete_dir_empty(url);}
public void Delete_sub_by_wildcard() {
}
public boolean Truncate_fil(Io_url url, long size) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).Truncate_fil(url, size);}
public void MoveDirDeep(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.move_(src, trg).Recur_().Exec();}
public IoEngine_xrg_xferDir CopyDir_cmd(Io_url src, Io_url trg) {return IoEngine_xrg_xferDir.copy_(src, trg);}
public void CopyDirSubs(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.copy_(src, trg).Exec();}
public void CopyDirDeep(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.copy_(src, trg).Recur_().Exec();}
public void DeleteDirIfEmpty(Io_url url) {
if (ArrayUtl.Len(QueryDir_fils(url)) == 0)
this.DeleteDirDeep(url);
}
public void AliasDir_sysEngine(String srcRoot, String trgRoot) {AliasDir(srcRoot, trgRoot, IoEngine_.SysKey);}
public void AliasDir(String srcRoot, String trgRoot, String engineKey) {IoUrlInfoRegy.Instance.Reg(IoUrlInfo_.alias_(srcRoot, trgRoot, engineKey));}
public IoStream OpenStreamRead(Io_url url) {return OpenStreamRead_args(url).ExecAsIoStreamOrFail();}
public IoEngine_xrg_openRead OpenStreamRead_args(Io_url url) {return IoEngine_xrg_openRead.new_(url);}
public String LoadFilStr(String url) {return LoadFilStr_args(Io_url_.new_fil_(url)).Exec();}
public String LoadFilStr(Io_url url) {return LoadFilStr_args(url).Exec();}
public IoEngine_xrg_loadFilStr LoadFilStr_args(Io_url url) {return IoEngine_xrg_loadFilStr.new_(url);}
public byte[] LoadFilBryOrNull(Io_url url) {return LoadFilBryOr(url, null);}
public byte[] LoadFilBryOr(Io_url url, byte[] or) {return ExistsFil(url) ? LoadFilBry(url) : or;}
public byte[] LoadFilBry(String url) {return LoadFilBry_reuse(Io_url_.new_fil_(url), Bry_.Empty, Int_obj_ref.New_zero());}
public byte[] LoadFilBry(Io_url url) {return LoadFilBry_reuse(url, Bry_.Empty, Int_obj_ref.New_zero());}
public void LoadFilBryByBfr(Io_url url, Bry_bfr bfr) {
Int_obj_ref len = Int_obj_ref.New_zero();
byte[] bry = LoadFilBry_reuse(url, Bry_.Empty, len);
bfr.Bfr_init(bry, len.Val());
}
public static final byte[] LoadFilBry_fail = Bry_.Empty;
public byte[] LoadFilBry_reuse(Io_url url, byte[] ary, Int_obj_ref ary_len) {
if (loader != null) {
byte[] rv = loader.Load_fil_as_bry(url);
if (rv != null) return rv;
}
if (!ExistsFil(url)) {
ary_len.Val_(0);
return LoadFilBry_fail;
}
IoStream stream = IoStream_.Null;
try {
stream = OpenStreamRead(url);
int stream_len = (int)stream.Len();
ary_len.Val_(stream_len);
if (stream_len > ary.length)
ary = new byte[stream_len];
stream.ReadAry(ary);
return ary;
}
catch (Exception e) {throw Err_.new_wo_type("failed to load file", "url", url.Xto_api(), "e", Err_.Message_lang(e));}
finally {stream.Rls();}
}
public byte[] LoadFilBry_loose(Io_url url) {return Bry_.new_u8(LoadFilStr_loose(url));}
public String LoadFilStr_loose(Io_url url) {
String rv = LoadFilStr_args(url).BomUtf8Convert_(BoolUtl.Y).MissingIgnored_(BoolUtl.Y).Exec();
if (String_.Has(rv, "\r\n"))
rv = String_.Replace(rv, "\r\n", "\n");
return rv;
}
public void AppendFilBfr(Io_url url, Bry_bfr bfr) {AppendFilByt(url, bfr.Bfr(), 0, bfr.Len()); bfr.ClearAndReset();}
public void AppendFilByt(Io_url url, byte[] val) {AppendFilByt(url, val, 0, val.length);}
public void AppendFilByt(Io_url url, byte[] val, int len) {AppendFilByt(url, val, 0, len);}
public void AppendFilByt(Io_url url, byte[] val, int bgn, int len) {
IoStream stream = IoStream_.Null;
try {
stream = OpenStreamWrite_args(url).Mode_(IoStream_.Mode_wtr_append).Exec();
stream.Write(val, bgn, len);
} finally {stream.Rls();}
}
public void SaveFilBfr(Io_url url, Bry_bfr bfr) {SaveFilBry(url, bfr.Bfr(), bfr.Len()); bfr.Clear();}
public void SaveFilBry(String urlStr, byte[] val) {SaveFilBry(Io_url_.new_fil_(urlStr), val);}
public void SaveFilBry(Io_url url, byte[] val) {SaveFilBry(url, val, val.length);}
public void SaveFilBry(Io_url url, byte[] val, int len) {SaveFilBry(url, val, 0, len);}
public void SaveFilBry(Io_url url, byte[] val, int bgn, int len) {
IoStream stream = IoStream_.Null;
try {
stream = OpenStreamWrite(url);
stream.Write(val, bgn, len);
} finally {stream.Rls();}
}
public IoEngine InitEngine_mem() {return IoEngine_.Mem_init_();}
public IoEngine InitEngine_mem_(String key) {
IoEngine engine = IoEngine_.mem_new_(key);
IoEnginePool.Instance.Add_if_dupe_use_nth(engine);
IoUrlInfoRegy.Instance.Reg(IoUrlInfo_.mem_(key, key));
return engine;
}
public boolean DownloadFil(String src, Io_url trg) {return IoEngine_xrg_downloadFil.new_(src, trg).Exec();}
public IoEngine_xrg_downloadFil DownloadFil_args(String src, Io_url trg) {return IoEngine_xrg_downloadFil.new_(src, trg);}
public boolean Query_read_only(Io_url url, int read_only_type) {return IoEngineUtl.Query_read_only(IoEnginePool.Instance.Get_by(url.Info().EngineKey()), url, read_only_type);}
public static final Io_mgr Instance = new Io_mgr();
public static final int Len_kb = 1024, Len_mb = 1048576, Len_gb = 1073741824, Len_gb_2 = 2147483647;
public static final long Len_mb_long = Len_mb;
public static final long Len_null = -1;
public static final String Evt__fil_created = "fil_created";
public static final int Read_only__basic__file = 1, Read_only__basic__file_and_dirs = 2, Read_only__perms__file = 3;
}
class Io_mgr_ {
public static int Delete_dir_empty(Io_url url) {
IoItmDir dir = Io_mgr.Instance.QueryDir_args(url).ExecAsDir();
int sub_dirs_len = dir.SubDirs().Len();
int deleted_dirs = 0;
for (int i = 0; i < sub_dirs_len; ++i) {
IoItmDir sub_dir = (IoItmDir)dir.SubDirs().Get_at(i);
deleted_dirs += Io_mgr.Instance.Delete_dir_empty(sub_dir.Url());
}
if ( dir.SubFils().Len() == 0
&& deleted_dirs == sub_dirs_len
) {
Io_mgr.Instance.DeleteDirIfEmpty(url);
return 1;
}
else
return 0;
}
}

@ -1,30 +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;
public class Keyval implements To_str_able {
@gplx.Internal protected Keyval(int key_tid, Object key, Object val) {this.key_tid = key_tid; this.key = key; this.val = val;}
public String Key() {return Object_.Xto_str_strict_or_null(key);}
public Object Key_as_obj() {return key;} private Object key;
public int Key_tid() {return key_tid;} private int key_tid;
public Object Val() {return val;} private Object val;
public String Val_to_str_or_empty() {return Object_.Xto_str_strict_or_empty(val);}
public String Val_to_str_or_null() {return Object_.Xto_str_strict_or_null(val);}
public byte[] Val_to_bry() {return Bry_.new_u8(Object_.Xto_str_strict_or_null(val));}
public Keyval Key_(Object v) {this.key = v; return this;}
public Keyval Val_(Object v) {this.val = v; return this;}
public String To_str() {return Key() + "=" + Object_.Xto_str_strict_or_null_mark(val);}
@Override public String toString() {return To_str();}
}

@ -1,135 +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;
import gplx.core.strings.*;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.strings.AsciiByte;
public class Keyval_ {
public static final Keyval[] Ary_empty = new Keyval[0];
public static Keyval[] Ary(Keyval... ary) {return ary;}
public static Keyval[] Ary_cast_(Object o) {
try {return (Keyval[])o;}
catch (Exception e) {throw Err_.new_cast(e, Keyval.class, o);}
}
public static Keyval[] Ary_insert(Keyval[] orig, boolean insert_at_end, Keyval... vals) {
int orig_len = orig.length, vals_len = vals.length;
int rv_len = orig_len + vals_len;
Keyval[] rv = new Keyval[rv_len];
int vals_bgn = 0 , vals_end = vals_len;
int orig_bgn = vals_len , orig_end = rv_len;
if (insert_at_end) {
orig_bgn = 0 ; orig_end = orig_len;
vals_bgn = orig_len ; vals_end = rv_len;
}
for (int i = orig_bgn; i < orig_end; i++)
rv[i] = orig[i - orig_bgn];
for (int i = vals_bgn; i < vals_end; i++)
rv[i] = vals[i - vals_bgn];
return rv;
}
public static String Ary_to_str(Keyval... ary) {
String_bldr sb = String_bldr_.new_();
int len = ary.length;
for (int i = 0; i < len; i++) {
Keyval itm = ary[i];
if (itm == null) {
sb.Add("<<NULL>>");
continue;
}
sb.Add(itm.Key()).Add("=");
Object itm_val = itm.Val();
if (Type_.Eq_by_obj(itm_val, Keyval[].class))
sb.Add(Ary_to_str((Keyval[])itm_val));
else
sb.Add(Object_.Xto_str_strict_or_null_mark(itm_val));
sb.Add_char_nl();
}
return sb.To_str();
}
public static Object Ary_get_by_key_or_null(Keyval[] ary, String key) {
int len = ary.length;
for (int i = 0; i < len; i++) {
Keyval kv = ary[i];
if (String_.Eq(kv.Key(), key)) return kv.Val();
}
return null;
}
public static String Ary__to_str__nest(Keyval... ary) {
Bry_bfr bfr = Bry_bfr_.New();
Ary__to_str__nest__ary(bfr, 0, true, ary);
return bfr.To_str_and_clear();
}
public static Object[] Ary__to_objary__val(Keyval[] ary) {
int ary_len = ary.length;
Object[] rv = new Object[ary_len];
for (int i = 0; i < ary_len; i++) {
rv[i] = ary[i].Val();
}
return rv;
}
private static void Ary__to_str__nest__ary(Bry_bfr bfr, int indent, boolean is_kv, Object[] ary) {
int len = ary.length;
for (int i = 0; i < len; ++i) {
Ary__to_str__nest__val(bfr, indent, is_kv, i, ary[i]);
}
}
private static void Ary__to_str__nest__val(Bry_bfr bfr, int indent, boolean is_kv, int idx, Object val) {
if (indent > 0)
bfr.Add_byte_repeat(AsciiByte.Space, indent * 2); // add indent; EX: " "
String key = null;
if (is_kv) {
Keyval kv = (Keyval)val;
key = Object_.Xto_str_strict_or_empty(kv.Key());
val = kv.Val();
}
else {
key = Int_.To_str(idx + 1);
}
bfr.Add_str_u8(key).Add_byte_eq(); // add key + eq : "key="
if (val == null)
bfr.Add_str_a7(String_.Null_mark);
else {
Class<?> val_type = Type_.Type_by_obj(val);
if (Type_.Eq(val_type, Keyval[].class)) { // val is Keyval[]; recurse
bfr.Add_byte_nl(); // add nl: "\n"
Ary__to_str__nest__ary(bfr, indent + 1, true, (Keyval[])val);
return; // don't add \n below
}
else if (Type_.Eq(val_type, Keyval.class)) { // val is Keyval; recurse
bfr.Add_byte_nl(); // add nl: "\n"
Ary__to_str__nest__val(bfr, indent + 1, true, 1, (Keyval)val);
return; // don't add \n below
}
else if (Type_.Eq(val_type, Object[].class)) { // val is Object[]
bfr.Add_byte_nl();
Ary__to_str__nest__ary(bfr, indent + 1, false, (Object[])val);
return; // don't add \n below
}
else if (Type_.Eq(val_type, BoolUtl.ClsRefType)) { // val is boolean
boolean val_as_bool = BoolUtl.Cast(val);
bfr.Add(val_as_bool ? BoolUtl.TrueBry : BoolUtl.FalseBry); // add "true" or "false"; don't call toString
}
else
bfr.Add_str_u8(Object_.Xto_str_strict_or_null_mark(val)); // call toString()
}
bfr.Add_byte_nl();
}
public static Keyval as_(Object obj) {return obj instanceof Keyval ? (Keyval)obj : null;}
public static Keyval new_(String key) {return new Keyval(Type_ids_.Id__str, key, key);}
public static Keyval new_(String key, Object val) {return new Keyval(Type_ids_.Id__str, key, val);}
public static Keyval int_(int key, Object val) {return new Keyval(Type_ids_.Id__int, key, val);}
public static Keyval obj_(Object key, Object val) {return new Keyval(Type_ids_.Id__obj, key, val);}
}

@ -1,40 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx;
public class Keyval_hash {
private final Ordered_hash hash = Ordered_hash_.New();
public int Count() {return hash.Len();}
public int Len() {return hash.Len();}
public Keyval_hash Clear() {hash.Clear(); return this;}
public boolean Has(String key) {return hash.Has(key);}
public Keyval Get_at(int i) {return (Keyval)hash.Get_at(i);}
public Object Get_val_or(String key, Object or) {Keyval rv = Get_kvp_or_null(key); return rv == null ? or : rv.Val();}
public Object Get_val_or_null(String key) {return Get_val_or(key, null);}
public Object Get_val_or_fail(String key) {return Keyval_.as_(hash.GetByOrFail(key)).Val();}
public String Get_val_as_str_or_fail(String key) {return (String)Get_val_or_fail(key);}
public Keyval Get_kvp_or_null(String key) {return Keyval_.as_(hash.GetByOrNull(key));}
public Keyval_hash Add(Keyval kv) {hash.Add(kv.Key(), kv); return this;}
public Keyval_hash Add(String key, Object val) {hash.Add(key, Keyval_.new_(key, val)); return this;}
public Keyval_hash Add_if_dupe_use_nth(String key, Object val) {hash.AddIfDupeUseNth(key, Keyval_.new_(key, val)); return this;}
public void Del(String key) {hash.Del(key);}
public Keyval[] To_ary() {
int len = this.Count();
Keyval[] rv = new Keyval[len];
for (int i = 0; i < len; ++i)
rv[i] = this.Get_at(i);
return rv;
}
}

@ -1,34 +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;
public class Keyval_list {
public int Count() {return list.Len();} private final List_adp list = List_adp_.New();
public void Clear() {list.Clear();}
public Keyval Get_at(int i) {return (Keyval)list.Get_at(i);}
public Keyval_list Add(String key, Object val) {list.Add(Keyval_.new_(key, val)); return this;}
public Keyval[] To_ary() {return (Keyval[])list.ToAry(Keyval.class);}
public String To_str() {
Bry_bfr bfr = Bry_bfr_.New();
int len = list.Len();
for (int i = 0; i < len; ++i) {
Keyval kv = (Keyval)list.Get_at(i);
if (i == 0) bfr.Add_byte_space();
bfr.Add_str_u8(kv.Key()).Add_byte_eq().Add_str_u8(kv.Val_to_str_or_empty());
}
return bfr.To_str_and_clear();
}
public static Keyval_list New_with_one(String key, Object val) {return new Keyval_list().Add(key, val);}
}

@ -1,111 +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;
import gplx.objects.lists.CompareAbleUtl;
public class Long_ {
public static final String Cls_val_name = "long";
public static final Class<?> Cls_ref_type = Long.class;
public static final int Log10Ary_len = 21;
public static long[] Log10Ary = new long[]
{ 1, 10, 100, 1000, 10000
, 100000, 1000000, 10000000, 100000000, 1000000000
, Long_.Pow(10, 10), Long_.Pow(10, 11), Long_.Pow(10, 12), Long_.Pow(10, 13), Long_.Pow(10, 14)
, Long_.Pow(10, 15), Long_.Pow(10, 16), Long_.Pow(10, 17), Long_.Pow(10, 18), Long_.Pow(10, 19)
, Long_.Max_value
};
public static long parse(String raw) {try {return Long.parseLong(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, long.class, raw);}}
public static long cast(Object obj) {try {return (Long)obj;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, long.class, obj);}}
public static long coerce_(Object v) {
try {String s = String_.as_(v); return s == null ? Long_.cast(v) : Long_.parse(s);}
catch (Exception e) {throw Err_.new_cast(e, long.class, v);}
}
public static String To_str(long v) {return Long.toString(v);}
public static String To_str_PadBgn(long v, int reqdPlaces) {return String_.Pad(To_str(v), reqdPlaces, "0", true);} // ex: 1, 3 returns 001
public static long parse_or(String raw, long or) {
if (raw == null) return or;
try {
int rawLen = String_.Len(raw);
if (raw == null || rawLen == 0) return or;
long rv = 0, factor = 1; int tmp = 0;
for (int i = rawLen; i > 0; i--) {
tmp = Char_.To_digit_or(String_.CharAt(raw, i - 1), Int_.Min_value);
if (tmp == Int_.Min_value) return or;
rv += (tmp * factor);
factor *= 10;
}
return rv;
} catch (Exception e) {Err_.Noop(e); return or;}
}
public static int Compare(long lhs, long rhs) {
if (lhs == rhs) return CompareAbleUtl.Same;
else if (lhs < rhs) return CompareAbleUtl.Less;
else return CompareAbleUtl.More;
}
private static int FindIdx(long[] ary, long find_val) {
int ary_len = ary.length;
int adj = 1;
int prv_pos = 0;
int prv_len = ary_len;
int cur_len = 0;
int cur_idx = 0;
long cur_val = 0;
while (true) {
cur_len = prv_len / 2;
if (prv_len % 2 == 1) ++cur_len;
cur_idx = prv_pos + (cur_len * adj);
if (cur_idx < 0) cur_idx = 0;
else if (cur_idx >= ary_len) cur_idx = ary_len - 1;
cur_val = ary[cur_idx];
if (find_val < cur_val) adj = -1;
else if (find_val > cur_val) adj = 1;
else if (find_val == cur_val) return cur_idx;
if (cur_len == 1) {
if (adj == -1 && cur_idx > 0)
return --cur_idx;
return cur_idx;
}
prv_len = cur_len;
prv_pos = cur_idx;
}
}
public static int DigitCount(long v) {
int adj = Int_.Base1;
if (v < 0) {
if (v == Long_.Min_value) return 19; // NOTE: Long_.Min_value * -1 = Long_.Min_value
v *= -1;
++adj;
}
return FindIdx(Log10Ary, v) + adj;
}
public static long Pow(int val, int exp) {
long rv = val;
for (int i = 1; i < exp; i++)
rv *= val;
return rv;
}
public static long Int_merge(int hi, int lo) {return (long)hi << 32 | (lo & 0xFFFFFFFFL);}
public static int Int_split_lo(long v) {return (int)(v);}
public static int Int_split_hi(long v) {return (int)(v >> 32);}
public static final long
Min_value = Long.MIN_VALUE
, Max_value = Long.MAX_VALUE
;
}
/* alternate for Int_merge; does not work in java
public static long MergeInts(int lo, int hi) {return (uint)(hi << 32) | (lo & 0xffffffff);}
public static int SplitLo(long v) {return (int)(((ulong)v & 0x00000000ffffffff));}
public static int SplitHi(long v) {return (int)(((ulong)v & 0xffffffff00000000)) >> 32;}
*/

@ -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;
import org.junit.*;
public class Long__tst {
@Test public void DigitCount() {
tst_DigitCount(0, 1);
tst_DigitCount(1, 1);
tst_DigitCount(9, 1);
tst_DigitCount(10, 2);
tst_DigitCount(100, 3);
tst_DigitCount(10000, 5);
tst_DigitCount(100000, 6);
tst_DigitCount(1000000, 7);
tst_DigitCount(1000000000, 10);
tst_DigitCount(10000000000L, 11);
tst_DigitCount(100000000000L, 12);
tst_DigitCount(10000000000000000L, 17);
tst_DigitCount(-1, 2);
} void tst_DigitCount(long val, int expd) {Tfds.Eq(expd, Long_.DigitCount(val));}
@Test public void Int_merge() {
tst_Int_merge(123, 456, 528280977864L);
tst_Int_merge(123, 457, 528280977865L);
}
void tst_Int_merge(int hi, int lo, long expd) {
Tfds.Eq(expd, Long_.Int_merge(hi, lo));
Tfds.Eq(hi, Long_.Int_split_hi(expd));
Tfds.Eq(lo, Long_.Int_split_lo(expd));
}
@Test public void parse_or() {
parse_or_tst("10000000000", 10000000000L);
}
void parse_or_tst(String raw, long expd) {Tfds.Eq(expd, Long_.parse_or(raw, -1));}
}

@ -1,73 +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;
public class Math_ {
public static double Pow(double val, double exponent) {return java.lang.Math.pow(val, exponent);}
public static int Pow_int(int val, int exponent) {return (int)java.lang.Math.pow(val, exponent);}
public static double Pi = java.lang.Math.PI;
public static double E = java.lang.Math.E;
public static int Ceil_as_int(double v) {return (int)Ceil(v);}
public static double Ceil(double v) {return java.lang.Math.ceil(v);}
public static int Floor_as_int(double v) {return (int)Floor(v);}
public static double Floor(double v) {return java.lang.Math.floor(v);}
public static double Round(double v, int places) {
return java.math.BigDecimal.valueOf(v).setScale(places, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static int Trunc(double v) {return (int)v;}
public static double Exp(double v) {return java.lang.Math.exp(v);}
public static double Log(double v) {return java.lang.Math.log(v);}
public static double Sin(double v) {return java.lang.Math.sin(v);}
public static double Cos(double v) {return java.lang.Math.cos(v);}
public static double Tan(double v) {return java.lang.Math.tan(v);}
public static double Asin(double v) {return java.lang.Math.asin(v);}
public static double Acos(double v) {return java.lang.Math.acos(v);}
public static double Atan(double v) {return java.lang.Math.atan(v);}
public static double Sqrt(double v) {return java.lang.Math.sqrt(v);}
public static int Abs(int val) {return val > 0 ? val : val * -1;}
public static long Abs(long val) {return val > 0 ? val : val * -1;}
public static float Abs(float val) {return val > 0 ? val : val * -1;}
public static double Abs_double(double val) {return val > 0 ? val : val * -1;}
public static int Log10(int val) {
if (val <= 0) return Int_.Min_value;
int rv = -1, baseVal = 10;
while (val != 0) {
val = (val / baseVal);
rv++;
}
return rv;
}
public static int Div_safe_as_int(int val, int divisor) {return divisor == 0 ? 0 : val / divisor;}
public static long Div_safe_as_long(long val, long divisor) {return divisor == 0 ? 0 : val / divisor;}
public static double Div_safe_as_double(double val, double divisor) {return divisor == 0 ? 0 : val / divisor;}
public static int Min(int val0, int val1) {return val0 < val1 ? val0 : val1;}
public static int Max(int val0, int val1) {return val0 > val1 ? val0 : val1;}
public static int[] Base2Ary(int v, int max) {
int[] idxs = new int[32];
int cur = v, mult = max, idx = 0;
while (mult > 0) {
int tmp = cur / mult;
if (tmp >= 1) {
idxs[idx++] = mult;
cur -= mult;
}
mult /= 2;
}
int[] rv = new int[idx];
for (int i = 0; i < idx; i++)
rv[i] = idxs[idx - i - 1];
return rv;
}
}

@ -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;
import org.junit.*;
public class Math__tst {
@Test public void Abs() {
tst_Abs(1, 1);
tst_Abs(-1, 1);
tst_Abs(0, 0);
} void tst_Abs(int val, int expd) {Tfds.Eq(expd, Math_.Abs(val));}
@Test public void Log10() {
tst_Log10(0, Int_.Min_value);
tst_Log10(9, 0);
tst_Log10(10, 1);
tst_Log10(99, 1);
tst_Log10(100, 2);
} void tst_Log10(int val, int expd) {Tfds.Eq(expd, Math_.Log10(val));}
@Test public void Min() {
tst_Min(0, 1, 0);
tst_Min(1, 0, 0);
tst_Min(0, 0, 0);
} void tst_Min(int val0, int val1, int expd) {Tfds.Eq(expd, Math_.Min(val0, val1));}
@Test public void Pow() {
tst_Pow(2, 0, 1);
tst_Pow(2, 1, 2);
tst_Pow(2, 2, 4);
} void tst_Pow(int val, int exponent, double expd) {Tfds.Eq(expd, Math_.Pow(val, exponent));}
@Test public void Mult() {
tst_Mult(100, .01f, 1);
} void tst_Mult(int val, float multiplier, int expd) {Tfds.Eq(expd, Int_.Mult(val, multiplier));}
@Test public void Base2Ary() {
tst_Base2Ary( 1, 256, 1);
tst_Base2Ary( 2, 256, 2);
tst_Base2Ary( 3, 256, 1, 2);
tst_Base2Ary( 4, 256, 4);
tst_Base2Ary( 5, 256, 1, 4);
tst_Base2Ary( 6, 256, 2, 4);
tst_Base2Ary(511, 256, 1, 2, 4, 8, 16, 32, 64, 128, 256);
} void tst_Base2Ary(int v, int max, int... expd) {Tfds.Eq_ary(expd, Math_.Base2Ary(v, max));}
@Test public void Round() {
tst_Round(1.5 , 0, 2);
tst_Round(2.5 , 0, 3);
tst_Round(2.123 , 2, 2.12);
tst_Round(21.1 , -1, 20);
} void tst_Round(double v, int places, double expd) {Tfds.Eq(expd, Math_.Round(v, places));}
}

@ -1,34 +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;
public class ObjAry {
public Object[] Ary() {return ary;} Object[] ary;
public Object Get(int i) {return ary[i];}
public Object Get0() {return ary[0];}
public Object Get1() {return ary[1];}
public static ObjAry pair_(Object val0, Object val1) {
ObjAry rv = new ObjAry();
rv.ary = new Object[2];
rv.ary[0] = val0;
rv.ary[1] = val1;
return rv;
} ObjAry() {}
public static ObjAry many_(Object... ary) {
ObjAry rv = new ObjAry();
rv.ary = ary;
return rv;
}
}

@ -1,69 +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;
import gplx.objects.primitives.BoolUtl;
public class Object_ {
public static final String Cls_val_name = "Object";
public static final Object[] Ary_empty = new Object[0];
public static Object[] Ary(Object... ary) {return ary;}
public static Object[] Ary_add(Object[] lhs, Object[] rhs) {
int lhs_len = lhs.length, rhs_len = rhs.length;
if (lhs_len == 0) return rhs;
else if (rhs_len == 0) return lhs;
int rv_len = lhs_len + rhs_len;
Object[] rv = new Object[rv_len];
for (int i = 0; i < lhs_len; ++i)
rv[i] = lhs[i];
for (int i = lhs_len; i < rv_len; ++i)
rv[i] = rhs[i - lhs_len];
return rv;
}
public static Object[] Ary_add_one(Object[] lhs, Object rhs) {
int lhs_len = lhs.length, rhs_len = 1;
int rv_len = lhs_len + rhs_len;
Object[] rv = new Object[rv_len];
for (int i = 0; i < lhs_len; ++i)
rv[i] = lhs[i];
rv[rv_len - 1] = rhs;
return rv;
}
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);
}
public static String Xto_str_or(Object v, String or) {return v == null ? or : ToString_lang(v);}
public static String Xto_str_strict_or_null(Object v) {return v == null ? null : ToString_lang(v);}
public static String Xto_str_strict_or_null_mark(Object v) {return v == null ? String_.Null_mark : ToString_lang(v);}
public static String Xto_str_strict_or_empty(Object v) {return v == null ? String_.Empty : ToString_lang(v);}
private static String ToString_lang(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_u8((byte[])v);
else return v.toString();
}
public static String Xto_str_loose_or(Object v, String or) { // tries to pretty-print doubles; also standardizes true/false; DATE:2014-07-14
if (v == null) return null;
Class<?> c = Type_.Type_by_obj(v);
if (Type_.Eq(c, String_.Cls_ref_type)) return (String)v;
else if (Type_.Eq(c, Bry_.Cls_ref_type)) return String_.new_u8((byte[])v);
else if (Type_.Eq(c, BoolUtl.ClsRefType)) return BoolUtl.Cast(v) ? BoolUtl.TrueStr : BoolUtl.FalseStr; // always return "true" / "false"
else if (Type_.Eq(c, Double_.Cls_ref_type)) return Double_.To_str_loose(Double_.cast(v));
else return v.toString();
}
public static final Object Null = null;
public static final byte[] Bry__null = Bry_.new_a7("null");
}

@ -1,34 +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;
import org.junit.*;
public class Object__Utl__tst {
@Before public void init() {} private Object__fxt fxt = new Object__fxt();
@Test public void Eq() {
fxt.Test_eq(null, null, true); // both null
fxt.Test_eq(5, 5, true); // both non-null
fxt.Test_eq(5, null, false); // rhs non-null
fxt.Test_eq(null, 5, false); // lhs non-null
}
@Test public void Xto_str_loose_or_null() {
fxt.Test_xto_str_loose_or_null(null, null);
fxt.Test_xto_str_loose_or_null(2449.6000000000004d, "2449.6");
}
}
class Object__fxt {
public void Test_eq(Object lhs, Object rhs, boolean expd) {Tfds.Eq(expd, Object_.Eq(lhs, rhs));}
public void Test_xto_str_loose_or_null(Object v, String expd) {Tfds.Eq(expd, Object_.Xto_str_loose_or(v, null));}
}

@ -1,28 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx;
import gplx.core.primitives.*;
public class Ordered_hash_ {
public static Ordered_hash New() {return new Ordered_hash_base();}
public static Ordered_hash New_bry() {return new Ordered_hash_bry();}
}
class Ordered_hash_bry extends Ordered_hash_base {
private final Bry_obj_ref tmp_ref = Bry_obj_ref.New_empty();
@Override protected void Add_base(Object key, Object val) {super.Add_base(Bry_obj_ref.New((byte[])key), val);}
@Override protected void Del_base(Object key) {synchronized (tmp_ref) {super.Del_base(tmp_ref.Val_((byte[])key));}}
@Override protected boolean Has_base(Object key) {synchronized (tmp_ref) {return super.Has_base(tmp_ref.Val_((byte[])key));}}
@Override protected Object Fetch_base(Object key) {synchronized (tmp_ref) {return super.Fetch_base(tmp_ref.Val_((byte[])key));}}
}

@ -1,28 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx;
import java.util.*;
public class RandomAdp_ implements Gfo_invk {
public static RandomAdp new_() {
Random random = new Random(System.currentTimeMillis());
return new RandomAdp(random);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_Next)) return RandomAdp_.new_().Next(m.ReadInt("max"));
else return Gfo_invk_.Rv_unhandled;
} static final String Invk_Next = "Next";
public static final RandomAdp_ Gfs = new RandomAdp_();
}

@ -1,23 +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;
public class Short_ {
public static final String Cls_val_name = "short";
public static final Class<?> Cls_ref_type = Short.class;
public static short cast(Object obj) {try {return (Short)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, short.class, obj);}}
public static short By_int(int v) {return (short)v;}
}

@ -1,559 +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;
import gplx.core.envs.Op_sys;
import gplx.core.strings.String_bldr;
import gplx.core.strings.String_bldr_;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.lists.CompareAbleUtl;
public class String_ {
// -------- BASELIB_COPY --------
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", Nl = "\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);}
public static String new_u8(byte[] v) {return v == null ? null : new_u8(v, 0, v.length);}
public static String new_u8(byte[] v, int bgn, int end) {
try {
return v == null
? null
: new String(v, bgn, end - bgn, "UTF-8");
}
catch (Exception e) {Err_.Noop(e); throw Err_.new_("core", "unsupported encoding", "bgn", bgn, "end", end);}
}
// 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 = ArrayUtl.LenObjAry(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_bldr bfr = String_bldr_.new_();
while (pos < fmt_len) { // loop over every char; NOTE: UT8-SAFE b/c only checking for "{"; "}"
char c = CharAt(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(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_.Xto_str_strict_or_empty(args[args_idx]) // valid; add itm
: String_.Concat_any(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(c);
else {
char next = CharAt(fmt, pos + 1);
if (next == c) { // "{{" or "}}": escape by doubling
bfr.Add(c);
pos++;
}
else
inside_brackets = true;
}
}
else
bfr.Add(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(FORMAT_ITM_LHS).Add(arg_idx_str);
return bfr.To_str();
}
// -------- TO_MIGRATE --------
public static String cast(Object v) {return (String)v;}
public static String as_(Object obj) {return obj instanceof String ? (String)obj : null;}
public static String new_a7(byte[] v) {return v == null ? null : new_a7(v, 0, v.length);}
public static String new_a7(byte[] v, int bgn, int end) {
try {
return v == null
? null
: new String(v, bgn, end - bgn, "ASCII");
}
catch (Exception e) {throw Err_.new_exc(e, "core", "unsupported encoding");}
}
public static String new_u8__by_len(byte[] v, int bgn, int len) {
int v_len = v.length;
if (bgn + len > v_len) len = v_len - bgn;
return new_u8(v, bgn, bgn + len);
}
public static String[] Ary_add(String[]... arys) {
if (arys == null) return String_.Ary_empty;
int arys_len = arys.length;
int rv_len = 0;
for (int i = 0; i < arys_len; i++) {
String[] ary = arys[i];
rv_len += ary.length;
}
int rv_idx = 0;
String[] rv = new String[rv_len];
for (int i = 0; i < arys_len; i++) {
String[] ary = arys[i];
int ary_len = ary.length;
for (int j = 0; j < ary_len; j++)
rv[rv_idx++] = ary[j];
}
return rv;
}
public static boolean Len_gt_0(String s) {return s != null && s.length() > 0;}
public static boolean Len_eq_0(String s) {return s == null || s.length() == 0;}
public static String Lower(String s) {return s.toLowerCase();}
public static String Upper(String s) {return s.toUpperCase();}
public static String CaseNormalize(boolean caseSensitive, String s) {return caseSensitive ? s : String_.Lower(s);}
public static String Trim(String s) {return s.trim();}
public static String Mid(String s, int bgn) {return s.substring(bgn);}
public static String Replace(String s, String find, String replace) {return s.replace(find, replace);}
public static char[] XtoCharAry(String s) {return s.toCharArray();}
public static int CodePointAt(String s, int i) {return s.codePointAt(i);}
public static boolean Has(String s, String find) {return s.indexOf(find) != String_.Find_none;}
public static boolean Has_at_bgn(String s, String v) {return s.startsWith(v);}
public static boolean Has_at_end(String s, String v) {return s.endsWith(v);}
public static int FindFwd(String s, String find) {return s.indexOf(find);}
public static int FindFwd(String s, String find, int pos) {return s.indexOf(find, pos);}
public static int FindFwd(String s, String find, int bgn, int end) {
int rv = FindFwd(s, find, bgn);
return rv > end ? String_.Find_none : rv;
}
public static int FindBwdOr(String s, String find, int or) {int pos = FindBwd(s, find); return pos == Pos_neg1 ? or : pos;}
public static int FindBwd(String s, String find) {return s.lastIndexOf(find);}
public static int FindBwd(String s, String find, int pos) {return s.lastIndexOf(find, pos);}
public static int FindBetween(String s, String find, int bgn, int end) {
int rv = FindFwd(s, find, bgn);
return (rv > end) ? String_.Find_none : rv;
}
public static int FindAfter(String s, String find, int bgn) {
int rv = FindFwd(s, find, bgn);
return rv == String_.Find_none ? String_.Find_none : rv + Len(find);
}
public static int FindAfterRev(String s, String find, int pos) {
int rv = FindBwd(s, find, pos);
return rv == String_.Find_none ? String_.Find_none : rv + Len(find);
}
public static int Count(String s, String part) {
int count = 0, pos = -1; // -1 b/c first pass must be 0 (see pos + 1 below)
do {
pos = FindFwd(s, part, pos + 1);
if (pos == String_.Find_none) break;
count++;
} while (true);
return count;
}
public static boolean EqAny(String lhs, String... rhsAry) {
for (int i = 0; i < rhsAry.length; i++)
if (Eq(lhs, rhsAry[i])) return true;
return false;
}
public static boolean EqNot(String lhs, String rhs) {return !Object_.Eq(lhs, rhs);}
public static boolean EqEmpty(String lhs) {return lhs.equals("");}
public static String IfNullOrEmpty(String s, String or) {return s == null || s.length() == 0 ? or : s;}
public static int Compare_as_ordinals(String lhs, String rhs) {return lhs.compareTo(rhs);}
public static int Compare_ignoreCase(String lhs, String rhs) {
if (lhs == null && rhs != null) return CompareAbleUtl.Less;
else if (lhs != null && rhs == null) return CompareAbleUtl.More;
else if (lhs == null && rhs == null) return CompareAbleUtl.Same;
else return lhs.compareToIgnoreCase(rhs);
//#-
/*
if (lhs == null && rhs != null) return CompareAble_.Less;
else if (lhs != null && rhs == null) return CompareAble_.More;
else if (lhs == null && rhs == null) return CompareAble_.Same;
else return lhs.compareToIgnoreCase(rhs);
*/
}
public static int Compare(String lhs, String rhs) {
int compare = lhs.compareTo(rhs);
if (compare == CompareAbleUtl.Same) return CompareAbleUtl.Same;
else if (compare < CompareAbleUtl.Same) return CompareAbleUtl.Less;
else /* (compare > CompareAble_.Same) */ return CompareAbleUtl.More;
}
public static int Compare_byteAry(String lhs, String rhs) {
int lhsLen = lhs.length(), rhsLen = rhs.length();
int aryLen = lhsLen < rhsLen ? lhsLen : rhsLen;
int[] lhsAry = XtoIntAry(lhs, aryLen), rhsAry = XtoIntAry(rhs, aryLen);
for (int i = 0; i < aryLen; i++) {
int comp = Int_.Compare(lhsAry[i], rhsAry[i]);
if (comp != CompareAbleUtl.Same) return comp;
}
return Int_.Compare(lhsLen, rhsLen);
}
public static int[] XtoIntAry(String s, int len) {
int[] rv = new int[len];
for (int i = 0; i < len; i++)
rv[i] = (int)s.charAt(i);
return rv;
}
public static String Coalesce(String s, String alt) {return Len_eq_0(s) ? alt : s;}
public static boolean In(String s, String... ary) {
for (String itm : ary)
if (String_.Eq(s, itm)) return true;
return false;
}
public static String new_charAry_(char[] ary, int bgn, int len) {return new String(ary, bgn, len);}
public static String Mid(String s, int bgn, int end) {
try {return Mid_lang(s, bgn, end - bgn);}
catch (Exception e) {
int len = s == null ? 0 : Len(s);
String msg = "";
if (s == null) msg = "s is null";
else if (bgn > end) msg = "@bgn > @end";
else if (bgn < 0 || bgn >= len) msg = "@bgn is invalid";
else if (end < 0 || end > len) msg = "@end is invalid";
throw Err_.new_exc(e, "core", msg, "s", s, "bgn", bgn, "end", end, "len", len);
}
}
public static String MidByLenSafe(String s, int bgn, int len) {
if (bgn + len >= Len(s)) len = Len(s) - bgn;
return Mid_lang(s, bgn, len);
}
public static String MidByLen(String s, int bgn, int len) {return Mid_lang(s, bgn, len);}
public static String GetStrBefore(String s, String spr) {
int sprPos = String_.FindFwd(s, spr); if (sprPos == String_.Find_none) throw Err_.new_wo_type("could not find spr", "s", s, "spr", spr);
return Mid(s, 0, sprPos);
}
public static String GetStrAfter(String s, String spr) {
int sprPos = String_.FindFwd(s, spr); if (sprPos == String_.Find_none) throw Err_.new_wo_type("could not find spr", "s", s, "spr", spr);
return Mid(s, sprPos + 1);
}
public static String LimitToFirst(String s, int len) {
if (len < 0) throw Err_.new_invalid_arg("< 0", "len", len);
int sLen = Len(s); if (len > sLen) return s;
return Mid_lang(s, 0, len);
}
public static String LimitToLast(String s, int len) {
if (len < 0) throw Err_.new_invalid_arg("< 0", "len", len);
int sLen = Len(s); if (len > sLen) return s;
return Mid_lang(s, sLen - len, len);
}
public static String DelBgn(String s, int count) {
if (count < 0) throw Err_.new_invalid_arg("< 0", "count", count);
if (s == null) throw Err_.new_null();
int len = Len(s); if (count > len) throw Err_.new_invalid_arg("> @len", "count", count, "len", len);
return String_.Mid(s, count);
}
public static String DelBgnIf(String s, String find) {
if (s == null) throw Err_.new_null();
if (find == null) throw Err_.new_null();
return Has_at_bgn(s, find) ? String_.Mid(s, Len(find)) : s;
}
public static String DelEnd(String s, int count) {
if (count < 0) throw Err_.new_invalid_arg("< 0", "count", count);
if (s == null) throw Err_.new_null();
int len = Len(s); if (count > len) throw Err_.new_invalid_arg("> len", "count", count, "len", len);
return Mid_lang(s, 0, len + -count);
}
public static String DelEndIf(String s, String find) {
if (s == null) throw Err_.new_null();
if (find == null) throw Err_.new_null();
return Has_at_end(s, find) ? Mid_lang(s, 0, Len(s) - Len(find)) : s;
}
public static String LowerFirst(String s) {
int len = Len(s); if (len == 0) return String_.Empty;
String char0 = Lower(Mid_lang(s, 0, 1));
return len == 1 ? char0 : char0 + Mid(s, 1);
}
public static String UpperFirst(String s) {
int len = Len(s); if (len == 0) return String_.Empty;
String char0 = Upper(Mid_lang(s, 0, 1));
return len == 1 ? char0 : char0 + Mid(s, 1);
}
public static String PadBgn(String s, int totalLen, String pad) {return Pad(s, totalLen, pad, true);}
public static String PadEnd(String s, int totalLen, String pad) {return Pad(s, totalLen, pad, false);}
@gplx.Internal protected static String Pad(String s, int totalLen, String pad, boolean bgn) {
int sLen = Len(s);
int padLen = totalLen - sLen; if (padLen < 0) return s;
String_bldr sb = String_bldr_.new_();
if (!bgn) sb.Add(s);
for (int i = 0; i < padLen; i++)
sb.Add(pad);
if (bgn) sb.Add(s);
return sb.To_str();
}
public static String TrimEnd(String s) {if (s == null) return null;
int len = String_.Len(s);
if (len == 0) return s;
int last = len;
for (int i = len; i > 0; i--) {
char c = s.charAt(i - 1);
last = i;
if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
break;
}
}
return (last == len) ? s : Mid_lang(s, 0, last);
}
public static String Repeat(String s, int count) {
if (count < 0) throw Err_.new_wo_type("count cannot be negative", "count", count, "s", s);
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < count; i++)
sb.Add(s);
return sb.To_str();
}
public static String Insert(String s, int pos, String toInsert) {
if (pos < 0 || pos >= String_.Len(s)) throw Err_.new_wo_type("String_.Insert failed; pos invalid", "pos", pos, "s", s, "toInsert", toInsert);
return s.substring(0, pos) + toInsert + s.substring(pos);
}
public static String FormatOrEmptyStrIfNull(String fmt, Object arg) {return arg == null ? "" : Format(fmt, arg);}
public static String Concat(char... ary) {return new String(ary);}
public static String Concat(String s1, String s2, String s3) {return s1 + s2 + s3;}
public static String Concat(String... ary) {
String_bldr sb = String_bldr_.new_();
for (String val : ary)
sb.Add(val);
return sb.To_str();
}
public static String Concat_any(Object... ary) {
String_bldr sb = String_bldr_.new_();
for (Object val : ary)
sb.Add_obj(val);
return sb.To_str();
}
public static String Concat_with_obj(String separator, Object... ary) {
String_bldr sb = String_bldr_.new_();
int aryLen = ArrayUtl.Len(ary);
for (int i = 0; i < aryLen; i++) {
if (i != 0) sb.Add(separator);
Object val = ary[i];
sb.Add_obj(Object_.Xto_str_strict_or_empty(val));
}
return sb.To_str();
}
public static String Concat_with_str(String spr, String... ary) {
String_bldr sb = String_bldr_.new_();
int len = ary.length;
for (int i = 0; i < len; i++) {
if (i != 0) sb.Add(spr);
sb.Add_obj(ary[i]);
}
return sb.To_str();
}
public static String Concat_lines_crlf(String... values) {
String_bldr sb = String_bldr_.new_();
for (String val : values)
sb.Add(val).Add(String_.CrLf);
return sb.To_str();
}
public static String Concat_lines_crlf_skipLast(String... values) {
String_bldr sb = String_bldr_.new_();
for (String val : values) {
if (sb.Count() != 0) sb.Add(String_.CrLf);
sb.Add(val);
}
return sb.To_str();
}
public static String Concat_lines_nl(String... values) {
String_bldr sb = String_bldr_.new_();
for (String val : values)
sb.Add(val).Add("\n");
return sb.To_str();
}
public static String Concat_lines_nl_apos_skip_last(String... lines) {
Bry_bfr bfr = Bry_bfr_.Get();
try {
Bry_.New_u8_nl_apos(bfr, lines);
return bfr.To_str_and_clear();
}
finally {bfr.Mkr_rls();}
}
public static String Concat_lines_nl_skip_last(String... ary) {
String_bldr sb = String_bldr_.new_();
int ary_len = ary.length; int ary_end = ary_len - 1;
for (int i = 0; i < ary_len; i++) {
sb.Add(ary[i]);
if (i != ary_end) sb.Add("\n");
}
return sb.To_str();
}
public static String[] Ary(String... ary) {return ary;}
public static String[] Ary_wo_null(String... ary) {
List_adp list = List_adp_.New();
int len = ary.length;
for (int i = 0; i < len; ++i) {
String itm = ary[i];
if (itm == null) continue;
list.Add(itm);
}
return list.ToStrAry();
}
public static String AryXtoStr(String... ary) {
String_bldr sb = String_bldr_.new_();
for (String s : ary)
sb.Add(s).Add(";");
return sb.To_str();
}
public static final String[] Ary_empty = new String[0];
public static String[] Split(String raw, char dlm) {return Split(raw, dlm, false);}
public static String[] Split(String raw, char dlm, boolean addEmptyIfDlmIsLast) {
List_adp list = List_adp_.New(); String_bldr sb = String_bldr_.new_();
int rawLen = String_.Len(raw); char c = '\0';
for (int i = 0; i < rawLen; i++) {
c = String_.CharAt(raw, i);
if (c == dlm) {
if (!addEmptyIfDlmIsLast && sb.Count() == 0 && i == rawLen - 1) {}
else list.Add(sb.To_str_and_clear());
}
else
sb.Add(c);
}
if (sb.Count() > 0)
list.Add(sb.To_str_and_clear());
return list.ToStrAry();
}
public static String[] Split(String s, String separator) {return Split_do(s, separator, false);}
public static String[] SplitLines_crlf(String s) {return Split(s, Op_sys.Wnt.Nl_str());}
public static String[] SplitLines_nl(String s) {return Split(s, Op_sys.Lnx.Nl_str());}
public static String[] SplitLines_any(String s) {return Split_do(s, Op_sys.Lnx.Nl_str(), true);}
public static String[] Split_lang(String s, char c) {return s.split(Character.toString(c));}
static String[] Split_do(String s, String spr, boolean skipChar13) {
if (String_.Eq(s, "") // "".Split('a') return array with one member: ""
|| String_.Eq(spr, "")) // "a".Split('\0') returns array with one member: "a"
return new String[] {s};
List_adp list = List_adp_.New(); String_bldr sb = String_bldr_.new_();
int i = 0, sprPos = 0; boolean sprMatched = false; char spr0 = CharAt(spr, 0);
int textLength = Len(s); int sprLength = Len(spr);
while (true) {
if (sprMatched
|| i == textLength) { // last pass; add whatever's in sb to list
list.Add(sb.To_str_and_clear());
if (sprMatched && i == textLength) list.Add(""); // if s ends with spr and last pass, add emptyString as last
sprMatched = false;
}
if (i == textLength) break;
char c = CharAt(s, i);
if (skipChar13 && c == (char)13) {i++; continue;}
if (c == spr0) { // matches first char of spr
sprPos = 1;
while (true) {
if (sprPos == sprLength) { // made it to end, must be match
sprMatched = true;
break;
}
if (i + sprPos == textLength) break; // ran out of s; handles partial match at end of String; ab+, +-
if (CharAt(s, i + sprPos) != CharAt(spr, sprPos)) break; // no match
sprPos++;
}
if (!sprMatched) // add partial match to sb
sb.Add(Mid_lang(s, i, sprPos));
i += sprPos;
}
else { // no spr match; just add char, increment pos
sb.Add(c);
i++;
}
}
return (String[])list.ToAry(String.class);
}
static String Mid_lang(String s, int bgn, int len) {return s.substring(bgn, bgn + len);}
public static String Extract_after_bwd(String src, String dlm) {
int dlm_pos = String_.FindBwd(src, dlm); if (dlm_pos == String_.Find_none) return String_.Empty;
int src_len = String_.Len(src); if (dlm_pos == src_len - 1) return String_.Empty;
return String_.Mid(src, dlm_pos + 1, src_len);
}
public static String Replace_by_pos(String v, int del_bgn, int del_end, String repl) {
return String_.Mid(v, 0, del_bgn) + repl + String_.Mid(v, del_end, String_.Len(v));
}
public static String read_(Object obj) {// NOTE: same as cast; for consistent readability only
String rv = as_(obj);
if (rv == null && obj != null) throw Err_.new_type_mismatch(String.class, obj); // NOTE: obj != null needed; EX: cast(null) --> null
return rv;
}
public static String[] Ary_parse(String raw, String dlm) {return String_.Split(raw, dlm);}
public static String[] Ary(byte[]... ary) {
if (ary == null) return String_.Ary_empty;
int ary_len = ary.length;
String[] rv = new String[ary_len];
for (int i = 0; i < ary_len; i++) {
byte[] itm = ary[i];
rv[i] = itm == null ? null : String_.new_u8(itm);
}
return rv;
}
public static String [] Ary_filter(String[] src, String[] filter) {
Hash_adp hash = Hash_adp_.New();
int len = filter.length;
for (int i = 0; i < len; i++) {
String itm = filter[i];
hash.AddIfDupeUseNth(itm, itm);
}
List_adp rv = List_adp_.New();
len = src.length;
for (int i = 0; i < len; i++) {
String itm = src[i];
if (hash.Has(itm)) rv.Add(itm);
}
return rv.ToStrAry();
}
public static String[] Ary_flatten(String[][] src_ary) {
int trg_len = 0;
int src_len = ArrayUtl.Len(src_ary);
for (int i = 0; i < src_len; i++) {
String[] itm = src_ary[i];
if (itm != null) trg_len += ArrayUtl.Len(itm);
}
String[] trg_ary = new String[trg_len];
trg_len = 0;
for (int i = 0; i < src_len; i++) {
String[] itm = src_ary[i];
if (itm == null) continue;
int itm_len = ArrayUtl.Len(itm);
for (int j = 0; j < itm_len; j++)
trg_ary[trg_len++] = itm[j];
}
return trg_ary;
}
public static boolean Ary_eq(String[] lhs, String[] rhs) {
int lhs_len = lhs.length, rhs_len = rhs.length;
if (lhs_len != rhs_len) return false;
for (int i = 0; i < lhs_len; ++i)
if (!String_.Eq(lhs[i], rhs[i])) return false;
return true;
}
public static String To_str__as_kv_ary(String... ary) {
int len = ary.length;
Bry_bfr bfr = Bry_bfr_.New();
for (int i = 0; i < len; i+=2) {
bfr.Add_str_u8(ary[i]).Add_byte_eq();
String val = i + 1 < len ? ary[i + 1] : null;
if (val != null) bfr.Add_str_u8(val);
bfr.Add_byte_nl();
}
return bfr.To_str_and_clear();
}
}

@ -1,164 +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;
import gplx.objects.lists.CompareAbleUtl;
import org.junit.*;
public class String__tst {
@Test public void LimitToFirst() {
tst_LimitToFirst("abc", 0, "");
tst_LimitToFirst("abc", 1, "a");
tst_LimitToFirst("abc", 2, "ab");
tst_LimitToFirst("abc", 3, "abc");
tst_LimitToFirst("abc", 4, "abc");
err_LimitToFirst("abc", -1);
}
void tst_LimitToFirst(String s, int v, String expd) {Tfds.Eq(expd, String_.LimitToFirst(s, v));}
void err_LimitToFirst(String s, int v) {try {String_.LimitToFirst(s, v);} catch (Exception exc) {Tfds.Err_classMatch(exc, Err.class); return;} Tfds.Fail_expdError();}
@Test public void LimitToLast() {
tst_LimitToLast("abc", 0, "");
tst_LimitToLast("abc", 1, "c");
tst_LimitToLast("abc", 2, "bc");
tst_LimitToLast("abc", 3, "abc");
tst_LimitToLast("abc", 4, "abc");
err_LimitToLast("abc", -1);
}
void tst_LimitToLast(String s, int v, String expd) {Tfds.Eq(expd, String_.LimitToLast(s, v));}
void err_LimitToLast(String s, int v) {try {String_.LimitToLast(s, v);} catch (Exception exc) {Tfds.Err_classMatch(exc, Err.class); return;} Tfds.Fail_expdError();}
@Test public void DelBgn() {
tst_DelBgn("abc", 0, "abc");
tst_DelBgn("abc", 1, "bc");
tst_DelBgn("abc", 2, "c");
tst_DelBgn("abc", 3, "");
err_DelBgn(null, 0);
err_DelBgn("abc", 4);
}
void tst_DelBgn(String s, int v, String expd) {Tfds.Eq(expd, String_.DelBgn(s, v));}
void err_DelBgn(String s, int v) {try {String_.DelBgn(s, v);} catch (Exception exc) {Tfds.Err_classMatch(exc, Err.class); return;} Tfds.Fail_expdError();}
@Test public void DelBgnIf() {
tst_DelBgnIf("abc", "", "abc");
tst_DelBgnIf("abc", "a", "bc");
tst_DelBgnIf("abc", "ab", "c");
tst_DelBgnIf("abc", "abc", "");
tst_DelBgnIf("abc", "abcd", "abc");
tst_DelBgnIf("abc", "bcd", "abc");
err_DelBgnIf(null, "abc");
err_DelBgnIf("abc", null);
}
void tst_DelBgnIf(String s, String v, String expd) {Tfds.Eq(expd, String_.DelBgnIf(s, v));}
void err_DelBgnIf(String s, String v) {try {String_.DelBgnIf(s, v);} catch (Exception exc) {Tfds.Err_classMatch(exc, Err.class); return;} Tfds.Fail_expdError();}
@Test public void DelEnd() {
tst_DelEnd("abc", 0, "abc");
tst_DelEnd("abc", 1, "ab");
tst_DelEnd("abc", 2, "a");
tst_DelEnd("abc", 3, "");
err_DelEnd(null, 0);
err_DelEnd("abc", 4);
}
void tst_DelEnd(String s, int v, String expd) {Tfds.Eq(expd, String_.DelEnd(s, v));}
void err_DelEnd(String s, int v) {try {String_.DelEnd(s, v);} catch (Exception exc) {Tfds.Err_classMatch(exc, Err.class); return;} Tfds.Fail_expdError();}
@Test public void DelEndIf() {
tst_DelEndIf("abc", "", "abc");
tst_DelEndIf("abc", "c", "ab");
tst_DelEndIf("abc", "bc", "a");
tst_DelEndIf("abc", "abc", "");
tst_DelEndIf("abc", "abcd", "abc");
tst_DelEndIf("abc", "ab", "abc");
err_DelEndIf(null, "");
err_DelEndIf("", null);
}
void tst_DelEndIf(String s, String v, String expd) {Tfds.Eq(expd, String_.DelEndIf(s, v));}
void err_DelEndIf(String s, String v) {try {String_.DelEndIf(s, v);} catch (Exception exc) {Tfds.Err_classMatch(exc, Err.class); return;} Tfds.Fail_expdError();}
@Test public void MidByPos() {
tst_MidByPos("abc", 0, 0, "");
tst_MidByPos("abc", 0, 1, "a");
tst_MidByPos("abc", 0, 2, "ab");
tst_MidByPos("abc", 0, 3, "abc");
tst_MidByPos("abc", 2, 3, "c");
err_MidByPos("abc", 1, 5);
// err_MidByPos("abc", 0, 4);
}
void tst_MidByPos(String s, int bgn, int end, String expd) {Tfds.Eq(expd, String_.Mid(s, bgn, end));}
void err_MidByPos(String s, int bgn, int end) {try {String_.Mid(s, bgn, end);} catch (Exception e) {Tfds.Err_classMatch(e, Err.class); return;} Tfds.Fail_expdError();}
@Test public void TrimEnd() {
tst_TrimEnd("a", "a");
tst_TrimEnd("a ", "a");
tst_TrimEnd("a\t", "a");
tst_TrimEnd("a\n", "a");
tst_TrimEnd("a\r", "a");
tst_TrimEnd("a\r\n \t", "a");
tst_TrimEnd(" a", " a");
tst_TrimEnd(null, null);
}
void tst_TrimEnd(String s, String expd) {Tfds.Eq(expd, String_.TrimEnd(s));}
@Test public void Count() {
String text = "0 0 0";
Tfds.Eq(3, String_.Count(text, "0"));
}
@Test public void Has() {
String text = "find word";
Tfds.Eq_true(String_.Has(text, "word"));
Tfds.Eq_false(String_.Has(text, "nothing"));
}
@Test public void Repeat() {
Tfds.Eq("333", String_.Repeat("3", 3));
}
@Test public void Split() {
tst_Split("ab", " ", "ab"); // no match -> return array with original input
tst_Split("ab cd", " ", "ab", "cd"); // separator.length = 1
tst_Split("ab+!cd", "+!", "ab", "cd"); // separator.length = 2
tst_Split("ab+!cd+!ef", "+!", "ab", "cd", "ef"); // terms = 3
tst_Split("ab+!cd+!", "+!", "ab", "cd", ""); // closing separator
tst_Split("+!ab", "+!", "", "ab"); // opening separator
tst_Split("ab+cd+!ef", "+!", "ab+cd", "ef"); // ignore partial matches
tst_Split("ab+!cd+", "+!", "ab", "cd+"); // ignore partial matches; end of String
// boundary
tst_Split("ab", "", "ab"); // separator.length = 0 -> return array with input as only member
tst_Split("", " ", ""); // empty input -> return array with empty input
// acceptance
tst_Split("this\r\nis\na\rtest\r\n.", "\r\n", "this", "is\na\rtest", ".");
} void tst_Split(String text, String separator, String... expd) {Tfds.Eq_ary(expd, String_.Split(text, separator));}
@Test public void Concat_with_obj() {
tst_ConcatWith_any("a|b", "|", "a", "b"); // do not append final delimiter
tst_ConcatWith_any("a||c", "|", "a", null, "c"); // null
tst_ConcatWith_any("a|b", "|", Object_.Ary("a", "b")); // pass array as arg
} void tst_ConcatWith_any(String expd, String delimiter, Object... array) {Tfds.Eq(expd, String_.Concat_with_obj(delimiter, array));}
@Test public void Compare_byteAry() {
tst_Compare_byteAry("a", "a", CompareAbleUtl.Same);
tst_Compare_byteAry("a", "b", CompareAbleUtl.Less);
tst_Compare_byteAry("b", "a", CompareAbleUtl.More);
tst_Compare_byteAry("ab", "ac", CompareAbleUtl.Less);
tst_Compare_byteAry("ac", "ab", CompareAbleUtl.More);
tst_Compare_byteAry("a", "ab", CompareAbleUtl.Less);
tst_Compare_byteAry("ab", "a", CompareAbleUtl.More);
tst_Compare_byteAry("101", "1-0-1", CompareAbleUtl.More); // NOTE: regular String_.Compare_as_ordinals returns Less in .NET, More in Java
tst_Compare_byteAry("1-0-1", "101 (album)", CompareAbleUtl.Less);
} void tst_Compare_byteAry(String lhs, String rhs, int expd) {Tfds.Eq(expd, String_.Compare_byteAry(lhs, rhs));}
@Test public void FindBwd() { // WORKAROUND.CS:String.LastIndexOf returns -1 for multi-chars;
tst_FindRev("abc", "a", 0, 0);
tst_FindRev("abc", "ab", 0, 0); // 2 chars
tst_FindRev("abc", "abc", 0, 0); // 3 chars
tst_FindRev("ab", "abc", 0, -1); // out of index error
tst_FindRev("ababab", "ab", 2, 2); // make sure cs implementation doesn't pick up next
} void tst_FindRev(String s, String find, int pos, int expd) {Tfds.Eq(expd, String_.FindBwd(s, find, pos));}
@Test public void Extract_after_bwd() {
Extract_after_bwd_tst("a/b", "/", "b");
Extract_after_bwd_tst("a/", "/", "");
Extract_after_bwd_tst("a", "/", "");
} void Extract_after_bwd_tst(String src, String dlm, String expd) {Tfds.Eq(expd, String_.Extract_after_bwd(src, dlm));}
}

@ -1,235 +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;
import gplx.core.strings.*; import gplx.core.consoles.*; import gplx.core.tests.*;
import gplx.objects.arrays.ArrayUtl;
public class Tfds { // URL:doc/gplx.tfds/Tfds.txt
public static boolean SkipDb = false;
public static void Eq_bool (boolean expd , boolean actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_bool (boolean expd , boolean actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq_byte (byte expd , byte actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq_int (int expd , int actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_int (int expd , int actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq_double(double expd, double actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_str (byte[] expd, byte[] actl, String fmt, Object... args) {Eq_exec_y(String_.new_u8(expd), String_.new_u8(actl), fmt, args);}
public static void Eq_str (byte[] expd, String actl, String fmt, Object... args) {Eq_exec_y(String_.new_u8(expd), actl, fmt, args);}
public static void Eq_str (String expd, byte[] actl, String fmt, Object... args) {Eq_exec_y(expd, String_.new_u8(actl), fmt, args);}
public static void Eq_str (String expd, String actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_str (String expd, String actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq(Object expd, Object actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_byte(byte expd, byte actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_long(long expd, long actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_float(float expd, float actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_decimal(Decimal_adp expd, Decimal_adp actl) {Eq_wkr(expd.To_double(), actl.To_double(), true, EmptyStr);}
public static void Eq_date(DateAdp expd, DateAdp actl) {Eq_wkr(expd.XtoStr_gplx(), actl.XtoStr_gplx(), true, EmptyStr);}
public static void Eq_date(DateAdp expd, DateAdp actl, String fmt, Object... args){Eq_wkr(expd.XtoStr_gplx(), actl.XtoStr_gplx(), true, String_.Format(fmt, args));}
public static void Eq_url(Io_url expd, Io_url actl) {Eq_wkr(expd.Raw(), actl.Raw(), true, EmptyStr);}
public static void Eq_str(String expd, byte[] actl) {Eq_wkr(expd, String_.new_u8(actl), true, EmptyStr);}
public static void Eq_bry(String expd, byte[] actl) {Eq_wkr(expd, String_.new_u8(actl), true, EmptyStr);}
public static void Eq_bry(byte[] expd, byte[] actl) {Eq_wkr(String_.new_u8(expd), String_.new_u8(actl), true, EmptyStr);}
public static void Eq_str_intf(To_str_able expd, To_str_able actl, String msg) {Eq_wkr(expd.To_str(), actl.To_str(), true, msg);}
public static void Eq_str_intf(To_str_able expd, To_str_able actl) {Eq_wkr(expd.To_str(), actl.To_str(), true, String_.Empty);}
public static void Eq_str_lines(String lhs, String rhs) {Eq_str_lines(lhs, rhs, EmptyStr);}
public static void Eq_str_lines(String lhs, String rhs, String note) {
if (lhs == null) lhs = "";
if (rhs == null) rhs = "";
Eq_ary_wkr(String_.Split(lhs, Char_.NewLine), String_.Split(rhs, Char_.NewLine), false, note);
}
public static void Eq(Object expd, Object actl, String fmt, Object... args) {Eq_wkr(expd, actl, true, String_.Format(fmt, args));}
public static void Eq_rev(Object actl, Object expd) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_rev(Object actl, Object expd, String fmt, Object... args) {Eq_wkr(expd, actl, true, String_.Format(fmt, args));}
public static void Eq_true(Object actl) {Eq_wkr(true, actl, true, EmptyStr);}
public static void Eq_true(Object actl, String fmt, Object... args) {Eq_wkr(true, actl, true, String_.Format(fmt, args));}
public static void Eq_false(Object actl) {Eq_wkr(false, actl, true, EmptyStr);}
public static void Eq_false(Object actl, String fmt, Object... args) {Eq_wkr(false, actl, true, String_.Format(fmt, args));}
public static void Eq_null(Object actl) {Eq_wkr(null, actl, true, EmptyStr);}
public static void Eq_null(Object actl, String fmt, Object... args) {Eq_wkr(null, actl, true, String_.Format(fmt, args));}
public static void Eq_nullNot(Object actl) {Eq_wkr(null, actl, false, EmptyStr);}
public static void Eq_nullNot(Object actl, String fmt, Object... args) {Eq_wkr(null, actl, false, String_.Format(fmt, args));}
public static void Fail_expdError() {Eq_wkr(true, false, true, "fail expd error");}
public static void Fail(String fmt, Object... args) {Eq_wkr(true, false, true, String_.Format(fmt, args));}
public static void Eq_ary(Object lhs, Object rhs) {Eq_ary_wkr(lhs, rhs, true, EmptyStr);}
public static void Eq_ary(Object lhs, Object rhs, String fmt, Object... args){Eq_ary_wkr(lhs, rhs, true, String_.Format(fmt, args));}
public static void Eq_ary_str(Object lhs, Object rhs, String note) {Eq_ary_wkr(lhs, rhs, false, note);}
public static void Eq_ary_str(Object lhs, Object rhs) {Eq_ary_wkr(lhs, rhs, false, EmptyStr);}
public static void Eq_list(List_adp lhs, List_adp rhs) {Eq_list_wkr(lhs, rhs, TfdsEqListItmStr_cls_default.Instance, EmptyStr);}
public static void Eq_list(List_adp lhs, List_adp rhs, TfdsEqListItmStr xtoStr) {Eq_list_wkr(lhs, rhs, xtoStr, EmptyStr);}
private static void Eq_exec_y(Object lhs, Object rhs, String fmt, Object[] args) {
if (Object_.Eq(lhs, rhs)) return;
String msg = msgBldr.Eq_xtoStr(lhs, rhs, String_.Format(fmt, args));
throw Err_.new_wo_type(msg);
}
static void Eq_wkr(Object lhs, Object rhs, boolean expd, String customMsg) {
boolean actl = Object_.Eq(lhs, rhs);
if (expd == actl) return;
String msg = msgBldr.Eq_xtoStr(lhs, rhs, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_ary_wkr(Object lhsAry, Object rhsAry, boolean compareUsingEquals, String customMsg) {
List_adp list = List_adp_.New(); boolean pass = true;
int lhsLen = ArrayUtl.Len(lhsAry), rhsLen = ArrayUtl.Len(rhsAry);
for (int i = 0; i < lhsLen; i++) {
Object lhs = ArrayUtl.GetAt(lhsAry, i);
Object rhs = i >= rhsLen ? "<<N/A>>" : ArrayUtl.GetAt(rhsAry, i);
String lhsString = msgBldr.Obj_xtoStr(lhs); String rhsString = msgBldr.Obj_xtoStr(rhs); // even if compareUsingEquals, method does ToStr on each itm for failMsg
boolean isEq = compareUsingEquals
? Object_.Eq(lhs, rhs)
: Object_.Eq(lhsString, rhsString);
Eq_ary_wkr_addItm(list, i, isEq, lhsString, rhsString);
if (!isEq) pass = false;
}
for (int i = lhsLen; i < rhsLen; i++) {
String lhsString = "<<N/A>>";
String rhsString = msgBldr.Obj_xtoStr(ArrayUtl.GetAt(rhsAry, i));
Eq_ary_wkr_addItm(list, i, false, lhsString, rhsString);
pass = false;
}
if (pass) return;
String msg = msgBldr.Eq_ary_xtoStr(list, lhsLen, rhsLen, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_list_wkr(List_adp lhsList, List_adp rhsList, TfdsEqListItmStr xtoStr, String customMsg) {
List_adp list = List_adp_.New(); boolean pass = true;
int lhsLen = lhsList.Len(), rhsLen = rhsList.Len();
for (int i = 0; i < lhsLen; i++) {
Object lhs = lhsList.Get_at(i);
Object rhs = i >= rhsLen ? null : rhsList.Get_at(i);
String lhsStr = xtoStr.To_str(lhs, lhs);
String rhsStr = rhs == null ? "<<N/A>>" : xtoStr.To_str(rhs, lhs);
boolean isEq = Object_.Eq(lhsStr, rhsStr); if (!isEq) pass = false;
Eq_ary_wkr_addItm(list, i, isEq, lhsStr, rhsStr);
}
for (int i = lhsLen; i < rhsLen; i++) {
String lhsStr = "<<N/A>>";
Object rhs = rhsList.Get_at(i);
String rhsStr = xtoStr.To_str(rhs, null);
Eq_ary_wkr_addItm(list, i, false, lhsStr, rhsStr);
pass = false;
}
if (pass) return;
String msg = msgBldr.Eq_ary_xtoStr(list, lhsLen, rhsLen, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_ary_wkr_addItm(List_adp list, int i, boolean isEq, String lhsString, String rhsString) {
TfdsEqAryItm itm = new TfdsEqAryItm().Idx_(i).Eq_(isEq).Lhs_(lhsString).Rhs_(rhsString);
list.Add(itm);
}
public static void Err_classMatch(Exception exc, Class<?> type) {
boolean match = Type_.Eq_by_obj(exc, type);
if (!match) throw Err_.new_("Tfds", "error types do not match", "expdType", Type_.Canonical_name(type), "actlType", Type_.Name_by_obj(exc), "actlMsg", Err_.Message_lang(exc));
}
public static void Eq_err(Err expd, Exception actlExc) {
Tfds.Eq(Err_.Message_gplx_full(expd), Err_.Message_gplx_full(actlExc));
}
public static void Err_has(Exception e, String hdr) {
Tfds.Eq_true(String_.Has(Err_.Message_gplx_full(e), hdr), "could not find '{0}' in '{1}'", hdr, Err_.Message_gplx_full(e));
}
static final String EmptyStr = TfdsMsgBldr.EmptyStr;
static TfdsMsgBldr msgBldr = TfdsMsgBldr.new_();
public static final Io_url RscDir = Io_url_.Usr().GenSubDir_nest("000", "200_dev", "190_tst");
public static void WriteText(String text) {Console_adp__sys.Instance.Write_str(text);}
public static void Write(byte[] s, int b, int e) {Write(Bry_.Mid(s, b, e));}
public static void Write() {Write("tmp");}
public static void Dbg(Object... ary) {Write(ary);}
public static void Write(Object... ary) {
String_bldr sb = String_bldr_.new_();
int aryLen = ArrayUtl.Len(ary);
for (int i = 0; i < aryLen; i++)
sb.Add_many("'", Object_.Xto_str_strict_or_null_mark(ary[i]), "'", " ");
WriteText(sb.To_str() + String_.Lf);
}
}
class TfdsEqListItmStr_cls_default implements TfdsEqListItmStr {
public String To_str(Object cur, Object actl) {
return Object_.Xto_str_strict_or_null_mark(cur);
}
public static final TfdsEqListItmStr_cls_default Instance = new TfdsEqListItmStr_cls_default(); TfdsEqListItmStr_cls_default() {}
}
class TfdsEqAryItm {
public int Idx() {return idx;} public TfdsEqAryItm Idx_(int v) {idx = v; return this;} int idx;
public String Lhs() {return lhs;} public TfdsEqAryItm Lhs_(String v) {lhs = v; return this;} private String lhs;
public String Rhs() {return rhs;} public TfdsEqAryItm Rhs_(String v) {rhs = v; return this;} private String rhs;
public boolean Eq() {return eq;} public TfdsEqAryItm Eq_(boolean v) {eq = v; return this;} private boolean eq;
}
class TfdsMsgBldr {
public String Eq_xtoStr(Object expd, Object actl, String customMsg) {
String expdString = Obj_xtoStr(expd); String actlString = Obj_xtoStr(actl);
String detail = String_.Concat
( CustomMsg_xtoStr(customMsg)
, "\t\t", "expd: ", expdString, String_.CrLf
, "\t\t", "actl: ", actlString, String_.CrLf
);
return WrapMsg(detail);
}
public String Eq_ary_xtoStr(List_adp list, int lhsAryLen, int rhsAryLen, String customMsg) {
String_bldr sb = String_bldr_.new_();
sb.Add(CustomMsg_xtoStr(customMsg));
if (lhsAryLen != rhsAryLen)
sb.Add_fmt_line("{0}element counts differ: {1} {2}", "\t\t", lhsAryLen, rhsAryLen);
int lhsLenMax = 0, rhsLenMax = 0;
for (int i = 0; i < list.Len(); i++) {
TfdsEqAryItm itm = (TfdsEqAryItm)list.Get_at(i);
int lhsLen = String_.Len(itm.Lhs()), rhsLen = String_.Len(itm.Rhs());
if (lhsLen > lhsLenMax) lhsLenMax = lhsLen;
if (rhsLen > rhsLenMax) rhsLenMax = rhsLen;
}
for (int i = 0; i < list.Len(); i++) {
TfdsEqAryItm itm = (TfdsEqAryItm)list.Get_at(i);
String eq_str = itm.Eq() ? "==" : "";
if (!itm.Eq()) {
// if (lhsLenMax < 8 )
// eq_str = "!=";
// else
eq_str = "\n!= ";
}
sb.Add_fmt_line("{0}: {1} {2} {3}"
, Int_.To_str_pad_bgn_zero(itm.Idx(), 4)
, itm.Lhs() // String_.PadBgn(itm.Lhs(), lhsLenMax, " ")
, eq_str
, itm.Rhs() // String_.PadBgn(itm.Rhs(), rhsLenMax, " ")
);
}
// String compSym = isEq ? " " : "!=";
// String result = String_.Format("{0}: {1}{2} {3} {4}", Int_.To_str_pad_bgn_zero(i, 4), lhsString, String_.CrLf + "\t\t", compSym, rhsString);
// foreach (Object obj in list) {
// String itmComparison = (String)obj;
// sb.Add_fmt_line("{0}{1}", "\t\t", itmComparison);
// }
return WrapMsg(sb.To_str());
}
String CustomMsg_xtoStr(String customMsg) {
return (customMsg == EmptyStr)
? ""
: String_.Concat(customMsg, String_.CrLf);
}
public String Obj_xtoStr(Object obj) {
String s = String_.as_(obj);
if (s != null) return String_.Concat("'", s, "'"); // if Object is String, put quotes around it for legibility
To_str_able xtoStrAble = To_str_able_.as_(obj);
if (xtoStrAble != null) return xtoStrAble.To_str();
return Object_.Xto_str_strict_or_null_mark(obj);
}
String WrapMsg(String text) {
return String_.Concat(String_.CrLf
, "************************************************************************************************", String_.CrLf
, text
, "________________________________________________________________________________________________"
);
}
public static TfdsMsgBldr new_() {return new TfdsMsgBldr();} TfdsMsgBldr() {}
public static final String EmptyStr = "";
}

@ -1,83 +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;
import gplx.core.strings.*;
import gplx.objects.lists.CompareAble;
import gplx.objects.lists.CompareAbleUtl;
public class Time_span implements CompareAble { // NOTE: gplx.Time_span b/c System.TimeSpan
public long Fracs() {return fracs;} long fracs; public int FracsAsInt() {return (int)fracs;}
public Decimal_adp Total_days() {return Decimal_adp_.divide_(fracs, Time_span_.Divisors[Time_span_.Idx_Hour] * 24);}
public Decimal_adp Total_hours() {return Decimal_adp_.divide_(fracs, Time_span_.Divisors[Time_span_.Idx_Hour]);}
public Decimal_adp Total_mins() {return Decimal_adp_.divide_(fracs, Time_span_.Divisors[Time_span_.Idx_Min]);}
public Decimal_adp Total_secs() {return Decimal_adp_.divide_(fracs, Time_span_.Divisors[Time_span_.Idx_Sec]);}
public int[] Units() {return Time_span_.Split_long(fracs, Time_span_.Divisors);}
public int Units_fracs() {
int[] ary = Time_span_.Split_long(fracs, Time_span_.Divisors);
return ary[Time_span_.Idx_Frac];
}
public Time_span Add(Time_span val) {return new Time_span(fracs + val.fracs);}
public Time_span Add_fracs(long val) {return new Time_span(fracs + val);}
public Time_span Add_unit(int idx, int val) {
int[] units = Time_span_.Split_long(fracs, Time_span_.Divisors);
units[idx] += val;
int sign = fracs >= 0 ? 1 : -1;
long rv = sign * Time_span_.Merge_long(units, Time_span_.Divisors);
return Time_span_.fracs_(rv);
}
public Time_span Subtract(Time_span val) {return new Time_span(fracs - val.fracs);}
public int compareTo(Object obj) {Time_span comp = Time_span_.cast(obj); return CompareAbleUtl.Compare_obj(fracs, comp.fracs);}
public boolean Eq(Object o) {
Time_span comp = Time_span_.cast(o); if (comp == null) return false;
return fracs == comp.fracs;
}
@Override public String toString() {return To_str(Time_span_.Fmt_Default);}
@Override public boolean equals(Object obj) {Time_span comp = Time_span_.cast(obj); return Object_.Eq(fracs, comp.fracs);}
@Override public int hashCode() {return super.hashCode();}
public String To_str() {return Time_span_.To_str(fracs, Time_span_.Fmt_Default);}
public String To_str(String format) {
return Time_span_.To_str(fracs, format);
}
public String XtoStrUiAbbrv() {
if (fracs == 0) return "0" + UnitAbbrv(0);
int[] units = Units();
boolean started = false;
String_bldr sb = String_bldr_.new_();
for (int i = units.length - 1; i > -1; i--) {
int unit = units[i];
if (!started) {
if (unit == 0)
continue;
else
started = true;
}
if (sb.Count() != 0) sb.Add(" ");
sb.Add_obj(unit).Add(UnitAbbrv(i));
}
return sb.To_str();
}
String UnitAbbrv(int i) {
switch (i) {
case 0: return "f";
case 1: return "s";
case 2: return "m";
case 3: return "h";
default: return "unknown:<" + Int_.To_str(i) + ">";
}
}
@gplx.Internal protected Time_span(long fracs) {this.fracs = fracs;}
}

@ -1,163 +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;
import gplx.core.strings.*; import gplx.core.envs.*;
import gplx.objects.arrays.ArrayUtl;
import gplx.objects.strings.AsciiByte;
public class Time_span_ {
public static final Time_span Zero = new Time_span(0);
public static final Time_span Null = new Time_span(-1);
public static Time_span fracs_(long val) {return new Time_span(val);}
public static Time_span seconds_(double seconds) {
long fracs = (long)(seconds * Divisors[Idx_Sec]);
return new Time_span(fracs);
}
public static Time_span decimal_(Decimal_adp seconds) {
return new Time_span(seconds.To_long_mult_1000());
}
public static Time_span units_(int frc, int sec, int min, int hour) {
int[] units = new int[] {frc, sec, min, hour};
long fracs = Merge_long(units, Time_span_.Divisors);
return Time_span_.fracs_(fracs);
}
public static Time_span from_(long bgn) {return Time_span_.fracs_(System_.Ticks() - bgn);}
public static final long parse_null = Long_.Min_value;
public static Time_span parse(String raw) {
byte[] bry = Bry_.new_u8(raw);
long fracs = parse_to_fracs(bry, 0, bry.length, false);
return fracs == parse_null ? null : Time_span_.fracs_(fracs);
}
public static long parse_to_fracs(byte[] raw, int bgn, int end, boolean fail_if_ws) {
int sign = 1, val_f = 0, val_s = 0, val_m = 0, val_h = 0, colon_pos = 0, unit_val = 0, unit_multiple = 1;
for (int i = end - 1; i >= bgn; i--) { // start from end; fracs should be lowest unit
byte b = raw[i];
switch (b) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
int unit_digit = AsciiByte.ToA7Int(b);
unit_val = (unit_multiple == 1) ? unit_digit : unit_val + (unit_digit * unit_multiple);
switch (colon_pos) {
case 0: val_s = unit_val; break;
case 1: val_m = unit_val; break;
case 2: val_h = unit_val; break;
default: return parse_null; // only hour:minute:second supported for ':' separator; ':' count should be <= 2
}
unit_multiple *= 10;
break;
case AsciiByte.Dot:
double factor = (double)1000 / (double)unit_multiple; // factor is necessary to handle non-standard decimals; ex: .1 -> 100; .00199 -> .001
val_f = (int)((double)val_s * factor); // move val_s unit_val to val_f; logic is indirect, b/c of differing inputs: "123" means 123 seconds; ".123" means 123 fractionals
val_s = 0;
unit_multiple = 1;
break;
case AsciiByte.Colon:
colon_pos++;
unit_multiple = 1;
break;
case AsciiByte.Dash:
if (i == 0 && unit_val > 0) // only if first char && unit_val > 0
sign = -1;
break;
case AsciiByte.Space: case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr:
if (fail_if_ws) return parse_null;
break;
default:
return parse_null; // invalid char; return null;
}
}
return sign * (val_f + (val_s * Divisors[1]) + (val_m * Divisors[2]) + (val_h * Divisors[3]));
}
public static String To_str(long frc, String fmt) {
String_bldr sb = String_bldr_.new_();
int[] units = Split_long(frc, Divisors);
if (String_.Eq(fmt, Time_span_.Fmt_Short)) {
for (int i = Idx_Hour; i > -1; i--) {
int val = units[i];
if (val == 0 && i == Idx_Hour) continue; // skip hour if 0; ex: 01:02, instead of 00:01:02
if (i == Idx_Frac) continue; // skip frac b/c fmt is short
if (sb.Count() > 0) // sb already has unit; add delimiter
sb.Add(Sprs[i]);
if (val < 10) // zeroPad
sb.Add("0");
sb.Add(Int_.To_str(val));
}
return sb.To_str_and_clear();
}
boolean fmt_fracs = !String_.Eq(fmt, Time_span_.Fmt_NoFractionals);
boolean fmt_padZeros = String_.Eq(fmt, Time_span_.Fmt_PadZeros);
if (frc == 0) return fmt_padZeros ? "00:00:00.000" : "0";
int[] padZerosAry = ZeroPadding;
boolean first = true;
String dlm = "";
int zeros = 0;
if (frc < 0) sb.Add("-"); // negative sign
for (int i = Idx_Hour; i > -1; i--) { // NOTE: "> Idx_Frac" b/c frc will be handled below
int val = units[i];
if (i == Idx_Frac // only write fracs...
&& !(val == 0 && fmt_padZeros) // ... if val == 0 && fmt is PadZeros
&& !(val != 0 && fmt_fracs) // ... or val != 0 && fmt is PadZeros or Default
) continue;
if (first && val == 0 && !fmt_padZeros) continue; // if first and val == 0, don't full pad (avoid "00:")
zeros = first && !fmt_padZeros ? 1 : padZerosAry[i]; // if first, don't zero pad (avoid "01")
dlm = first ? "" : Sprs[i]; // if first, don't use dlm (avoid ":01")
sb.Add(dlm);
sb.Add(Int_.To_str_pad_bgn_zero(val, zeros));
first = false;
}
return sb.To_str();
}
@gplx.Internal protected static int[] Split_long(long fracs, int[] divisors) {
int divLength = ArrayUtl.Len(divisors);
int[] rv = new int[divLength];
long cur = Math_.Abs(fracs);
for (int i = divLength - 1; i > -1; i--) {
int divisor = divisors[i];
long factor = cur / divisor;
rv[i] = (int)factor;
cur -= (factor * divisor);
}
return rv;
}
@gplx.Internal protected static long Merge_long(int[] vals, int[] divisors) {
long rv = 0; int valLength = ArrayUtl.Len(vals);
for (int i = 0; i < valLength; i++) {
rv += vals[i] * divisors[i];
}
return rv;
}
public static final String Fmt_PadZeros = "00:00:00.000"; // u,h00:m00:s00.f000
public static final String Fmt_Short = "short"; // u,h##:m#0:s00;
public static final String Fmt_Default = "0.000"; // v,#.000
public static final String Fmt_NoFractionals = "0"; // v,#
@gplx.Internal protected static final int[] Divisors = {
1, //1 fracs
1000, //1,000 fracs in a second
60000, //60,000 fracs in a minute (60 seconds * 1,000)
3600000, //3,600,000 fracs in an hour (60 minutes * 60,000)
};
public static final String MajorDelimiter = ":";
public static final int
Idx_Frac = 0
, Idx_Sec = 1
, Idx_Min = 2
, Idx_Hour = 3;
static int[] ZeroPadding = {3, 2, 2, 2,};
static String[] Sprs = {".", MajorDelimiter, MajorDelimiter, "",};
public static Time_span cast(Object arg) {try {return (Time_span)arg;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, Time_span.class, arg);}}
public static final double Ratio_f_to_s = 1000;
}

@ -1,19 +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;
class To_str_able_ {//RF:2017-10-08
public static To_str_able as_(Object obj) {return obj instanceof To_str_able ? (To_str_able)obj : null;}
}

@ -1,62 +0,0 @@
/*
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;
public class Type_ {//RF:2017-10-08
public static Class<?> Type_by_obj(Object o) {return o.getClass();}
public static Class<?> Type_by_primitive(Object o) {
Class<?> rv = o.getClass();
if (rv == Integer.class) rv = int.class;
else if (rv == Long.class) rv = long.class;
else if (rv == Byte.class) rv = byte.class;
else if (rv == Short.class) rv = short.class;
return rv;
}
public static boolean Eq_by_obj(Object lhs_obj, Class<?> rhs_type) {
Class<?> lhs_type = lhs_obj == null ? null : lhs_obj.getClass();
return Type_.Eq(lhs_type, rhs_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);
}
public static String Canonical_name_by_obj(Object o) {return Canonical_name(o.getClass());}
public static String Canonical_name(Class<?> type) {
return type.getCanonicalName();
}
public static String Name_by_obj(Object obj) {return obj == null ? String_.Null_mark : Name(Type_by_obj(obj));}
public static String Name(Class<?> type) {
return type.getName();
}
public static String SimpleName_by_obj(Object obj) {return obj == null ? String_.Null_mark : SimpleName(Type_by_obj(obj));}
public static String SimpleName(Class<?> type) {
return type.getSimpleName();
}
public static boolean Is_array(Class<?> t) {
return t.isArray();
}
public static boolean Is_assignable_from_by_obj(Object o, Class<?> generic) {return o == null ? false : Is_assignable_from(generic, o.getClass());}
public static boolean Is_assignable_from(Class<?> generic, Class<?> specific) {
return generic.isAssignableFrom(specific);
}
}

@ -1,58 +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;
import gplx.objects.primitives.BoolUtl;
public class Type_ids_ {//RF:2017-10-08
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, BoolUtl.ClsRefType)) 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_adp_.Cls_ref_type)) return Id__decimal;
else if (Type_.Eq(type, DateAdp_.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;
}
}

@ -1,78 +1,81 @@
/*
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;
import gplx.core.stores.*;
import gplx.objects.primitives.BoolUtl;
public class Yn {
public static final String Y = "y", N = "n";
public static boolean parse_by_char_or(String v, boolean or) {
if (String_.Eq(v, Y)) return true;
else if (String_.Eq(v, N)) return false;
else return or;
}
public static boolean parse_or_n_(String v) {return parse_or(v, false);}
public static int parse_as_int(String v) {
if (v == null) return BoolUtl.NullInt;
else if (String_.Eq(v, "y")) return BoolUtl.YInt;
else if (String_.Eq(v, "n")) return BoolUtl.NInt;
else return BoolUtl.NullInt;
}
public static boolean parse_or(String v, boolean or) {
int v_int = parse_as_int(v);
switch (v_int) {
case BoolUtl.NInt: return false;
case BoolUtl.YInt: return true;
case BoolUtl.NullInt: return or;
default: throw Err_.new_unhandled(v_int);
}
}
public static boolean parse(String v) {
int v_int = parse_as_int(v);
if (v_int == BoolUtl.NullInt) Err_.new_unhandled(v);
return v_int == BoolUtl.YInt;
}
public static String To_str(boolean v) {return v ? "y" : "n";}
public static String To_nullable_str(byte v) {
switch (v) {
case BoolUtl.YByte: return "y";
case BoolUtl.NByte: return "n";
case BoolUtl.NullByte: return "?";
default: throw Err_.new_unhandled(v);
}
}
public static byte To_nullable_byte(String v) {
if (v != null && String_.Len(v) == 1) {
char c = String_.CharAt(v, 0);
switch (c) {
case 'y': return BoolUtl.YByte;
case 'n': return BoolUtl.NByte;
case '?': return BoolUtl.NullByte;
}
}
throw Err_.new_unhandled(v);
}
public static boolean store_bool_or(SrlMgr mgr, String key, boolean or) {
String v = mgr.SrlStrOr(key, "");
return mgr.Type_rdr() ? parse_or(v, or) : or;
}
public static boolean coerce_(Object o) {String s = String_.as_(o); return s != null ? parse_or(s, false) : BoolUtl.Cast(o);}
public static boolean readOrFalse_(DataRdr rdr, String key) {return read_(rdr, key, false);}
public static boolean readOrTrue_(DataRdr rdr, String key) {return read_(rdr, key, true);}
static boolean read_(DataRdr rdr, String key, boolean or) {
String v = rdr.ReadStrOr(key, null);
return parse_or(v, or);
}
}
/*
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;
import gplx.core.stores.DataRdr;
import gplx.core.stores.SrlMgr;
import gplx.types.basics.utls.BoolUtl;
import gplx.types.basics.utls.StringUtl;
import gplx.types.errs.ErrUtl;
public class Yn {
public static final String Y = "y", N = "n";
public static boolean parse_by_char_or(String v, boolean or) {
if (StringUtl.Eq(v, Y)) return true;
else if (StringUtl.Eq(v, N)) return false;
else return or;
}
public static boolean parse_or_n_(String v) {return parse_or(v, false);}
public static int parse_as_int(String v) {
if (v == null) return BoolUtl.NullInt;
else if (StringUtl.Eq(v, "y")) return BoolUtl.YInt;
else if (StringUtl.Eq(v, "n")) return BoolUtl.NInt;
else return BoolUtl.NullInt;
}
public static boolean parse_or(String v, boolean or) {
int v_int = parse_as_int(v);
switch (v_int) {
case BoolUtl.NInt: return false;
case BoolUtl.YInt: return true;
case BoolUtl.NullInt: return or;
default: throw ErrUtl.NewUnhandled(v_int);
}
}
public static boolean parse(String v) {
int v_int = parse_as_int(v);
if (v_int == BoolUtl.NullInt) ErrUtl.NewUnhandled(v);
return v_int == BoolUtl.YInt;
}
public static String To_str(boolean v) {return v ? "y" : "n";}
public static String To_nullable_str(byte v) {
switch (v) {
case BoolUtl.YByte: return "y";
case BoolUtl.NByte: return "n";
case BoolUtl.NullByte: return "?";
default: throw ErrUtl.NewUnhandled(v);
}
}
public static byte To_nullable_byte(String v) {
if (v != null && StringUtl.Len(v) == 1) {
char c = StringUtl.CharAt(v, 0);
switch (c) {
case 'y': return BoolUtl.YByte;
case 'n': return BoolUtl.NByte;
case '?': return BoolUtl.NullByte;
}
}
throw ErrUtl.NewUnhandled(v);
}
public static boolean store_bool_or(SrlMgr mgr, String key, boolean or) {
String v = mgr.SrlStrOr(key, "");
return mgr.Type_rdr() ? parse_or(v, or) : or;
}
public static boolean coerce_(Object o) {String s = StringUtl.CastOrNull(o); return s != null ? parse_or(s, false) : BoolUtl.Cast(o);}
public static boolean readOrFalse_(DataRdr rdr, String key) {return read_(rdr, key, false);}
public static boolean readOrTrue_(DataRdr rdr, String key) {return read_(rdr, key, true);}
static boolean read_(DataRdr rdr, String key, boolean or) {
String v = rdr.ReadStrOr(key, null);
return parse_or(v, or);
}
}

@ -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,29 +13,30 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.bits; import gplx.*; import gplx.core.*;
public class Bitmask_ {
public static boolean Has_int(int val, int find) {return find == (val & find);}
public static int Flip_int(boolean enable, int val, int find) {
boolean has = find == (val & find);
return (has ^ enable) ? val ^ find : val;
}
public static int Add_int(int lhs, int rhs) {return lhs | rhs;}
public static int Add_int_ary(int... ary) {
int rv = 0;
int len = ary.length;
for (int i = 0; i < len; ++i) {
int itm = ary[i];
if (rv == 0)
rv = itm;
else
rv = Flip_int(true, rv, itm);
}
return rv;
}
public static int Set_or_add(int val, int flag) {
return val == 0 ? flag : val | flag;
}
public static boolean Has_byte(byte val, byte find) {return find == (val & find);}
public static byte Add_byte(byte flag, byte itm) {return (byte)(flag | itm);}
}
package gplx.core.bits;
import gplx.*; import gplx.core.*;
public class Bitmask_ {
public static boolean Has_int(int val, int find) {return find == (val & find);}
public static int Flip_int(boolean enable, int val, int find) {
boolean has = find == (val & find);
return (has ^ enable) ? val ^ find : val;
}
public static int Add_int(int lhs, int rhs) {return lhs | rhs;}
public static int Add_int_ary(int... ary) {
int rv = 0;
int len = ary.length;
for (int i = 0; i < len; ++i) {
int itm = ary[i];
if (rv == 0)
rv = itm;
else
rv = Flip_int(true, rv, itm);
}
return rv;
}
public static int Set_or_add(int val, int flag) {
return val == 0 ? flag : val | flag;
}
public static boolean Has_byte(byte val, byte find) {return find == (val & find);}
public static byte Add_byte(byte flag, byte itm) {return (byte)(flag | itm);}
}

@ -1,33 +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.core.brys; import gplx.*; import gplx.core.*;
import gplx.core.brys.args.*; import gplx.core.brys.fmtrs.*;
public class Bfr_arg_ {
public static Bfr_arg__int New_int(int v) {return new Bfr_arg__int(v);}
public static Bfr_arg__byte New_byte(byte v) {return new Bfr_arg__byte(v);}
public static Bfr_arg__bry New_bry(String v) {return Bfr_arg__bry.New(Bry_.new_u8(v));}
public static Bfr_arg__bry New_bry(byte[] v) {return Bfr_arg__bry.New(v);}
public static Bfr_arg__bry_fmtr New_bry_fmtr__null() {return new Bfr_arg__bry_fmtr(null, null);}
public static Bfr_arg__bry_fmtr New_bry_fmtr(Bry_fmtr v, Bfr_arg... arg_ary) {return new Bfr_arg__bry_fmtr(v, arg_ary);}
public static final Bfr_arg Noop = new Bfr_arg___noop();
public static void Clear(Bfr_arg_clearable... ary) {
for (Bfr_arg_clearable arg : ary)
arg.Bfr_arg__clear();
}
}
class Bfr_arg___noop implements gplx.core.brys.Bfr_arg {
public void Bfr_arg__add(Bry_bfr bfr) {}
}

@ -1,20 +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.core.brys; import gplx.*; import gplx.core.*;
public interface Bfr_arg_clearable extends Bfr_arg {
void Bfr_arg__clear();
boolean Bfr_arg__missing();
}

@ -1,19 +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.core.brys; import gplx.*; import gplx.core.*;
public interface Bry_bfr_able {
void To_bfr(Bry_bfr bfr);
}

@ -1,35 +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.core.brys; import gplx.*; import gplx.core.*;
public class Bry_bfr_able_ {
public static byte[][] To_bry_ary(Bry_bfr tmp_bfr, Bry_bfr_able[] ary) {
int len = ary.length;
byte[][] rv = new byte[len][];
for (int i = 0; i < len; ++i) {
Bry_bfr_able itm = ary[i];
if (itm != null) {
itm.To_bfr(tmp_bfr);
rv[i] = tmp_bfr.To_bry_and_clear();
}
}
return rv;
}
public static byte[] To_bry_or_null(Bry_bfr tmp_bfr, Bry_bfr_able itm) {
if (itm == null) return null;
itm.To_bfr(tmp_bfr);
return tmp_bfr.To_bry_and_clear();
}
}

@ -1,40 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.brys; import gplx.*; import gplx.core.*;
public class Bry_bfr_mkr {
public Bry_bfr Get_b128() {return mkr_b128.Get();} private final Bry_bfr_mkr_mgr mkr_b128 = new Bry_bfr_mkr_mgr(Tid_b128, 128);
public Bry_bfr Get_b512() {return mkr_b512.Get();} private final Bry_bfr_mkr_mgr mkr_b512 = new Bry_bfr_mkr_mgr(Tid_b512, 512);
public Bry_bfr Get_k004() {return mkr_k004.Get();} private final Bry_bfr_mkr_mgr mkr_k004 = new Bry_bfr_mkr_mgr(Tid_k004, 4 * Io_mgr.Len_kb);
public Bry_bfr Get_m001() {return mkr_m001.Get();} private final Bry_bfr_mkr_mgr mkr_m001 = new Bry_bfr_mkr_mgr(Tid_m001, 1 * Io_mgr.Len_mb);
public void Clear() {
for (byte i = Tid_b128; i <= Tid_m001; i++)
mkr(i).Clear();
}
public void Clear_fail_check() {
for (byte i = Tid_b128; i <= Tid_m001; i++)
mkr(i).Clear_fail_check();
}
private Bry_bfr_mkr_mgr mkr(byte tid) {
switch (tid) {
case Tid_b128: return mkr_b128;
case Tid_b512: return mkr_b512;
case Tid_k004: return mkr_k004;
case Tid_m001: return mkr_m001;
default: throw Err_.new_unhandled(tid);
}
}
public static final byte Tid_b128 = 0, Tid_b512 = 1, Tid_k004 = 2, Tid_m001 = 3;
}

@ -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.core.brys;
import gplx.Bry_bfr;
import gplx.Bry_bfr_;
import gplx.Err_;
import gplx.Int_;
import gplx.Int_ary_;
import gplx.objects.arrays.ArrayUtl;
public class Bry_bfr_mkr_mgr {
private final Object thread_lock = new Object();
private final byte mgr_id; private final int reset;
private Bry_bfr[] used = Bry_bfr_.Ary_empty; private int used_len = 0, used_max = 0;
private int[] free; private int free_len;
public Bry_bfr_mkr_mgr(byte mgr_id, int reset) {// NOTE: random IndexOutOfBounds errors in Get around free[--free_len] with free_len being -1; put member variable initialization within thread_lock to try to avoid; DATE:2014-09-21
this.mgr_id = mgr_id;
this.reset = reset;
this.free = Int_ary_.Empty;
this.free_len = 0;
}
public Bry_bfr Get() {
synchronized (thread_lock) {
Bry_bfr rv = null; int rv_idx = -1;
if (free_len > 0) {
try {rv_idx = free[--free_len];} catch (Exception e) {throw Err_.new_exc(e, "core", "failed to get free", "idx", free_len, "free_len", free.length);}
try {rv = used[rv_idx];} catch (Exception e) {throw Err_.new_exc(e, "core", "failed to get used", "idx", rv_idx, "used_len", used.length);}
}
else {
if (used_len == used_max) Expand();
rv_idx = used_len++;
rv = used[rv_idx];
if (rv == null) {
rv = Bry_bfr_.Reset(reset);
used[rv_idx] = rv;
}
}
rv.Mkr_init(this, rv_idx);
return rv.Clear(); // NOTE: ALWAYS call Clear when doing Get. caller may forget to call Clear, and reused bfr may have leftover bytes. unit tests will not catch, and difficult to spot in app
}
}
public void Rls(int idx) {
synchronized (thread_lock) {
if (idx == -1) throw Err_.new_wo_type("rls called on bfr that was not created by factory");
int new_used_len = used_len - 1;
if (idx == new_used_len)
used_len = new_used_len;
else
free[free_len++] = idx;
}
}
public void Clear_fail_check() {
synchronized (thread_lock) {
for (int i = 0; i < used_max; i++) {
Bry_bfr itm = used[i];
if (itm != null) {
if (!itm.Mkr_idx_is_null()) throw Err_.new_wo_type("failed to clear bfr", "mgr_id", mgr_id, "idx", Int_.To_str(i));
itm.Clear();
}
used[i] = null;
}
used = Bry_bfr_.Ary_empty;
free = Int_ary_.Empty;
free_len = used_len = used_max = 0;
}
}
public void Clear() {
synchronized (thread_lock) {
for (int i = 0; i < used_max; i++) {
Bry_bfr itm = used[i];
if (itm != null) itm.Clear();
used[i] = null;
}
used = Bry_bfr_.Ary_empty;
free = Int_ary_.Empty;
free_len = 0;
used_len = used_max = 0;
}
}
@gplx.Internal protected Bry_bfr[] Used() {return used;}
@gplx.Internal protected int Used_len() {return used_len;}
private void Expand() {
int new_max = used_max == 0 ? 2 : used_max * 2;
Bry_bfr[] new_ary = new Bry_bfr[new_max];
ArrayUtl.CopyTo(used, 0, new_ary, 0, used_max);
used = new_ary;
used_max = new_max;
int[] new_free = new int[used_max];
ArrayUtl.CopyTo(free, 0, new_free, 0, free_len);
free = new_free;
}
}

@ -1,55 +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.core.brys; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Bry_bfr_mkr_tst {
private final Bry_bfr_mkr_fxt fxt = new Bry_bfr_mkr_fxt();
@Before public void setup() {fxt.Clear();}
@Test public void Get_1() {fxt.Clear().Get().Test__used(0);}
@Test public void Get_2() {fxt.Clear().Get().Get().Test__used(0, 1);}
@Test public void Get_3() {fxt.Clear().Get().Get().Get().Test__used(0, 1, 2);}
@Test public void Rls() {fxt.Clear().Get().Rls(0).Test__used();}
@Test public void Rls_skip_1() {
fxt.Clear().Get().Get().Rls(0).Test__used(-1, 1);
fxt.Get().Test__used(0, 1);
}
@Test public void Rls_skip_2_1() {
fxt.Clear().Get().Get().Get().Rls(1).Rls(0).Test__used(-1, -1, 2);
fxt.Get().Test__used(0, -1, 2);
fxt.Get().Test__used(0, 1, 2);
fxt.Get().Test__used(0, 1, 2, 3);
}
@Test public void Get_rls_get() { // PURPOSE: defect in which last rls failed b/c was not doing ++ if rv existed
fxt.Clear().Get().Rls(0).Get().Get().Rls(1).Rls(0).Test__used();
}
}
class Bry_bfr_mkr_fxt {
private final Bry_bfr_mkr_mgr mkr = new Bry_bfr_mkr_mgr(Byte_.Zero, 32);
public Bry_bfr_mkr_fxt Clear() {mkr.Clear(); return this;}
public Bry_bfr_mkr_fxt Get() {mkr.Get(); return this;}
public Bry_bfr_mkr_fxt Rls(int i) {mkr.Used()[i].Mkr_rls(); return this;}
public Bry_bfr_mkr_fxt Test__used(int... expd) {
int actl_len = mkr.Used_len();
int[] actl = new int[actl_len];
for (int i = 0; i < actl_len; i++) {
Bry_bfr bfr = mkr.Used()[i];
int actl_val = bfr == null ? -2 : bfr.Mkr_idx();
actl[i] = actl_val;
}
Tfds.Eq_ary(expd, actl);
return this;
}
}

@ -1,270 +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.core.brys; import gplx.objects.primitives.BoolUtl;
import gplx.Bry_;
import gplx.Bry_find_;
import gplx.Byte_;
import gplx.objects.strings.AsciiByte;
import gplx.Double_;
import gplx.Int_;
import gplx.String_;
import gplx.core.btries.Btrie_rv;
import gplx.core.btries.Btrie_slim_mgr;
public class Bry_rdr {
private final gplx.core.primitives.Int_obj_ref pos_ref = gplx.core.primitives.Int_obj_ref.New_neg1();
private final Btrie_rv trv = new Btrie_rv();
public byte[] Src() {return src;} protected byte[] src;
public int Src_end() {return src_end;} protected int src_end;
public int Pos() {return pos;} protected int pos;
public boolean Pos_is_eos() {return pos == src_end;}
public boolean Pos_is_reading() {return pos > -1 && pos < src_end;}
public byte Cur() {return src[pos];}
public byte Nxt() {return pos + 1 >= src_end ? Not_found : src[pos + 1];}
public Bry_rdr Dflt_dlm_(byte b) {this.dflt_dlm = b; return this;} private byte dflt_dlm;
public Bry_rdr Fail_throws_err_(boolean v) {err_wkr.Fail_throws_err_(v); return this;}
public Bry_rdr Init_by_src(byte[] src) {err_wkr.Init_by_page("", src); this.pos = 0; this.src = src; this.src_end = src.length; return this;}
public Bry_rdr Init_by_page(byte[] page, byte[] src, int src_len) {err_wkr.Init_by_page(String_.new_u8(page), src); this.pos = 0; this.src = src; this.src_end = src_len; return this;}
public Bry_rdr Init_by_sect(String sect, int sect_bgn, int pos) {err_wkr.Init_by_sect(sect, sect_bgn); this.pos = pos; return this;}
public Bry_rdr Init_by_wkr (Bry_err_wkr wkr, String sect, int pos, int src_end) {
this.pos = pos; this.src = wkr.Src(); this.src_end = src_end;
err_wkr.Init_by_page(wkr.Page(), src);
err_wkr.Init_by_sect(sect, pos);
return this;
}
public Bry_err_wkr Err_wkr() {return err_wkr;} private Bry_err_wkr err_wkr = new Bry_err_wkr();
public int Move_to(int v) {this.pos = v; return pos;}
public int Move_to_last() {this.pos = src_end - 1; return pos;}
public int Move_to_end() {this.pos = src_end; return pos;}
public int Move_by_one() {return Move_by(1);}
public int Move_by(int v) {this.pos += v; return pos;}
public int Find_fwd_lr() {return Find_fwd(dflt_dlm , BoolUtl.Y, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_lr(byte find) {return Find_fwd(find , BoolUtl.Y, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_lr_or(byte find, int or)
{return Find_fwd(find , BoolUtl.Y, BoolUtl.N, or);}
public int Find_fwd_lr(String find) {return Find_fwd(Bry_.new_u8(find), BoolUtl.Y, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_lr(byte[] find) {return Find_fwd(find , BoolUtl.Y, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_lr_or(String find, int or) {return Find_fwd(Bry_.new_u8(find), BoolUtl.Y, BoolUtl.N, or);}
public int Find_fwd_lr_or(byte[] find, int or)
{return Find_fwd(find , BoolUtl.Y, BoolUtl.N, or);}
public int Find_fwd_rr() {return Find_fwd(dflt_dlm , BoolUtl.N, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_rr(byte find) {return Find_fwd(find , BoolUtl.N, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_rr(byte[] find) {return Find_fwd(find , BoolUtl.N, BoolUtl.N, Fail_if_missing);}
public int Find_fwd_rr_or(byte[] find, int or)
{return Find_fwd(find , BoolUtl.N, BoolUtl.N, or);}
private int Find_fwd(byte find, boolean ret_lhs, boolean pos_lhs, int or) {
int find_pos = Bry_find_.Find_fwd(src, find, pos, src_end);
if (find_pos == Bry_find_.Not_found) {
if (or == Fail_if_missing) {
err_wkr.Fail("find failed", "find", AsciiByte.ToStr(find));
return Bry_find_.Not_found;
}
else
return or;
}
pos = find_pos + (pos_lhs ? 0 : 1);
return ret_lhs ? find_pos : pos;
}
private int Find_fwd(byte[] find, boolean ret_lhs, boolean pos_lhs, int or) {
int find_pos = Bry_find_.Find_fwd(src, find, pos, src_end);
if (find_pos == Bry_find_.Not_found) {
if (or == Fail_if_missing) {
err_wkr.Fail("find failed", "find", String_.new_u8(find));
return Bry_find_.Not_found;
}
else
return or;
}
pos = find_pos + (pos_lhs ? 0 : find.length);
return ret_lhs ? find_pos : pos;
}
public byte Read_byte() {
byte rv = src[pos];
++pos;
return rv;
}
public byte Read_byte_to() {return Read_byte_to(dflt_dlm);}
public byte Read_byte_to(byte to_char) {
byte rv = src[pos];
++pos;
if (pos < src_end) {
if (src[pos] != to_char) {err_wkr.Fail("read byte to failed", "to", AsciiByte.ToStr(to_char)); return Byte_.Max_value_127;}
++pos;
}
return rv;
}
public double Read_double_to() {return Read_double_to(dflt_dlm);}
public double Read_double_to(byte to_char) {
byte[] bry = Read_bry_to(to_char);
return Double_.parse(String_.new_a7(bry));
}
public int Read_int_to() {return Read_int_to(dflt_dlm);}
public int Read_int_to_non_num() {return Read_int_to(AsciiByte.Null);}
public int Read_int_to(byte to_char) {
int bgn = pos;
int rv = 0;
int negative = 1;
while (pos < src_end) {
byte b = src[pos++];
switch (b) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
rv = (rv * 10) + (b - AsciiByte.Num0);
break;
case AsciiByte.Dash:
if (negative == -1) { // 2nd negative
err_wkr.Fail("invalid int", "mid", String_.new_u8(src, bgn, pos));
return Int_.Min_value;
}
else // 1st negative
negative = -1; // flag negative
break;
default: {
boolean match = b == to_char;
if (to_char == AsciiByte.Null) {// hack for Read_int_to_non_num
--pos;
match = true;
}
if (!match) {
err_wkr.Fail("invalid int", "mid", String_.new_u8(src, bgn, pos));
return Int_.Min_value;
}
return rv * negative;
}
}
}
if (bgn == pos) {err_wkr.Fail("int is empty"); return Int_.Min_value;}
return rv * negative;
}
public int Read_hzip_int(int reqd) {
int rv = gplx.core.encoders.Gfo_hzip_int_.Decode(reqd, src, src_end, pos, pos_ref);
pos = pos_ref.Val();
return rv;
}
public byte[] Read_bry_to() {return Read_bry_to(dflt_dlm);}
public byte[] Read_bry_to(byte b) {
int bgn = pos;
return Bry_.Mid(src, bgn, Find_fwd_lr(b));
}
public int Move_fwd_while(byte b) {
while (pos < src_end) {
if (src[pos] != b) {
break;
}
pos++;
}
return pos;
}
public int Move_bwd_while(byte b) {
while (pos > -1) {
if (src[pos] != b) {
return pos + 1; // return position which is start of b sequence
}
pos--;
}
return -1;
}
public boolean Match(byte[] find) { // same as Is but no auto-move
int find_len = find.length;
int find_end = pos + find_len;
return Bry_.Match(src, pos, find_end, find, 0, find_len);
}
public boolean Is(byte find) {
boolean rv = src[pos] == find;
if (rv) ++pos; // only advance if match;
return rv;
}
public boolean Is(byte[] find) {
int find_len = find.length;
int find_end = pos + find_len;
boolean rv = Bry_.Match(src, pos, find_end, find, 0, find_len);
if (rv) pos = find_end; // only advance if match;
return rv;
}
public int Chk(byte find) {
if (src[pos] != find) {err_wkr.Fail("failed check", "chk", Byte_.To_str(find)); return Bry_find_.Not_found;}
++pos;
return pos;
}
public int Chk(byte[] find) {
int find_end = pos + find.length;
if (!Bry_.Match(src, pos, find_end, find)) {err_wkr.Fail("failed check", "chk", String_.new_u8(find)); return Bry_find_.Not_found;}
pos = find_end;
return pos;
}
public byte Chk(Btrie_slim_mgr trie) {return Chk(trie, pos, src_end);}
public void Chk_trie_val(Btrie_slim_mgr trie, byte val) {
byte rv = Chk_or(trie, Byte_.Max_value_127);
if (rv == Byte_.Max_value_127) err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16)));
}
public Object Chk_trie_as_obj(Btrie_rv trv, Btrie_slim_mgr trie) {
Object rv = trie.Match_at(trv, src, pos, src_end); if (rv == null) err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16)));
return rv;
}
public byte Chk_or(Btrie_rv trv, Btrie_slim_mgr trie, byte or) {
Object rv_obj = trie.Match_at(trv, src, pos, src_end);
return rv_obj == null ? or : ((gplx.core.primitives.Byte_obj_val)rv_obj).Val();
}
public byte Chk_or(Btrie_slim_mgr trie, byte or) {return Chk_or(trie, pos, src_end, or);}
public byte Chk(Btrie_slim_mgr trie, int itm_bgn, int itm_end) {
byte rv = Chk_or(trie, itm_bgn, itm_end, Byte_.Max_value_127);
if (rv == Byte_.Max_value_127) {err_wkr.Fail("failed trie check", "mid", String_.new_u8(Bry_.Mid_by_len_safe(src, pos, 16))); return Byte_.Max_value_127;}
return rv;
}
public byte Chk_or(Btrie_slim_mgr trie, int itm_bgn, int itm_end, byte or) {
Object rv_obj = trie.Match_at(trv, src, itm_bgn, itm_end);
if (rv_obj == null) return or;
pos = trv.Pos();
return ((gplx.core.primitives.Byte_obj_val)rv_obj).Val();
}
public Bry_rdr Skip_ws() {
while (pos < src_end) {
switch (src[pos]) {
case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr: case AsciiByte.Space:
++pos;
break;
default:
return this;
}
}
return this;
}
public Bry_rdr Skip_alpha_num_under() {
while (pos < src_end) {
switch (src[pos]) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
case AsciiByte.Ltr_A: case AsciiByte.Ltr_B: case AsciiByte.Ltr_C: case AsciiByte.Ltr_D: case AsciiByte.Ltr_E:
case AsciiByte.Ltr_F: case AsciiByte.Ltr_G: case AsciiByte.Ltr_H: case AsciiByte.Ltr_I: case AsciiByte.Ltr_J:
case AsciiByte.Ltr_K: case AsciiByte.Ltr_L: case AsciiByte.Ltr_M: case AsciiByte.Ltr_N: case AsciiByte.Ltr_O:
case AsciiByte.Ltr_P: case AsciiByte.Ltr_Q: case AsciiByte.Ltr_R: case AsciiByte.Ltr_S: case AsciiByte.Ltr_T:
case AsciiByte.Ltr_U: case AsciiByte.Ltr_V: case AsciiByte.Ltr_W: case AsciiByte.Ltr_X: case AsciiByte.Ltr_Y: case AsciiByte.Ltr_Z:
case AsciiByte.Ltr_a: case AsciiByte.Ltr_b: case AsciiByte.Ltr_c: case AsciiByte.Ltr_d: case AsciiByte.Ltr_e:
case AsciiByte.Ltr_f: case AsciiByte.Ltr_g: case AsciiByte.Ltr_h: case AsciiByte.Ltr_i: case AsciiByte.Ltr_j:
case AsciiByte.Ltr_k: case AsciiByte.Ltr_l: case AsciiByte.Ltr_m: case AsciiByte.Ltr_n: case AsciiByte.Ltr_o:
case AsciiByte.Ltr_p: case AsciiByte.Ltr_q: case AsciiByte.Ltr_r: case AsciiByte.Ltr_s: case AsciiByte.Ltr_t:
case AsciiByte.Ltr_u: case AsciiByte.Ltr_v: case AsciiByte.Ltr_w: case AsciiByte.Ltr_x: case AsciiByte.Ltr_y: case AsciiByte.Ltr_z:
case AsciiByte.Underline:
++pos;
break;
default:
return this;
}
}
return this;
}
private static final int Fail_if_missing = Int_.Min_value;
public static final int Not_found = Bry_find_.Not_found;
}

@ -1,176 +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.core.brys;
import gplx.Bry_;
import gplx.Bry_find_;
import gplx.Double_;
import gplx.Err_;
import gplx.Gfo_usr_dlg_;
import gplx.Int_;
import gplx.String_;
import gplx.objects.primitives.BoolUtl;
import gplx.objects.strings.AsciiByte;
public class Bry_rdr_old {
private byte[] scope = Bry_.Empty;
public byte[] Src() {return src;} protected byte[] src;
public int Src_len() {return src_len;} protected int src_len;
public void Init(byte[] src) {this.Init(Bry_.Empty, src, 0);}
public void Init(byte[] src, int pos) {this.Init(Bry_.Empty, src, pos);}
public void Init(byte[] scope, byte[] src, int pos) {
this.src = src; this.src_len = src.length; this.pos = pos;
this.scope = scope;
}
public int Pos() {return pos;} public Bry_rdr_old Pos_(int v) {this.pos = v; return this;} protected int pos;
public void Pos_add(int v) {pos += v;}
public boolean Pos_is_eos() {return pos == src_len;}
public boolean Pos_is_reading() {return pos < src_len;}
public void Pos_add_one() {++pos;}
public int Or_int() {return or_int;} public void Or_int_(int v) {or_int = v;} private int or_int = Int_.Min_value;
public byte[] Or_bry() {return or_bry;} public void Or_bry_(byte[] v) {or_bry = v;} private byte[] or_bry;
public int Find_fwd(byte find) {return Bry_find_.Find_fwd(src, find, pos);}
public int Find_fwd_ws() {return Bry_find_.Find_fwd_until_ws(src, pos, src_len);}
public int Find_fwd__pos_at_lhs(byte[] find_bry) {return Find_fwd__pos_at(find_bry, BoolUtl.N);}
public int Find_fwd__pos_at_rhs(byte[] find_bry) {return Find_fwd__pos_at(find_bry, BoolUtl.Y);}
public int Find_fwd__pos_at(byte[] find_bry, boolean pos_at_rhs) {
int find_pos = Bry_find_.Find_fwd(src, find_bry, pos, src_len);
if (pos_at_rhs) find_pos += find_bry.length;
if (find_pos != Bry_find_.Not_found) pos = find_pos;
return find_pos;
}
public byte Read_byte() {return src[pos];}
public int Read_int_to_semic() {return Read_int_to(AsciiByte.Semic);}
public int Read_int_to_comma() {return Read_int_to(AsciiByte.Comma);}
public int Read_int_to_pipe() {return Read_int_to(AsciiByte.Pipe);}
public int Read_int_to_nl() {return Read_int_to(AsciiByte.Nl);}
public int Read_int_to_quote() {return Read_int_to(AsciiByte.Quote);}
public int Read_int_to_non_num(){return Read_int_to(AsciiByte.Null);}
public int Read_int_to(byte to_char) {
int bgn = pos;
int rv = 0;
int negative = 1;
while (pos < src_len) {
byte b = src[pos++];
switch (b) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
rv = (rv * 10) + (b - AsciiByte.Num0);
break;
case AsciiByte.Dash:
if (negative == -1) // 2nd negative
return or_int; // return or_int
else // 1st negative
negative = -1; // flag negative
break;
default: {
boolean match = b == to_char;
if (to_char == AsciiByte.Null) {// hack for Read_int_to_non_num
--pos;
match = true;
}
return match ? rv * negative : or_int;
}
}
}
return bgn == pos ? or_int : rv * negative;
}
public byte[] Read_bry_to_nl() {return Read_bry_to(AsciiByte.Nl);}
public byte[] Read_bry_to_semic() {return Read_bry_to(AsciiByte.Semic);}
public byte[] Read_bry_to_pipe() {return Read_bry_to(AsciiByte.Pipe);}
public byte[] Read_bry_to_quote() {return Read_bry_to(AsciiByte.Quote);}
public byte[] Read_bry_to_apos() {return Read_bry_to(AsciiByte.Apos);}
public byte[] Read_bry_to(byte to_char) {
int bgn = pos;
while (pos < src_len) {
byte b = src[pos];
if (b == to_char)
return Bry_.Mid(src, bgn, pos++);
else
++pos;
}
return bgn == pos ? or_bry : Bry_.Mid(src, bgn, src_len);
}
public boolean Read_yn_to_pipe() {return Read_byte_to_pipe() == AsciiByte.Ltr_y;}
public byte Read_byte_to_pipe() {
byte rv = src[pos];
pos += 2; // 1 for byte; 1 for pipe;
return rv;
}
public double Read_double_to_pipe() {return Read_double_to(AsciiByte.Pipe);}
public double Read_double_to(byte to_char) {
byte[] double_bry = Read_bry_to(to_char);
return Double_.parse(String_.new_a7(double_bry)); // double will never have utf8
}
public Bry_rdr_old Skip_ws() {
while (pos < src_len) {
switch (src[pos]) {
case AsciiByte.Tab: case AsciiByte.Nl: case AsciiByte.Cr: case AsciiByte.Space:
++pos;
break;
default:
return this;
}
}
return this;
}
public Bry_rdr_old Skip_alpha_num_under() {
while (pos < src_len) {
switch (src[pos]) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
case AsciiByte.Ltr_A: case AsciiByte.Ltr_B: case AsciiByte.Ltr_C: case AsciiByte.Ltr_D: case AsciiByte.Ltr_E:
case AsciiByte.Ltr_F: case AsciiByte.Ltr_G: case AsciiByte.Ltr_H: case AsciiByte.Ltr_I: case AsciiByte.Ltr_J:
case AsciiByte.Ltr_K: case AsciiByte.Ltr_L: case AsciiByte.Ltr_M: case AsciiByte.Ltr_N: case AsciiByte.Ltr_O:
case AsciiByte.Ltr_P: case AsciiByte.Ltr_Q: case AsciiByte.Ltr_R: case AsciiByte.Ltr_S: case AsciiByte.Ltr_T:
case AsciiByte.Ltr_U: case AsciiByte.Ltr_V: case AsciiByte.Ltr_W: case AsciiByte.Ltr_X: case AsciiByte.Ltr_Y: case AsciiByte.Ltr_Z:
case AsciiByte.Ltr_a: case AsciiByte.Ltr_b: case AsciiByte.Ltr_c: case AsciiByte.Ltr_d: case AsciiByte.Ltr_e:
case AsciiByte.Ltr_f: case AsciiByte.Ltr_g: case AsciiByte.Ltr_h: case AsciiByte.Ltr_i: case AsciiByte.Ltr_j:
case AsciiByte.Ltr_k: case AsciiByte.Ltr_l: case AsciiByte.Ltr_m: case AsciiByte.Ltr_n: case AsciiByte.Ltr_o:
case AsciiByte.Ltr_p: case AsciiByte.Ltr_q: case AsciiByte.Ltr_r: case AsciiByte.Ltr_s: case AsciiByte.Ltr_t:
case AsciiByte.Ltr_u: case AsciiByte.Ltr_v: case AsciiByte.Ltr_w: case AsciiByte.Ltr_x: case AsciiByte.Ltr_y: case AsciiByte.Ltr_z:
case AsciiByte.Underline:
++pos;
break;
default:
return this;
}
}
return this;
}
public void Chk_bry_or_fail(byte[] bry) {
int bry_len = bry.length;
boolean match = Bry_.Match(src, pos, pos + bry_len, bry);
if (match) pos += bry_len;
else throw Err_.new_wo_type("bry.rdr:chk failed", "bry", bry, "pos", pos);
}
public void Chk_byte_or_fail(byte b) {
boolean match = pos < src_len ? src[pos] == b : false;
if (match) ++pos;
else throw Err_.new_wo_type("bry.rdr:chk failed", "byte", b, "pos", pos);
}
public byte[] Mid_by_len_safe(int len) {
int end = pos + len; if (end > src_len) end = src_len;
return Bry_.Mid(src, pos, end);
}
public boolean Chk_bry_wo_move(byte[] bry, int pos) {
int bry_len = bry.length;
return Bry_.Match(src, pos, pos + bry_len, bry);
}
public int Warn(String err, int bgn, int rv) {
int end = rv + 256; if (end > src_len) end = src_len;
Gfo_usr_dlg_.Instance.Warn_many("", "", "read failed: scope=~{0} err=~{1} mid=~{2}", scope, err, String_.new_u8(src, bgn, end));
return rv + 1; // rv is always hook_bgn; add +1 to set at next character, else infinite loop
}
}

@ -1,54 +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.core.brys; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Bry_rdr_tst {
@Before public void init() {fxt.Clear();} private Bry_rdr_fxt fxt = new Bry_rdr_fxt();
@Test public void Int() {
fxt.Init_src("12|3456|789");
fxt.Test_read_int(12);
fxt.Test_read_int(3456);
fxt.Test_read_int(789);
fxt.Test_read_int(Int_.Min_value);
}
@Test public void Int_negative() {
fxt.Init_src("-1|-2");
fxt.Test_read_int(-1);
fxt.Test_read_int(-2);
}
@Test public void Bry() {
fxt.Init_src("abc|d||ef");
fxt.Test_read_bry("abc");
fxt.Test_read_bry("d");
fxt.Test_read_bry("");
fxt.Test_read_bry("ef");
fxt.Test_read_bry(null);
}
}
class Bry_rdr_fxt {
private Bry_rdr_old rdr;
public void Clear() {rdr = new Bry_rdr_old();}
public Bry_rdr_fxt Init_src(String v) {rdr.Init(Bry_.new_u8(v)); return this;}
public Bry_rdr_fxt Init_pos(int v) {rdr.Pos_(v); return this;}
public void Test_read_int(int expd_val) {
Tfds.Eq(expd_val, rdr.Read_int_to_pipe());
}
public void Test_read_bry(String expd_str) {
byte[] actl_bry = rdr.Read_bry_to_pipe();
String actl_str = actl_bry == null ? null : String_.new_u8(actl_bry);
Tfds.Eq(expd_str, actl_str);
}
}

@ -1,41 +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.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__bry implements Bfr_arg_clearable {
private int tid;
private byte[] src; private int src_bgn, src_end;
private Bfr_arg arg;
public void Set_by_mid(byte[] src, int bgn, int end) {this.tid = Tid_mid; this.src = src; this.src_bgn = bgn; this.src_end = end;}
public void Set_by_val(byte[] src) {this.tid = Tid_val; this.src = src;}
public void Set_by_arg(Bfr_arg arg) {this.tid = Tid_arg; this.arg = arg;}
public void Bfr_arg__clear() {
tid = Tid_nil;
src = null; src_bgn = src_end = -1;
arg = null;
}
public boolean Bfr_arg__missing() {return tid == Tid_nil;}
public void Bfr_arg__add(Bry_bfr bfr) {
switch (tid) {
case Tid_val: bfr.Add(src); break;
case Tid_mid: bfr.Add_mid(src, src_bgn, src_end); break;
case Tid_arg: arg.Bfr_arg__add(bfr); break;
case Tid_nil: break;
}
}
public static Bfr_arg__bry New_empty() {return new Bfr_arg__bry();}
public static Bfr_arg__bry New(byte[] v) {Bfr_arg__bry rv = new Bfr_arg__bry(); rv.Set_by_val(v); return rv;}
private static final int Tid_nil = 0, Tid_val = 1, Tid_mid = 2, Tid_arg = 3;
}

@ -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.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.core.brys.*;
public class Bfr_arg__bry_fmt implements Bfr_arg {
private final Bry_fmt fmt;
private Object[] arg_ary;
public Bfr_arg__bry_fmt(Bry_fmt fmt, Object... arg_ary) {
this.fmt = fmt;
Args_(arg_ary);
}
public void Bfr_arg__clear() {arg_ary = null;}
public boolean Bfr_arg__missing() {return arg_ary == null;}
public Bfr_arg__bry_fmt Args_(Object... arg_ary) {
this.arg_ary = arg_ary;
return this;
}
public void Bfr_arg__add(Bry_bfr bfr) {
if (Bfr_arg__missing()) return;
fmt.Bld_many(bfr, arg_ary);
}
}

@ -1,26 +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.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.core.brys.fmtrs.*;
public class Bfr_arg__bry_fmtr implements Bfr_arg {
private Bry_fmtr fmtr; private Object[] arg_ary;
public Bfr_arg__bry_fmtr(Bry_fmtr fmtr, Object[] arg_ary) {Set(fmtr, arg_ary);}
public Bfr_arg__bry_fmtr Set(Bry_fmtr fmtr, Object... arg_ary) {
this.fmtr = fmtr; this.arg_ary = arg_ary;
return this;
}
public void Bfr_arg__add(Bry_bfr bfr) {fmtr.Bld_bfr_many(bfr, arg_ary);}
}

@ -1,21 +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.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__byte implements Bfr_arg {
private final byte byt;
public Bfr_arg__byte(byte byt) {this.byt = byt;}
public void Bfr_arg__add(Bry_bfr bfr) {bfr.Add_byte(byt);}
}

@ -1,25 +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.core.brys.args; import gplx.*;
import gplx.core.brys.*;
import gplx.objects.strings.AsciiByte;
public class Bfr_arg__decimal_int implements Bfr_arg {
public int Val() {return val;} public Bfr_arg__decimal_int Val_(int v) {val = v; return this;} int val;
public Bfr_arg__decimal_int Places_(int v) {places = v; multiple = (int)Math_.Pow(10, v); return this;} int multiple = 1000, places = 3;
public void Bfr_arg__add(Bry_bfr bfr) {
bfr.Add_int_variable(val / multiple).Add_byte(AsciiByte.Dot).Add_int_fixed(val % multiple, places);
}
}

@ -1,26 +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.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__int implements Bfr_arg {
private int val, val_digits;
public Bfr_arg__int(int v) {Set(v);}
public Bfr_arg__int Set(int v) {
this.val = Int_.Cast(v);
this.val_digits = Int_.DigitCount(val);
return this;
}
public void Bfr_arg__add(Bry_bfr bfr) {bfr.Add_int_digits(val_digits, val);}
}

@ -1,55 +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.core.brys.args; import gplx.*;
import gplx.core.brys.*;
import gplx.objects.strings.AsciiByte;
public class Bfr_arg__time implements Bfr_arg {
public Bfr_arg__time() {
units_len = units.length;
}
public long Seconds() {return seconds;} public Bfr_arg__time Seconds_(long v) {seconds = v; return this;} long seconds;
byte[][] segs = new byte[][]
{ Bry_.new_a7("d")
, Bry_.new_a7("h")
, Bry_.new_a7("m")
, Bry_.new_a7("s")
};
int[] units = new int[] {86400, 3600, 60, 1};
int units_len;
byte[] spr = new byte[] {AsciiByte.Space};
public void Bfr_arg__add(Bry_bfr bfr) {
if (seconds == 0) { // handle 0 separately (since it will always be < than units[*]
bfr.Add_int_fixed(0, 2).Add(segs[units_len - 1]);
return;
}
long val = seconds;
boolean dirty = false;
for (int i = 0; i < units_len; i++) {
long unit = units[i];
long seg = 0;
if (val >= unit) { // unit has value; EX: 87000 > 86400, so unit is 1 day
seg = val / unit;
val = val - (seg * unit);
}
if (seg > 0 || dirty) { // dirty check allows for 0 in middle units (EX: 1h 0m 1s)
if (dirty) bfr.Add(spr);
if (seg < 10) bfr.Add_byte(AsciiByte.Num0); // 0 pad
bfr.Add_long_variable(seg).Add(segs[i]);
dirty = true;
}
}
}
}

@ -1,40 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import org.junit.*;
public class Bfr_arg__time_tst {
@Test public void Basic() {
Time_fmtr_arg_fxt fxt = new Time_fmtr_arg_fxt().Clear();
fxt.XferAry( 1, "01s"); // seconds
fxt.XferAry( 62, "01m 02s"); // minutes
fxt.XferAry( 3723, "01h 02m 03s"); // hours
fxt.XferAry( 93784, "01d 02h 03m 04s"); // days
fxt.XferAry( 0, "00s"); // handle 0 seconds
fxt.XferAry( 3601, "01h 00m 01s"); // handle 0 in middle unit
}
}
class Time_fmtr_arg_fxt {
public Time_fmtr_arg_fxt Clear() {
if (arg == null) arg = new Bfr_arg__time();
return this;
} Bfr_arg__time arg;
public void XferAry(int seconds, String expd) {
Bry_bfr bfr = Bry_bfr_.Reset(255);
arg.Seconds_(seconds);
arg.Bfr_arg__add(bfr);
Tfds.Eq(expd, bfr.To_str());
}
}

@ -1,270 +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.core.brys.fmtrs; import gplx.*;
import gplx.core.brys.*;
import gplx.core.primitives.*; import gplx.core.strings.*;
import gplx.objects.strings.AsciiByte;
public class Bry_fmtr {
public byte[] Fmt() {return fmt;} private byte[] fmt = Bry_.Empty;
public boolean Fmt_null() {return fmt.length == 0;}
public Bry_fmtr_eval_mgr Eval_mgr() {return eval_mgr;} public Bry_fmtr Eval_mgr_(Bry_fmtr_eval_mgr v) {eval_mgr = v; return this;} Bry_fmtr_eval_mgr eval_mgr = Bry_fmtr_eval_mgr_gfs.Instance;
public Bry_fmtr Fmt_(byte[] v) {fmt = v; dirty = true; return this;} public Bry_fmtr Fmt_(String v) {return Fmt_(Bry_.new_u8(v));}
public Bry_fmtr Keys_(String... ary) {
if (keys == null) keys = Hash_adp_.New();
else keys.Clear();
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
keys.Add(Bry_obj_ref.New(Bry_.new_u8(ary[i])), new Int_obj_val(i));
dirty = true;
return this;
} Hash_adp keys = null;
public void Bld_bfr(Bry_bfr bfr, byte[]... args) {
if (dirty) Compile();
int args_len = args.length;
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg) {
int arg_idx = itm.ArgIdx;
if (arg_idx < args_len)
bfr.Add(args[arg_idx]);
else
bfr.Add(missing_bgn).Add_int_variable(arg_idx + missing_adj).Add(missing_end);
}
else
bfr.Add(itm.Dat);
}
}
public void Bld_bfr_none(Bry_bfr bfr) {
if (dirty) Compile();
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg)
bfr.Add_byte(char_escape).Add_byte(char_arg_bgn).Add_int_variable(itm.ArgIdx).Add_byte(char_arg_end);
else
bfr.Add(itm.Dat);
}
}
public void Bld_bfr(Bry_bfr bfr, Bfr_arg... args) {
if (dirty) Compile();
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg)
args[itm.ArgIdx].Bfr_arg__add(bfr);
else
bfr.Add(itm.Dat);
}
}
public void Bld_bfr_one(Bry_bfr bfr, Object val) {
Bld_bfr_one_ary[0] = val;
Bld_bfr_ary(bfr, Bld_bfr_one_ary);
} Object[] Bld_bfr_one_ary = new Object[1];
public void Bld_bfr_many(Bry_bfr bfr, Object... args) {Bld_bfr_ary(bfr, args);}
public void Bld_bfr_ary(Bry_bfr bfr, Object[] args) {
if (dirty) Compile();
int args_len = args.length;
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg) {
int arg_idx = itm.ArgIdx;
if (arg_idx > -1 && arg_idx < args_len)
bfr.Add_obj(args[itm.ArgIdx]);
else
bfr.Add_byte(char_escape).Add_byte(char_arg_bgn).Add_int_variable(arg_idx).Add_byte(char_arg_end);
}
else
bfr.Add(itm.Dat);
}
}
public byte[] Bld_bry_none(Bry_bfr bfr) {Bld_bfr_ary(bfr, Object_.Ary_empty); return bfr.To_bry_and_clear();}
public byte[] Bld_bry_many(Bry_bfr bfr, Object... args) {
Bld_bfr_ary(bfr, args);
return bfr.To_bry_and_clear();
}
public String Bld_str_many(Bry_bfr bfr, String fmt, Object... args) {
this.Fmt_(fmt).Bld_bfr_many(bfr, args);
return bfr.To_str_and_clear();
}
public String Bld_str_many(String... args) {
if (dirty) Compile();
String_bldr rv = String_bldr_.new_();
int args_len = args.length;
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg) {
int arg_idx = itm.ArgIdx;
if (arg_idx < args_len)
rv.Add(args[arg_idx]);
else
rv.Add(missing_bgn).Add(arg_idx + missing_adj).Add(missing_end);
}
else
rv.Add(itm.DatStr());
}
return rv.To_str();
} private Bry_fmtr_itm[] itms; int itms_len;
public byte[] Missing_bgn() {return missing_bgn;} public Bry_fmtr Missing_bgn_(byte[] v) {missing_bgn = v; return this;} private byte[] missing_bgn = missing_bgn_static; static byte[] missing_bgn_static = Bry_.new_u8("~{"), missing_end_static = Bry_.new_u8("}");
public byte[] Missing_end() {return missing_end;} public Bry_fmtr Missing_end_(byte[] v) {missing_end = v; return this;} private byte[] missing_end = missing_end_static;
public int Missing_adj() {return missing_adj;} public Bry_fmtr Missing_adj_(int v) {missing_adj = v; return this;} int missing_adj;
public boolean Fail_when_invalid_escapes() {return fail_when_invalid_escapes;} public Bry_fmtr Fail_when_invalid_escapes_(boolean v) {fail_when_invalid_escapes = v; return this;} private boolean fail_when_invalid_escapes = true;
public Bry_fmtr Compile() {
synchronized (this) { // THREAD: DATE:2015-04-29
Bry_bfr lkp_bfr = Bry_bfr_.New_w_size(16);
int fmt_len = fmt.length; int fmt_end = fmt_len - 1; int fmt_pos = 0;
byte[] trg_bry = new byte[fmt_len]; int trg_pos = 0;
boolean lkp_is_active = false, lkp_is_numeric = true;
byte nxt_byte, tmp_byte;
boolean dirty_disable = true;
List_adp list = List_adp_.New();
fmt_args_exist = false;
while (true) {
if (fmt_pos > fmt_end) break;
byte cur_byte = fmt[fmt_pos];
if (lkp_is_active) {
if (cur_byte == char_arg_end) {
if (lkp_is_numeric)
list.Add(Bry_fmtr_itm.arg_(lkp_bfr.To_int(0) - baseInt));
else {
byte[] key_fmt = lkp_bfr.To_bry();
Object idx_ref = keys.GetByOrNull(Bry_obj_ref.New(key_fmt));
if (idx_ref == null) {
int lkp_bfr_len = lkp_bfr.Len();
byte[] lkp_bry = lkp_bfr.Bfr();
trg_bry[trg_pos++] = char_escape;
trg_bry[trg_pos++] = char_arg_bgn;
for (int i = 0; i < lkp_bfr_len; i++)
trg_bry[trg_pos++] = lkp_bry[i];
trg_bry[trg_pos++] = char_arg_end;
}
else {
list.Add(Bry_fmtr_itm.arg_(((Int_obj_val)idx_ref).Val() - baseInt));
}
}
lkp_is_active = false;
lkp_bfr.Clear();
fmt_args_exist = true;
}
else {
lkp_bfr.Add_byte(cur_byte);
switch (cur_byte) {
case AsciiByte.Num0: case AsciiByte.Num1: case AsciiByte.Num2: case AsciiByte.Num3: case AsciiByte.Num4:
case AsciiByte.Num5: case AsciiByte.Num6: case AsciiByte.Num7: case AsciiByte.Num8: case AsciiByte.Num9:
break;
default:
lkp_is_numeric = false;
break;
}
}
fmt_pos += 1;
}
else if (cur_byte == char_escape) {
if (fmt_pos == fmt_end) {
if (fail_when_invalid_escapes)
throw Err_.new_wo_type("escape char encountered but no more chars left");
else {
trg_bry[trg_pos] = cur_byte;
break;
}
}
nxt_byte = fmt[fmt_pos + 1];
if (nxt_byte == char_arg_bgn) {
if (trg_pos > 0) {list.Add(Bry_fmtr_itm.dat_(trg_bry, trg_pos)); trg_pos = 0;} // something pending; add it to list
int eval_lhs_bgn = fmt_pos + 2;
if (eval_lhs_bgn < fmt_len && fmt[eval_lhs_bgn] == char_eval_bgn) { // eval found
dirty_disable = false; // eval allows args to retrigger compiles; this is probably not used, but just in case, do not disable dirty; TEST: Tfds.Eq("012~{<>3<>}4", fmtr.Bld_str_many("1"));
fmt_pos = Compile_eval_cmd(fmt, fmt_len, eval_lhs_bgn, list);
continue;
}
else {
lkp_is_active = true;
lkp_is_numeric = true;
}
}
else { // ~{0}; ~~ -> ~; ~n -> newLine; ~t -> tab
if (nxt_byte == char_escape) tmp_byte = char_escape;
else if (nxt_byte == char_escape_nl) tmp_byte = AsciiByte.Nl;
else if (nxt_byte == char_escape_tab) tmp_byte = AsciiByte.Tab;
else {
if (fail_when_invalid_escapes) throw Err_.new_wo_type("unknown escape code", "code", Char_.By_int(nxt_byte), "fmt_pos", fmt_pos + 1);
else
tmp_byte = cur_byte;
}
trg_bry[trg_pos++] = tmp_byte;
}
fmt_pos += 2;
}
else {
trg_bry[trg_pos++] = cur_byte;
fmt_pos += 1;
}
}
if (lkp_is_active) throw Err_.new_wo_type("idx mode not closed");
if (trg_pos > 0) {list.Add(Bry_fmtr_itm.dat_(trg_bry, trg_pos)); trg_pos = 0;}
itms = (Bry_fmtr_itm[])list.ToAry(Bry_fmtr_itm.class);
itms_len = itms.length;
if (dirty_disable)
dirty = false; // ISSUE#:575; DATE:2019-09-16
return this;
}
}
int Compile_eval_cmd(byte[] fmt, int fmt_len, int eval_lhs_bgn, List_adp list) {
int eval_lhs_end = Bry_find_.Find_fwd(fmt, char_eval_end, eval_lhs_bgn + AsciiByte.Len1, fmt_len); if (eval_lhs_end == Bry_find_.Not_found) throw Err_.new_wo_type("eval_lhs_end_invalid: could not find eval_lhs_end", "snip", String_.new_u8(fmt, eval_lhs_bgn, fmt_len));
byte[] eval_dlm = Bry_.Mid(fmt, eval_lhs_bgn , eval_lhs_end + AsciiByte.Len1);
int eval_rhs_bgn = Bry_find_.Find_fwd(fmt, eval_dlm , eval_lhs_end + AsciiByte.Len1, fmt_len); if (eval_rhs_bgn == Bry_find_.Not_found) throw Err_.new_wo_type("eval_rhs_bgn_invalid: could not find eval_rhs_bgn", "snip", String_.new_u8(fmt, eval_lhs_end, fmt_len));
byte[] eval_cmd = Bry_.Mid(fmt, eval_lhs_end + AsciiByte.Len1, eval_rhs_bgn);
byte[] eval_rslt = eval_mgr.Eval(eval_cmd);
int eval_rhs_end = eval_rhs_bgn + AsciiByte.Len1 + eval_dlm.length;
if (eval_rslt == null) eval_rslt = Bry_.Mid(fmt, eval_lhs_bgn - 2, eval_rhs_end); // not found; return original argument
list.Add(Bry_fmtr_itm.dat_bry_(eval_rslt));
return eval_rhs_end;
}
static final String GRP_KEY = "gplx.Bry_fmtr";
public boolean Fmt_args_exist() {return fmt_args_exist;} private boolean fmt_args_exist;
boolean dirty = true;
int baseInt = 0;
public static final byte char_escape = AsciiByte.Tilde, char_arg_bgn = AsciiByte.CurlyBgn, char_arg_end = AsciiByte.CurlyEnd, char_escape_nl = AsciiByte.Ltr_n, char_escape_tab = AsciiByte.Ltr_t, char_eval_bgn = AsciiByte.Lt, char_eval_end = AsciiByte.Gt;
public static final Bry_fmtr Null = new Bry_fmtr().Fmt_("");
public static Bry_fmtr New__tmp() {return new Bry_fmtr().Fmt_("").Keys_();}
public static Bry_fmtr new_(String fmt, String... keys) {return new Bry_fmtr().Fmt_(fmt).Keys_(keys);} // NOTE: keys may seem redundant, but are needed to align ordinals with proc; EX: fmt may be "~{A} ~{B}" or "~{B} ~{A}"; call will always be Bld(a, b); passing in "A", "B" guarantees A is 0 and B is 1;
public static Bry_fmtr new_(byte[] fmt, String... keys) {return new Bry_fmtr().Fmt_(fmt).Keys_(keys);} // NOTE: keys may seem redundant, but are needed to align ordinals with proc; EX: fmt may be "~{A} ~{B}" or "~{B} ~{A}"; call will always be Bld(a, b); passing in "A", "B" guarantees A is 0 and B is 1;
public static Bry_fmtr new_() {return new Bry_fmtr();}
public static Bry_fmtr keys_(String... keys) {return new Bry_fmtr().Keys_(keys);}
public static Bry_fmtr new_bry_(byte[] fmt, String... keys) {return new Bry_fmtr().Fmt_(fmt).Keys_(keys);}
public static String New_fmt_str(String key, Object[] args) {
tmp_bfr.Clear();
tmp_bfr.Add_str_u8(key);
tmp_bfr.Add_byte(AsciiByte.Colon);
int args_len = args.length;
for (int i = 0; i < args_len; i++) { // add " 0='~{0}'"
tmp_bfr.Add_byte(AsciiByte.Space);
tmp_bfr.Add_int_variable(i);
tmp_bfr.Add_byte(AsciiByte.Eq);
tmp_bfr.Add_byte(AsciiByte.Apos);
tmp_bfr.Add_byte(AsciiByte.Tilde);
tmp_bfr.Add_byte(AsciiByte.CurlyBgn);
tmp_bfr.Add_int_variable(i);
tmp_bfr.Add_byte(AsciiByte.CurlyEnd);
tmp_bfr.Add_byte(AsciiByte.Apos);
}
return tmp_bfr.To_str_and_clear();
} static Bry_bfr tmp_bfr = Bry_bfr_.Reset(255);
public void Bld_bfr_many_and_set_fmt(Object... args) {
Bry_bfr bfr = Bry_bfr_.New();
this.Bld_bfr_many(bfr, args);
byte[] bry = bfr.To_bry_and_clear();
this.Fmt_(bry).Compile();
}
public static String Escape_tilde(String v) {return String_.Replace(v, "~", "~~");}
}

@ -1,20 +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.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public interface Bry_fmtr_eval_mgr {
boolean Enabled(); void Enabled_(boolean v);
byte[] Eval(byte[] cmd);
}

@ -1,25 +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.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bry_fmtr_eval_mgr_ {
public static Io_url Eval_url(Bry_fmtr_eval_mgr eval_mgr, byte[] fmt) {
if (eval_mgr == null) return Io_url_.new_any_(String_.new_u8(fmt));
Bry_bfr bfr = Bry_bfr_.Reset(255);
Bry_fmtr fmtr = Bry_fmtr.New__tmp();
fmtr.Eval_mgr_(eval_mgr).Fmt_(fmt).Bld_bfr_none(bfr);
return Io_url_.new_any_(bfr.To_str_and_clear());
}
}

@ -1,24 +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.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.langs.gfs.*;
public class Bry_fmtr_eval_mgr_gfs implements Bry_fmtr_eval_mgr {
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public byte[] Eval(byte[] cmd) {
return enabled ? Bry_.new_u8(Object_.Xto_str_strict_or_null_mark(GfsCore.Instance.ExecText(String_.new_u8(cmd)))) : null;
}
public static final Bry_fmtr_eval_mgr_gfs Instance = new Bry_fmtr_eval_mgr_gfs(); Bry_fmtr_eval_mgr_gfs() {}
}

@ -1,31 +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.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bry_fmtr_itm {
Bry_fmtr_itm(boolean arg, int argIdx, byte[] dat) {
this.Arg = arg; this.ArgIdx = argIdx; this.Dat = dat;
}
public boolean Arg;
public int ArgIdx;
public byte[] Dat;
public String DatStr() {
if (datStr == null) datStr = String_.new_u8(Dat);
return datStr;
} String datStr;
public static Bry_fmtr_itm arg_(int idx) {return new Bry_fmtr_itm(true, idx, Bry_.Empty);}
public static Bry_fmtr_itm dat_(byte[] dat, int len) {return new Bry_fmtr_itm(false, -1, Bry_.Mid(dat, 0, len));}
public static Bry_fmtr_itm dat_bry_(byte[] bry) {return new Bry_fmtr_itm(false, -1, bry);}
}

@ -1,72 +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.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import org.junit.*;
public class Bry_fmtr_tst {
private final Bry_fmtr_fxt fxt = new Bry_fmtr_fxt();
@Test public void Text() {fxt.Clear().Fmt("a").Test("a");}
@Test public void Idx__1() {fxt.Clear().Fmt("~{0}").Args("a").Test("a");}
@Test public void Idx__3() {fxt.Clear().Fmt("~{0}~{1}~{2}").Args("a", "b", "c").Test("abc");}
@Test public void Idx__mix() {fxt.Clear().Fmt("a~{0}c~{1}e").Args("b", "d").Test("abcde");}
@Test public void Idx__missing() {fxt.Clear().Fmt("~{0}").Test("~{0}");}
@Test public void Key__basic() {fxt.Clear().Fmt("~{key}").Keys("key").Args("a").Test("a");}
@Test public void Key__mult() {fxt.Clear().Fmt("~{key1}~{key2}").Keys("key1", "key2").Args("a", "b").Test("ab");}
@Test public void Key__repeat() {fxt.Clear().Fmt("~{key1}~{key1}").Keys("key1").Args("a").Test("aa");}
@Test public void Mix() {fxt.Clear().Fmt("~{key1}~{1}").Keys("key1", "key2").Args("a", "b").Test("ab");}
@Test public void Simple() {
fxt.Clear().Fmt("0~{key1}1~{key2}2").Keys("key1", "key2").Args(".", ",").Test("0.1,2");
}
@Test public void Cmd() {
Bry_fmtr_tst_mok mok = new Bry_fmtr_tst_mok();
Bry_fmtr fmtr = Bry_fmtr.new_("0~{key1}2~{<>3<>}4", "key1").Eval_mgr_(mok);
Tfds.Eq("012~{<>3<>}4", fmtr.Bld_str_many("1"));
mok.Enabled_(true);
Tfds.Eq("01234", fmtr.Bld_str_many("1"));
}
@Test public void Bld_bfr_many_and_set_fmt() {
fxt.Bld_bfr_many_and_set_fmt("a~{0}c", Object_.Ary("b"), "abc");
}
@Test public void Escape_tilde() {
Tfds.Eq("~~~~~~", Bry_fmtr.Escape_tilde("~~~"));
}
}
class Bry_fmtr_tst_mok implements Bry_fmtr_eval_mgr {
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public byte[] Eval(byte[] cmd) {
return enabled ? cmd : null;
}
}
class Bry_fmtr_fxt {
private final Bry_fmtr fmtr = Bry_fmtr.new_();
private final Bry_bfr bfr = Bry_bfr_.New();
private Object[] args;
public Bry_fmtr_fxt Clear() {fmtr.Fmt_(String_.Empty).Keys_(String_.Empty); args = Object_.Ary_empty; return this;}
public Bry_fmtr_fxt Fmt (String fmt) {fmtr.Fmt_(fmt); return this;}
public Bry_fmtr_fxt Keys(String... args) {fmtr.Keys_(args); return this;}
public Bry_fmtr_fxt Args(Object... args) {this.args = args; return this;}
public void Test(String expd) {
fmtr.Bld_bfr_many(bfr, args);
Tfds.Eq(expd, bfr.To_str_and_clear());
}
public void Bld_bfr_many_and_set_fmt(String fmt, Object[] args, String expd) {
fmtr.Fmt_(fmt);
fmtr.Bld_bfr_many_and_set_fmt(args);
Tfds.Eq(expd, String_.new_a7(fmtr.Fmt()));
}
}

@ -1,30 +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.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.core.brys.*;
public class Bry_fmtr_vals implements Bfr_arg {
private final Bry_fmtr fmtr; private Object[] vals;
Bry_fmtr_vals(Bry_fmtr fmtr) {this.fmtr = fmtr;}
public Bry_fmtr_vals Vals_(Object... v) {this.vals = v; return this;}
public void Bfr_arg__add(Bry_bfr bfr) {
fmtr.Bld_bfr_ary(bfr, vals);
}
public static Bry_fmtr_vals new_fmt(String fmt, String... keys) {
Bry_fmtr fmtr = Bry_fmtr.new_(fmt, keys);
return new Bry_fmtr_vals(fmtr);
}
public static Bry_fmtr_vals new_(Bry_fmtr fmtr) {return new Bry_fmtr_vals(fmtr);}
}

@ -1,22 +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.core.brys.fmts; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_fmt_arg {
public Bfr_fmt_arg(byte[] key, Bfr_arg arg) {this.Key = key; this.Arg = arg;}
public byte[] Key;
public Bfr_arg Arg;
public static final Bfr_fmt_arg[] Ary_empty = new Bfr_fmt_arg[0];
}

@ -1,92 +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.core.brys.fmts; import gplx.*;
import gplx.objects.strings.AsciiByte;
public class Bry_fmt_parser_ {
public static Bry_fmt_itm[] Parse(byte escape, byte grp_bgn, byte grp_end, Bfr_fmt_arg[] args, byte[][] keys, byte[] src) {
int src_len = src.length;
int pos = 0;
int txt_bgn = -1;
int key_idx = -1;
Hash_adp_bry keys_hash = Hash_adp_bry.cs();
List_adp list = List_adp_.New();
while (true) {
boolean is_last = pos == src_len;
byte b = is_last ? escape : src[pos];
if (b == escape) {
if (txt_bgn != -1) list.Add(new Bry_fmt_itm(Bry_fmt_itm.Tid__txt, txt_bgn, pos));
if (is_last) break;
++pos;
if (pos == src_len) throw Err_.new_("bry_fmtr", "fmt cannot end with escape", "escape", AsciiByte.ToStr(escape), "raw", src);
b = src[pos];
if (b == escape) {
list.Add(new Bry_fmt_itm(Bry_fmt_itm.Tid__txt, pos, pos + 1));
++pos;
}
else if (b == grp_bgn) {
++pos;
int grp_end_pos = Bry_find_.Find_fwd(src, grp_end, pos); if (grp_end_pos == Bry_find_.Not_found) throw Err_.new_("bry_fmtr", "grp_end missing", "grp_bgn", AsciiByte.ToStr(grp_bgn), "grp_end", AsciiByte.ToStr(grp_end), "raw", src);
byte[] key_bry = Bry_.Mid(src, pos, grp_end_pos);
Bry_fmt_itm key_itm = (Bry_fmt_itm)keys_hash.Get_by_bry(key_bry);
if (key_itm == null) {
key_itm = new Bry_fmt_itm(Bry_fmt_itm.Tid__key, pos - 2, grp_end_pos + 1); // -2 to get "~{"; +1 to get "}"
key_itm.Key_idx = ++key_idx;
keys_hash.Add(key_bry, key_itm);
}
list.Add(key_itm);
pos = grp_end_pos + 1;
}
else throw Err_.new_("bry_fmtr", "escape must be followed by escape or group_bgn", "escape", AsciiByte.ToStr(escape), "group_bgn", AsciiByte.ToStr(escape), "raw", src);
txt_bgn = -1;
}
else {
if (txt_bgn == -1) txt_bgn = pos;
++pos;
}
}
Bry_fmt_itm[] rv = (Bry_fmt_itm[])list.ToAryAndClear(Bry_fmt_itm.class);
int len = args.length;
for (int i = 0; i < len; ++i) {
Bfr_fmt_arg arg = args[i];
Bry_fmt_itm key_itm = (Bry_fmt_itm)keys_hash.GetByOrNull(arg.Key); if (key_itm == null) continue;
key_itm.Tid = Bry_fmt_itm.Tid__arg;
key_itm.Arg = arg.Arg;
}
len = keys.length;
for (int i = 0; i < len; ++i) {
byte[] key = keys[i];
Bry_fmt_itm key_itm = (Bry_fmt_itm)keys_hash.GetByOrNull(key); if (key_itm == null) continue; // NOTE: ignore missing keys; EX: fmt=a~{b}c keys=b,d; do not fail b/c ~{d} is not in fmt; allows redefining from tests
key_itm.Key_idx = i;
}
return rv;
}
public static byte[][] Parse_keys(byte[] src) {
Ordered_hash list = Ordered_hash_.New_bry();
int src_len = src.length;
int pos = -1;
while (pos < src_len) {
int lhs_pos = Bry_find_.Move_fwd(src, Bry_arg_lhs, pos + 1, src_len);
if (lhs_pos == Bry_find_.Not_found) break; // no more "~{"
int rhs_pos = Bry_find_.Find_fwd(src, AsciiByte.CurlyEnd, lhs_pos, src_len);
if (rhs_pos == Bry_find_.Not_found) throw Err_.new_("bry_fmt", "unable to find closing }", "src", src);
if (rhs_pos - lhs_pos == 0) throw Err_.new_("bry_fmt", "{} will result in empty key", "src", src);
byte[] key = Bry_.Mid(src, lhs_pos, rhs_pos);
if (!list.Has(key)) list.Add(key, key);
pos = rhs_pos; // NOTE: auto-increment done at top of loop
}
return (byte[][])list.To_ary(byte[].class);
} private static final byte[] Bry_arg_lhs = Bry_.new_a7("~{");
}

@ -1,50 +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.core.brys.fmts; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import org.junit.*;
public class Bry_fmt_tst {
private final Bry_fmt_fxt fxt = new Bry_fmt_fxt();
@Test public void Text() {fxt.Clear().Fmt("a").Test("a");}
@Test public void Key__basic() {fxt.Clear().Fmt("~{key}").Vals("a").Test("a");}
@Test public void Key__mult() {fxt.Clear().Fmt("~{key1}~{key2}").Vals("a", "b").Test("ab");}
@Test public void Key__repeat() {fxt.Clear().Fmt("~{key1}~{key1}").Vals("a").Test("aa");}
@Test public void Key__missing() {fxt.Clear().Fmt("~{key}").Test("~{key}");}
@Test public void Tilde() {fxt.Clear().Fmt("~~~~").Test("~~");}
@Test public void Simple() {fxt.Clear().Fmt("0~{key1}1~{key2}2").Vals(".", ",").Test("0.1,2");}
@Test public void Arg() {fxt.Clear().Fmt("~{custom}").Args("custom", new Bfr_fmt_arg_mok(123)).Test("123");}
@Test public void Keys() {fxt.Clear().Fmt("~{b}~{c}~{a}").Keys("a", "b", "c").Vals("a", "b", "c").Test("bca");}
}
class Bfr_fmt_arg_mok implements Bfr_arg {
private int num;
public Bfr_fmt_arg_mok(int num) {this.num = num;}
public void Bfr_arg__add(Bry_bfr bfr) {
bfr.Add_int_variable(num);
}
}
class Bry_fmt_fxt {
private final Bry_fmt fmt = new Bry_fmt(Bry_.Empty, Bry_.Ary_empty, Bfr_fmt_arg.Ary_empty);
private final Bry_bfr bfr = Bry_bfr_.New();
private Object[] vals;
public Bry_fmt_fxt Clear() {vals = Object_.Ary_empty; return this;}
public Bry_fmt_fxt Fmt(String s) {fmt.Fmt_(s); return this;}
public Bry_fmt_fxt Vals(Object... vals) {this.vals = vals; return this;}
public Bry_fmt_fxt Args(String key, Bfr_arg arg) {fmt.Args_(new Bfr_fmt_arg(Bry_.new_u8(key), arg)); return this;}
public Bry_fmt_fxt Keys(String... keys) {fmt.Keys_(Bry_.Ary(keys)); return this;}
public void Test(String expd) {
fmt.Bld_many(bfr, vals);
Tfds.Eq(expd, bfr.To_str_and_clear());
}
}

@ -1,30 +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.core.brys.fmts; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import org.junit.*;
public class Bry_keys_parser_tst {
private final Bry_keys_parser_fxt fxt = new Bry_keys_parser_fxt();
@Test public void None() {fxt.Test("a");}
@Test public void One() {fxt.Test("~{a}" , "a");}
@Test public void Many() {fxt.Test("~{a}b~{c}d~{e}" , "a", "c", "e");}
@Test public void Dupe() {fxt.Test("~{a}b~{a}" , "a");}
@Test public void Bug__space() {fxt.Test("~{a}~{b} ~{c}" , "a", "b", "c");} // DATE:2016-08-02
}
class Bry_keys_parser_fxt {
public void Test(String fmt, String... expd) {
Tfds.Eq_ary(expd, String_.Ary(Bry_fmt_parser_.Parse_keys(Bry_.new_u8(fmt))));
}
}

@ -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,106 +13,110 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.btries; import gplx.*; import gplx.core.*;
import gplx.core.primitives.*;
public class Btrie_bwd_mgr {
public int Match_pos() {return match_pos;} private int match_pos;
public Object Match_exact(byte[] src, int bgn_pos, int end_pos) {
Object rv = Match(src[bgn_pos], src, bgn_pos, end_pos);
return rv == null ? null : match_pos - bgn_pos == end_pos - bgn_pos ? rv : null;
}
public Object Match_at(Btrie_rv rv, byte[] src, int bgn_pos, int end_pos) {return Match_at_w_b0(rv, src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match_at_w_b0(Btrie_rv rv, byte b, byte[] src, int bgn_pos, int end_pos) {
// NOTE: bgn, end follows same semantics as fwd where bgn >= & end < except reversed: bgn <= & end >; EX: "abcde" should pass 5, -1
Object rv_obj = null;
int rv_pos = bgn_pos;
int cur_pos = bgn_pos;
Btrie_slim_itm cur = root;
while (true) {
Btrie_slim_itm nxt = cur.Ary_find(b);
if (nxt == null) { // nxt does not have b; return rv_obj;
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
--cur_pos;
if (nxt.Ary_is_empty()) { // nxt is leaf; return nxt.Val() (which should be non-null)
rv_obj = nxt.Val();
rv.Init(cur_pos, rv_obj);
return rv_obj;
}
Object nxt_val = nxt.Val();
if (nxt_val != null) {rv_pos = cur_pos; rv_obj = nxt_val;} // nxt is node; cache rv_obj (in case of false match)
if (cur_pos == end_pos) { // increment cur_pos and exit if end_pos
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
b = src[cur_pos];
cur = nxt;
}
}
public Object Match_bgn(byte[] src, int bgn_pos, int end_pos) {return Match(src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match(byte b, byte[] src, int bgn_pos, int end_pos) {
// NOTE: bgn, end follows same semantics as fwd where bgn >= & end < except reversed: bgn <= & end >; EX: "abcde" should pass 5, -1
Object rv = null; int cur_pos = match_pos = bgn_pos;
Btrie_slim_itm cur = root;
while (true) {
Btrie_slim_itm nxt = cur.Ary_find(b); if (nxt == null) return rv; // nxt does not hav b; return rv;
--cur_pos;
if (nxt.Ary_is_empty()) {match_pos = cur_pos; return nxt.Val();} // nxt is leaf; return nxt.Val() (which should be non-null)
Object nxt_val = nxt.Val();
if (nxt_val != null) {match_pos = cur_pos; rv = nxt_val;} // nxt is node; cache rv (in case of false match)
if (cur_pos == end_pos) return rv; // increment cur_pos and exit if src_len
b = src[cur_pos];
cur = nxt;
}
}
public Btrie_bwd_mgr Add_str_byte(String key, byte val) {return Add(Bry_.new_u8(key), Byte_obj_val.new_(val));}
public Btrie_bwd_mgr Add_byteVal_strAry(byte val, String... ary) {
int ary_len = ary.length;
Byte_obj_val byteVal = Byte_obj_val.new_(val);
for (int i = 0; i < ary_len; i++) {
String itm = ary[i];
Add(Bry_.new_u8(itm), byteVal);
}
return this;
}
public Btrie_bwd_mgr Add(String key, Object val) {return Add(Bry_.new_u8(key), val);}
public Btrie_bwd_mgr Add(byte[] key, Object val) {
if (val == null) throw Err_.new_wo_type("null objects cannot be registered", "key", String_.new_u8(key));
int key_len = key.length;
Btrie_slim_itm cur = root;
for (int i = key_len - 1; i > -1; i--) {
byte b = key[i];
if (root.Case_any() && (b > 64 && b < 91)) b += 32;
Btrie_slim_itm nxt = cur.Ary_find(b);
if (nxt == null)
nxt = cur.Ary_add(b, null);
if (i == 0)
nxt.Val_set(val);
cur = nxt;
}
count++; // FUTURE: do not increment if replacing value
return this;
}
public int Count() {return count;} private int count;
public void Del(byte[] key) {
int key_len = key.length;
Btrie_slim_itm cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
cur = cur.Ary_find(b);
if (cur == null) break;
cur.Ary_del(b);
}
count--; // FUTURE: do not decrement if not found
}
public void Clear() {root.Clear(); count = 0;}
public static Btrie_bwd_mgr cs_() {return new Btrie_bwd_mgr(false);}
public static Btrie_bwd_mgr ci_() {return new Btrie_bwd_mgr(true);}
public static Btrie_bwd_mgr c__(boolean cs) {return new Btrie_bwd_mgr(!cs);}
public Btrie_bwd_mgr(boolean caseAny) {
root = new Btrie_slim_itm(Byte_.Zero, null, caseAny);
} private Btrie_slim_itm root;
}
package gplx.core.btries;
import gplx.types.basics.utls.BryUtl;
import gplx.types.errs.ErrUtl;
import gplx.types.basics.utls.ByteUtl;
import gplx.types.basics.utls.StringUtl;
import gplx.types.basics.wrappers.ByteVal;
public class Btrie_bwd_mgr {
public int Match_pos() {return match_pos;} private int match_pos;
public Object Match_exact(byte[] src, int bgn_pos, int end_pos) {
Object rv = Match(src[bgn_pos], src, bgn_pos, end_pos);
return rv == null ? null : match_pos - bgn_pos == end_pos - bgn_pos ? rv : null;
}
public Object Match_at(Btrie_rv rv, byte[] src, int bgn_pos, int end_pos) {return Match_at_w_b0(rv, src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match_at_w_b0(Btrie_rv rv, byte b, byte[] src, int bgn_pos, int end_pos) {
// NOTE: bgn, end follows same semantics as fwd where bgn >= & end < except reversed: bgn <= & end >; EX: "abcde" should pass 5, -1
Object rv_obj = null;
int rv_pos = bgn_pos;
int cur_pos = bgn_pos;
Btrie_slim_itm cur = root;
while (true) {
Btrie_slim_itm nxt = cur.Ary_find(b);
if (nxt == null) { // nxt does not have b; return rv_obj;
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
--cur_pos;
if (nxt.Ary_is_empty()) { // nxt is leaf; return nxt.Val() (which should be non-null)
rv_obj = nxt.Val();
rv.Init(cur_pos, rv_obj);
return rv_obj;
}
Object nxt_val = nxt.Val();
if (nxt_val != null) {rv_pos = cur_pos; rv_obj = nxt_val;} // nxt is node; cache rv_obj (in case of false match)
if (cur_pos == end_pos) { // increment cur_pos and exit if end_pos
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
b = src[cur_pos];
cur = nxt;
}
}
public Object Match_bgn(byte[] src, int bgn_pos, int end_pos) {return Match(src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match(byte b, byte[] src, int bgn_pos, int end_pos) {
// NOTE: bgn, end follows same semantics as fwd where bgn >= & end < except reversed: bgn <= & end >; EX: "abcde" should pass 5, -1
Object rv = null; int cur_pos = match_pos = bgn_pos;
Btrie_slim_itm cur = root;
while (true) {
Btrie_slim_itm nxt = cur.Ary_find(b); if (nxt == null) return rv; // nxt does not hav b; return rv;
--cur_pos;
if (nxt.Ary_is_empty()) {match_pos = cur_pos; return nxt.Val();} // nxt is leaf; return nxt.Val() (which should be non-null)
Object nxt_val = nxt.Val();
if (nxt_val != null) {match_pos = cur_pos; rv = nxt_val;} // nxt is node; cache rv (in case of false match)
if (cur_pos == end_pos) return rv; // increment cur_pos and exit if src_len
b = src[cur_pos];
cur = nxt;
}
}
public Btrie_bwd_mgr Add_str_byte(String key, byte val) {return Add(BryUtl.NewU8(key), ByteVal.New(val));}
public Btrie_bwd_mgr Add_byteVal_strAry(byte val, String... ary) {
int ary_len = ary.length;
ByteVal byteVal = ByteVal.New(val);
for (int i = 0; i < ary_len; i++) {
String itm = ary[i];
Add(BryUtl.NewU8(itm), byteVal);
}
return this;
}
public Btrie_bwd_mgr Add(String key, Object val) {return Add(BryUtl.NewU8(key), val);}
public Btrie_bwd_mgr Add(byte[] key, Object val) {
if (val == null) throw ErrUtl.NewArgs("null objects cannot be registered", "key", StringUtl.NewU8(key));
int key_len = key.length;
Btrie_slim_itm cur = root;
for (int i = key_len - 1; i > -1; i--) {
byte b = key[i];
if (root.Case_any() && (b > 64 && b < 91)) b += 32;
Btrie_slim_itm nxt = cur.Ary_find(b);
if (nxt == null)
nxt = cur.Ary_add(b, null);
if (i == 0)
nxt.Val_set(val);
cur = nxt;
}
count++; // FUTURE: do not increment if replacing value
return this;
}
public int Count() {return count;} private int count;
public void Del(byte[] key) {
int key_len = key.length;
Btrie_slim_itm cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
cur = cur.Ary_find(b);
if (cur == null) break;
cur.Ary_del(b);
}
count--; // FUTURE: do not decrement if not found
}
public void Clear() {root.Clear(); count = 0;}
public static Btrie_bwd_mgr cs_() {return new Btrie_bwd_mgr(false);}
public static Btrie_bwd_mgr ci_() {return new Btrie_bwd_mgr(true);}
public static Btrie_bwd_mgr c__(boolean cs) {return new Btrie_bwd_mgr(!cs);}
public Btrie_bwd_mgr(boolean caseAny) {
root = new Btrie_slim_itm(ByteUtl.Zero, null, caseAny);
} private Btrie_slim_itm root;
}

@ -1,86 +1,88 @@
/*
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.core.btries; import gplx.*;
import gplx.objects.strings.AsciiByte;
import org.junit.*;
public class Btrie_bwd_mgr_tst {
@Before public void init() {} private Btrie_bwd_mgr trie;
private void ini_setup1() {
trie = new Btrie_bwd_mgr(false);
run_Add("c" , 1);
run_Add("abc" , 123);
}
@Test public void Get_by() {
ini_setup1();
tst_MatchAtCur("c" , 1);
tst_MatchAtCur("abc" , 123);
tst_MatchAtCur("bc" , 1);
tst_MatchAtCur("yzabc" , 123);
tst_MatchAtCur("ab" , null);
}
@Test public void Fetch_intl() {
trie = new Btrie_bwd_mgr(false);
run_Add("a<>", 1);
tst_MatchAtCur("a<>" , 1);
tst_MatchAtCur("<22>" , null);
}
@Test public void Eos() {
ini_setup1();
tst_Match("ab", AsciiByte.Ltr_c, 2, 123);
}
@Test public void Match_exact() {
ini_setup1();
tst_MatchAtCurExact("c", 1);
tst_MatchAtCurExact("bc", null);
tst_MatchAtCurExact("abc", 123);
}
private void ini_setup2() {
trie = new Btrie_bwd_mgr(false);
run_Add("a" , 1);
run_Add("b" , 2);
}
@Test public void Match_2() {
ini_setup2();
tst_MatchAtCur("a", 1);
tst_MatchAtCur("b", 2);
}
private void ini_setup_caseAny() {
trie = Btrie_bwd_mgr.ci_();
run_Add("a" , 1);
run_Add("b" , 2);
}
@Test public void CaseAny() {
ini_setup_caseAny();
tst_MatchAtCur("a", 1);
tst_MatchAtCur("A", 1);
}
private void run_Add(String k, int val) {trie.Add(Bry_.new_u8(k), val);}
private void tst_Match(String srcStr, byte b, int bgn_pos, int expd) {
byte[] src = Bry_.new_u8(srcStr);
Object actl = trie.Match(b, src, bgn_pos, -1);
Tfds.Eq(expd, actl);
}
private void tst_MatchAtCur(String srcStr, Object expd) {
byte[] src = Bry_.new_u8(srcStr);
Object actl = trie.Match(src[src.length - 1], src, src.length - 1, -1);
Tfds.Eq(expd, actl);
}
private void tst_MatchAtCurExact(String srcStr, Object expd) {
byte[] src = Bry_.new_u8(srcStr);
Object actl = trie.Match_exact(src, src.length - 1, -1);
Tfds.Eq(expd, actl);
}
}
/*
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.core.btries;
import gplx.frameworks.tests.GfoTstr;
import gplx.types.basics.utls.BryUtl;
import gplx.types.basics.constants.AsciiByte;
import org.junit.*;
public class Btrie_bwd_mgr_tst {
@Before public void init() {} private Btrie_bwd_mgr trie;
private void ini_setup1() {
trie = new Btrie_bwd_mgr(false);
run_Add("c" , 1);
run_Add("abc" , 123);
}
@Test public void Get_by() {
ini_setup1();
tst_MatchAtCur("c" , 1);
tst_MatchAtCur("abc" , 123);
tst_MatchAtCur("bc" , 1);
tst_MatchAtCur("yzabc" , 123);
tst_MatchAtCur("ab" , null);
}
@Test public void Fetch_intl() {
trie = new Btrie_bwd_mgr(false);
run_Add("a<>", 1);
tst_MatchAtCur("a<>" , 1);
tst_MatchAtCur("<22>" , null);
}
@Test public void Eos() {
ini_setup1();
tst_Match("ab", AsciiByte.Ltr_c, 2, 123);
}
@Test public void Match_exact() {
ini_setup1();
tst_MatchAtCurExact("c", 1);
tst_MatchAtCurExact("bc", null);
tst_MatchAtCurExact("abc", 123);
}
private void ini_setup2() {
trie = new Btrie_bwd_mgr(false);
run_Add("a" , 1);
run_Add("b" , 2);
}
@Test public void Match_2() {
ini_setup2();
tst_MatchAtCur("a", 1);
tst_MatchAtCur("b", 2);
}
private void ini_setup_caseAny() {
trie = Btrie_bwd_mgr.ci_();
run_Add("a" , 1);
run_Add("b" , 2);
}
@Test public void CaseAny() {
ini_setup_caseAny();
tst_MatchAtCur("a", 1);
tst_MatchAtCur("A", 1);
}
private void run_Add(String k, int val) {trie.Add(BryUtl.NewU8(k), val);}
private void tst_Match(String srcStr, byte b, int bgn_pos, int expd) {
byte[] src = BryUtl.NewU8(srcStr);
Object actl = trie.Match(b, src, bgn_pos, -1);
GfoTstr.EqObj(expd, actl);
}
private void tst_MatchAtCur(String srcStr, Object expd) {
byte[] src = BryUtl.NewU8(srcStr);
Object actl = trie.Match(src[src.length - 1], src, src.length - 1, -1);
GfoTstr.EqObj(expd, actl);
}
private void tst_MatchAtCurExact(String srcStr, Object expd) {
byte[] src = BryUtl.NewU8(srcStr);
Object actl = trie.Match_exact(src, src.length - 1, -1);
GfoTstr.EqObj(expd, actl);
}
}

@ -1,198 +1,198 @@
/*
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.core.btries;
import gplx.Bry_;
import gplx.Bry_bfr;
import gplx.Byte_;
import gplx.Err_;
import gplx.String_;
import gplx.core.primitives.Byte_obj_val;
import gplx.objects.primitives.BoolUtl;
public class Btrie_fast_mgr {
private ByteTrieItm_fast root;
public boolean CaseAny() {return root.CaseAny();} public Btrie_fast_mgr CaseAny_(boolean v) {root.CaseAny_(v); return this;}
public int Match_pos() {return match_pos;} private int match_pos;
public Object Match_at(Btrie_rv rv, byte[] src, int bgn_pos, int end_pos) {return Match_at_w_b0(rv, src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match_at_w_b0(Btrie_rv rv, byte b, byte[] src, int bgn_pos, int src_end) {
Object rv_obj = null;
int rv_pos = bgn_pos;
ByteTrieItm_fast nxt = root.Ary_find(b);
if (nxt == null) { // nxt does not have b; return rv;
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
int cur_pos = bgn_pos + 1;
ByteTrieItm_fast cur = root;
while (true) {
if (nxt.Ary_is_empty()) { // nxt is leaf; return nxt.Val() (which should be non-null)
rv_obj = nxt.Val();
rv.Init(cur_pos, rv_obj);
return rv_obj;
}
Object nxt_val = nxt.Val();
if (nxt_val != null) { // nxt is node; cache rv (in case of false match)
rv_pos = cur_pos;
rv_obj = nxt_val;
}
if (cur_pos == src_end) { // eos; exit
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
b = src[cur_pos];
cur = nxt;
nxt = cur.Ary_find(b);
if (nxt == null) {
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
++cur_pos;
}
}
public Object Match_exact(byte[] src, int bgn_pos, int end_pos) {
Object rv = Match_bgn_w_byte(src[bgn_pos], src, bgn_pos, end_pos);
return rv == null ? null : match_pos - bgn_pos == end_pos - bgn_pos ? rv : null;
}
public Object Match_bgn(byte[] src, int bgn_pos, int end_pos) {return Match_bgn_w_byte(src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match_bgn_w_byte(byte b, byte[] src, int bgn_pos, int src_len) {
match_pos = bgn_pos;
ByteTrieItm_fast nxt = root.Ary_find(b); if (nxt == null) return null; // nxt does not have b; return rv;
Object rv = null; int cur_pos = bgn_pos + 1;
ByteTrieItm_fast cur = root;
while (true) {
if (nxt.Ary_is_empty()) {match_pos = cur_pos; return nxt.Val();} // nxt is leaf; return nxt.Val() (which should be non-null)
Object nxt_val = nxt.Val();
if (nxt_val != null) {match_pos = cur_pos; rv = nxt_val;} // nxt is node; cache rv (in case of false match)
if (cur_pos == src_len) return rv; // eos; exit
b = src[cur_pos];
cur = nxt;
nxt = cur.Ary_find(b); if (nxt == null) return rv;
++cur_pos;
}
}
public Btrie_fast_mgr Add_bry_byte(byte key, byte val) {return Add(new byte[] {key}, Byte_obj_val.new_(val));}
public Btrie_fast_mgr Add_bry_byte(byte[] key, byte val) {return Add(key, Byte_obj_val.new_(val));}
public Btrie_fast_mgr Add_str_byte(String key, byte val) {return Add(Bry_.new_u8(key), Byte_obj_val.new_(val));}
public Btrie_fast_mgr Add(byte key, Object val) {return Add(new byte[] {key}, val);}
public Btrie_fast_mgr Add(String key, Object val) {return Add(Bry_.new_u8(key), val);}
public Btrie_fast_mgr Add(byte[] key, Object val) {
if (val == null) throw Err_.new_wo_type("null objects cannot be registered", "key", String_.new_u8(key));
int key_len = key.length; int key_end = key_len - 1;
ByteTrieItm_fast cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
ByteTrieItm_fast nxt = cur.Ary_find(b);
if (nxt == null)
nxt = cur.Ary_add(b, null);
if (i == key_end)
nxt.Val_set(val);
cur = nxt;
}
return this;
}
public Btrie_fast_mgr Add_stub(byte tid, String s) {
byte[] bry = Bry_.new_u8(s);
Btrie_itm_stub stub = new Btrie_itm_stub(tid, bry);
return Add(bry, stub);
}
public void Del(byte[] key) {
int key_len = key.length;
ByteTrieItm_fast cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
Object itm_obj = cur.Ary_find(b);
if (itm_obj == null) break; // b not found; no match; exit;
ByteTrieItm_fast itm = (ByteTrieItm_fast)itm_obj;
if (i == key_len - 1) { // last char
if (itm.Val() == null) break; // itm does not have val; EX: trie with "abc", and "ab" deleted
if (itm.Ary_is_empty())
cur.Ary_del(b);
else
itm.Val_set(null);
}
else { // mid char; set itm as cur and continue
cur = itm;
}
}
}
public void Clear() {root.Clear();}
public byte[] Replace(Bry_bfr tmp_bfr, byte[] src, int bgn, int end) {
int pos = bgn;
boolean dirty = false;
while (pos < end) {
byte b = src[pos];
Object o = this.Match_bgn_w_byte(b, src, pos, end);
if (o == null) {
if (dirty)
tmp_bfr.Add_byte(b);
pos++;
}
else {
if (!dirty) {
tmp_bfr.Add_mid(src, bgn, pos);
dirty = true;
}
tmp_bfr.Add((byte[])o);
pos = match_pos;
}
}
return dirty ? tmp_bfr.To_bry_and_clear() : src;
}
public static Btrie_fast_mgr cs() {return new Btrie_fast_mgr(BoolUtl.N);}
public static Btrie_fast_mgr ci_a7() {return new Btrie_fast_mgr(BoolUtl.Y);}
public static Btrie_fast_mgr new_(boolean case_any) {return new Btrie_fast_mgr(case_any);}
Btrie_fast_mgr(boolean case_any) {
root = new ByteTrieItm_fast(Byte_.Zero, null, case_any);
}
}
class ByteTrieItm_fast {
private ByteTrieItm_fast[] ary = new ByteTrieItm_fast[256];
public byte Key_byte() {return key_byte;} private byte key_byte;
public Object Val() {return val;} public void Val_set(Object val) {this.val = val;} Object val;
public boolean Ary_is_empty() {return ary_is_empty;} private boolean ary_is_empty;
public boolean CaseAny() {return case_any;} public ByteTrieItm_fast CaseAny_(boolean v) {case_any = v; return this;} private boolean case_any;
public void Clear() {
val = null;
for (int i = 0; i < 256; i++) {
if (ary[i] != null) {
ary[i].Clear();
ary[i] = null;
}
}
ary_len = 0;
ary_is_empty = true;
}
public ByteTrieItm_fast Ary_find(byte b) {
int key_byte = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
return ary[key_byte];
}
public ByteTrieItm_fast Ary_add(byte b, Object val) {
int key_byte = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
ByteTrieItm_fast rv = new ByteTrieItm_fast(b, val, case_any);
ary[key_byte] = rv;
++ary_len;
ary_is_empty = false;
return rv;
}
public void Ary_del(byte b) {
int key_byte = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
ary[key_byte] = null;
--ary_len;
ary_is_empty = ary_len == 0;
} int ary_len = 0;
public ByteTrieItm_fast(byte key_byte, Object val, boolean case_any) {this.key_byte = key_byte; this.val = val; this.case_any = case_any;}
}
/*
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.core.btries;
import gplx.types.basics.utls.BryUtl;
import gplx.types.custom.brys.wtrs.BryWtr;
import gplx.types.errs.ErrUtl;
import gplx.types.basics.utls.BoolUtl;
import gplx.types.basics.utls.ByteUtl;
import gplx.types.basics.utls.StringUtl;
import gplx.types.basics.wrappers.ByteVal;
public class Btrie_fast_mgr {
private ByteTrieItm_fast root;
public boolean CaseAny() {return root.CaseAny();} public Btrie_fast_mgr CaseAny_(boolean v) {root.CaseAny_(v); return this;}
public int Match_pos() {return match_pos;} private int match_pos;
public Object Match_at(Btrie_rv rv, byte[] src, int bgn_pos, int end_pos) {return Match_at_w_b0(rv, src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match_at_w_b0(Btrie_rv rv, byte b, byte[] src, int bgn_pos, int src_end) {
Object rv_obj = null;
int rv_pos = bgn_pos;
ByteTrieItm_fast nxt = root.Ary_find(b);
if (nxt == null) { // nxt does not have b; return rv;
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
int cur_pos = bgn_pos + 1;
ByteTrieItm_fast cur = root;
while (true) {
if (nxt.Ary_is_empty()) { // nxt is leaf; return nxt.Val() (which should be non-null)
rv_obj = nxt.Val();
rv.Init(cur_pos, rv_obj);
return rv_obj;
}
Object nxt_val = nxt.Val();
if (nxt_val != null) { // nxt is node; cache rv (in case of false match)
rv_pos = cur_pos;
rv_obj = nxt_val;
}
if (cur_pos == src_end) { // eos; exit
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
b = src[cur_pos];
cur = nxt;
nxt = cur.Ary_find(b);
if (nxt == null) {
rv.Init(rv_pos, rv_obj);
return rv_obj;
}
++cur_pos;
}
}
public Object Match_exact(byte[] src, int bgn_pos, int end_pos) {
Object rv = Match_bgn_w_byte(src[bgn_pos], src, bgn_pos, end_pos);
return rv == null ? null : match_pos - bgn_pos == end_pos - bgn_pos ? rv : null;
}
public Object Match_bgn(byte[] src, int bgn_pos, int end_pos) {return Match_bgn_w_byte(src[bgn_pos], src, bgn_pos, end_pos);}
public Object Match_bgn_w_byte(byte b, byte[] src, int bgn_pos, int src_len) {
match_pos = bgn_pos;
ByteTrieItm_fast nxt = root.Ary_find(b); if (nxt == null) return null; // nxt does not have b; return rv;
Object rv = null; int cur_pos = bgn_pos + 1;
ByteTrieItm_fast cur = root;
while (true) {
if (nxt.Ary_is_empty()) {match_pos = cur_pos; return nxt.Val();} // nxt is leaf; return nxt.Val() (which should be non-null)
Object nxt_val = nxt.Val();
if (nxt_val != null) {match_pos = cur_pos; rv = nxt_val;} // nxt is node; cache rv (in case of false match)
if (cur_pos == src_len) return rv; // eos; exit
b = src[cur_pos];
cur = nxt;
nxt = cur.Ary_find(b); if (nxt == null) return rv;
++cur_pos;
}
}
public Btrie_fast_mgr Add_bry_byte(byte key, byte val) {return Add(new byte[] {key}, ByteVal.New(val));}
public Btrie_fast_mgr Add_bry_byte(byte[] key, byte val) {return Add(key, ByteVal.New(val));}
public Btrie_fast_mgr Add_str_byte(String key, byte val) {return Add(BryUtl.NewU8(key), ByteVal.New(val));}
public Btrie_fast_mgr Add(byte key, Object val) {return Add(new byte[] {key}, val);}
public Btrie_fast_mgr Add(String key, Object val) {return Add(BryUtl.NewU8(key), val);}
public Btrie_fast_mgr Add(byte[] key, Object val) {
if (val == null) throw ErrUtl.NewArgs("null objects cannot be registered", "key", StringUtl.NewU8(key));
int key_len = key.length; int key_end = key_len - 1;
ByteTrieItm_fast cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
ByteTrieItm_fast nxt = cur.Ary_find(b);
if (nxt == null)
nxt = cur.Ary_add(b, null);
if (i == key_end)
nxt.Val_set(val);
cur = nxt;
}
return this;
}
public Btrie_fast_mgr Add_stub(byte tid, String s) {
byte[] bry = BryUtl.NewU8(s);
Btrie_itm_stub stub = new Btrie_itm_stub(tid, bry);
return Add(bry, stub);
}
public void Del(byte[] key) {
int key_len = key.length;
ByteTrieItm_fast cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
Object itm_obj = cur.Ary_find(b);
if (itm_obj == null) break; // b not found; no match; exit;
ByteTrieItm_fast itm = (ByteTrieItm_fast)itm_obj;
if (i == key_len - 1) { // last char
if (itm.Val() == null) break; // itm does not have val; EX: trie with "abc", and "ab" deleted
if (itm.Ary_is_empty())
cur.Ary_del(b);
else
itm.Val_set(null);
}
else { // mid char; set itm as cur and continue
cur = itm;
}
}
}
public void Clear() {root.Clear();}
public byte[] Replace(BryWtr tmp_bfr, byte[] src, int bgn, int end) {
int pos = bgn;
boolean dirty = false;
while (pos < end) {
byte b = src[pos];
Object o = this.Match_bgn_w_byte(b, src, pos, end);
if (o == null) {
if (dirty)
tmp_bfr.AddByte(b);
pos++;
}
else {
if (!dirty) {
tmp_bfr.AddMid(src, bgn, pos);
dirty = true;
}
tmp_bfr.Add((byte[])o);
pos = match_pos;
}
}
return dirty ? tmp_bfr.ToBryAndClear() : src;
}
public static Btrie_fast_mgr cs() {return new Btrie_fast_mgr(BoolUtl.N);}
public static Btrie_fast_mgr ci_a7() {return new Btrie_fast_mgr(BoolUtl.Y);}
public static Btrie_fast_mgr new_(boolean case_any) {return new Btrie_fast_mgr(case_any);}
Btrie_fast_mgr(boolean case_any) {
root = new ByteTrieItm_fast(ByteUtl.Zero, null, case_any);
}
}
class ByteTrieItm_fast {
private ByteTrieItm_fast[] ary = new ByteTrieItm_fast[256];
public byte Key_byte() {return key_byte;} private byte key_byte;
public Object Val() {return val;} public void Val_set(Object val) {this.val = val;} Object val;
public boolean Ary_is_empty() {return ary_is_empty;} private boolean ary_is_empty;
public boolean CaseAny() {return case_any;} public ByteTrieItm_fast CaseAny_(boolean v) {case_any = v; return this;} private boolean case_any;
public void Clear() {
val = null;
for (int i = 0; i < 256; i++) {
if (ary[i] != null) {
ary[i].Clear();
ary[i] = null;
}
}
ary_len = 0;
ary_is_empty = true;
}
public ByteTrieItm_fast Ary_find(byte b) {
int key_byte = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
return ary[key_byte];
}
public ByteTrieItm_fast Ary_add(byte b, Object val) {
int key_byte = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
ByteTrieItm_fast rv = new ByteTrieItm_fast(b, val, case_any);
ary[key_byte] = rv;
++ary_len;
ary_is_empty = false;
return rv;
}
public void Ary_del(byte b) {
int key_byte = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
ary[key_byte] = null;
--ary_len;
ary_is_empty = ary_len == 0;
} int ary_len = 0;
public ByteTrieItm_fast(byte key_byte, Object val, boolean case_any) {this.key_byte = key_byte; this.val = val; this.case_any = case_any;}
}

@ -1,84 +1,86 @@
/*
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.core.btries; import gplx.*;
import gplx.objects.strings.AsciiByte;
import org.junit.*;
public class Btrie_fast_mgr_tst {
private Btrie_fast_mgr_fxt fxt = new Btrie_fast_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Get_by() {
fxt.Test_matchAtCur("a" , 1);
fxt.Test_matchAtCur("abc" , 123);
fxt.Test_matchAtCur("ab" , 1);
fxt.Test_matchAtCur("abcde" , 123);
fxt.Test_matchAtCur(" a" , null);
}
@Test public void Bos() {
fxt.Test_match("bc", AsciiByte.Ltr_a, -1, 123);
}
@Test public void Match_exact() {
fxt.Test_matchAtCurExact("a", 1);
fxt.Test_matchAtCurExact("ab", null);
fxt.Test_matchAtCurExact("abc", 123);
}
@Test public void Del_noop__no_match() {
fxt.Exec_del("d");
fxt.Test_matchAtCurExact("a" , 1);
fxt.Test_matchAtCurExact("abc" , 123);
}
@Test public void Del_noop__partial_match() {
fxt.Exec_del("ab");
fxt.Test_matchAtCurExact("a" , 1);
fxt.Test_matchAtCurExact("abc" , 123);
}
@Test public void Del_match__long() {
fxt.Exec_del("abc");
fxt.Test_matchAtCurExact("a" , 1);
fxt.Test_matchAtCurExact("abc" , null);
}
@Test public void Del_match__short() {
fxt.Exec_del("a");
fxt.Test_matchAtCurExact("a" , null);
fxt.Test_matchAtCurExact("abc" , 123);
}
}
class Btrie_fast_mgr_fxt {
private Btrie_fast_mgr trie;
public void Clear() {
trie = Btrie_fast_mgr.cs();
Init_add( 1 , AsciiByte.Ltr_a);
Init_add(123 , AsciiByte.Ltr_a, AsciiByte.Ltr_b, AsciiByte.Ltr_c);
}
public void Init_add(int val, byte... ary) {trie.Add(ary, val);}
public void Test_match(String src_str, byte b, int bgn_pos, int expd) {
byte[] src = Bry_.new_a7(src_str);
Object actl = trie.Match_bgn_w_byte(b, src, bgn_pos, src.length);
Tfds.Eq(expd, actl);
}
public void Test_matchAtCur(String src_str, Object expd) {
byte[] src = Bry_.new_a7(src_str);
Object actl = trie.Match_bgn(src, 0, src.length);
Tfds.Eq(expd, actl);
}
public void Test_matchAtCurExact(String src_str, Object expd) {
byte[] src = Bry_.new_a7(src_str);
Object actl = trie.Match_exact(src, 0, src.length);
Tfds.Eq(expd, actl);
}
public void Exec_del(String src_str) {
trie.Del(Bry_.new_u8(src_str));
}
}
/*
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.core.btries;
import gplx.frameworks.tests.GfoTstr;
import gplx.types.basics.utls.BryUtl;
import gplx.types.basics.constants.AsciiByte;
import org.junit.*;
public class Btrie_fast_mgr_tst {
private Btrie_fast_mgr_fxt fxt = new Btrie_fast_mgr_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Get_by() {
fxt.Test_matchAtCur("a" , 1);
fxt.Test_matchAtCur("abc" , 123);
fxt.Test_matchAtCur("ab" , 1);
fxt.Test_matchAtCur("abcde" , 123);
fxt.Test_matchAtCur(" a" , null);
}
@Test public void Bos() {
fxt.Test_match("bc", AsciiByte.Ltr_a, -1, 123);
}
@Test public void Match_exact() {
fxt.Test_matchAtCurExact("a", 1);
fxt.Test_matchAtCurExact("ab", null);
fxt.Test_matchAtCurExact("abc", 123);
}
@Test public void Del_noop__no_match() {
fxt.Exec_del("d");
fxt.Test_matchAtCurExact("a" , 1);
fxt.Test_matchAtCurExact("abc" , 123);
}
@Test public void Del_noop__partial_match() {
fxt.Exec_del("ab");
fxt.Test_matchAtCurExact("a" , 1);
fxt.Test_matchAtCurExact("abc" , 123);
}
@Test public void Del_match__long() {
fxt.Exec_del("abc");
fxt.Test_matchAtCurExact("a" , 1);
fxt.Test_matchAtCurExact("abc" , null);
}
@Test public void Del_match__short() {
fxt.Exec_del("a");
fxt.Test_matchAtCurExact("a" , null);
fxt.Test_matchAtCurExact("abc" , 123);
}
}
class Btrie_fast_mgr_fxt {
private Btrie_fast_mgr trie;
public void Clear() {
trie = Btrie_fast_mgr.cs();
Init_add( 1 , AsciiByte.Ltr_a);
Init_add(123 , AsciiByte.Ltr_a, AsciiByte.Ltr_b, AsciiByte.Ltr_c);
}
public void Init_add(int val, byte... ary) {trie.Add(ary, val);}
public void Test_match(String src_str, byte b, int bgn_pos, int expd) {
byte[] src = BryUtl.NewA7(src_str);
Object actl = trie.Match_bgn_w_byte(b, src, bgn_pos, src.length);
GfoTstr.EqObj(expd, actl);
}
public void Test_matchAtCur(String src_str, Object expd) {
byte[] src = BryUtl.NewA7(src_str);
Object actl = trie.Match_bgn(src, 0, src.length);
GfoTstr.EqObj(expd, actl);
}
public void Test_matchAtCurExact(String src_str, Object expd) {
byte[] src = BryUtl.NewA7(src_str);
Object actl = trie.Match_exact(src, 0, src.length);
GfoTstr.EqObj(expd, actl);
}
public void Exec_del(String src_str) {
trie.Del(BryUtl.NewU8(src_str));
}
}

@ -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,9 +13,10 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.btries; import gplx.*; import gplx.core.*;
public class Btrie_itm_stub {
public Btrie_itm_stub(byte tid, byte[] val) {this.tid = tid; this.val = val;}
public byte Tid() {return tid;} private byte tid;
public byte[] Val() {return val;} private byte[] val;
}
package gplx.core.btries;
import gplx.*; import gplx.core.*;
public class Btrie_itm_stub {
public Btrie_itm_stub(byte tid, byte[] val) {this.tid = tid; this.val = val;}
public byte Tid() {return tid;} private byte tid;
public byte[] Val() {return val;} private byte[] val;
}

@ -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,10 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.btries; import gplx.*; import gplx.core.*;
public interface Btrie_mgr {
int Match_pos();
Object Match_at(Btrie_rv rv, byte[] src, int bgn_pos, int end_pos);
Object Match_bgn(byte[] src, int bgn_pos, int end_pos);
Btrie_mgr Add_obj(String key, Object val);
Btrie_mgr Add_obj(byte[] key, Object val);
}
package gplx.core.btries;
public interface Btrie_mgr {
Object MatchAt(Btrie_rv rv, byte[] src, int bgn_pos, int end_pos);
Object MatchBgn(byte[] src, int bgn_pos, int end_pos);
Btrie_mgr AddObj(String key, Object val);
Btrie_mgr AddObj(byte[] key, Object val);
}

@ -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,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.core.btries; import gplx.*; import gplx.core.*;
import gplx.core.threads.poolables.*;
public class Btrie_rv {
public int Match_bgn = -1;
public Object Obj() {return obj;} private Object obj;
public int Pos() {return pos;} private int pos;
public Btrie_rv Init(int pos, Object obj) {
this.obj = obj;
this.pos = pos;
return this;
}
}
package gplx.core.btries;
public class Btrie_rv {
public int Match_bgn = -1;
public Object Obj() {return obj;} private Object obj;
public int Pos() {return pos;} private int pos;
public Btrie_rv Init(int pos, Object obj) {
this.obj = obj;
this.pos = pos;
return this;
}
}

@ -1,131 +1,131 @@
/*
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.core.btries;
import gplx.objects.arrays.ArrayUtl;
public class Btrie_slim_itm {
private Btrie_slim_itm[] ary = Btrie_slim_itm.Ary_empty;
public Btrie_slim_itm(byte key_byte, Object val, boolean case_any) {this.key_byte = key_byte; this.val = val; this.case_any = case_any;}
public byte Key_byte() {return key_byte;} private byte key_byte;
public Object Val() {return val;} public void Val_set(Object val) {this.val = val;} private Object val;
public boolean Case_any() {return case_any;} private boolean case_any;
public boolean Ary_is_empty() {return ary == Btrie_slim_itm.Ary_empty;}
public void Clear() {
val = null;
for (int i = 0; i < ary_len; i++)
ary[i].Clear();
ary = Btrie_slim_itm.Ary_empty;
ary_len = ary_max = 0;
}
public Btrie_slim_itm Ary_find(byte b) {
int find_val = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
int key_val = 0;
switch (ary_len) {
case 0: return null;
case 1:
Btrie_slim_itm rv = ary[0];
key_val = rv.Key_byte() & 0xff;// PATCH.JAVA:need to convert to unsigned byte;
key_val = (case_any && (key_val > 64 && key_val < 91) ? key_val + 32 : key_val);
return key_val == find_val ? rv : null;
default:
int adj = 1;
int prv_pos = 0;
int prv_len = ary_len;
int cur_len = 0;
int cur_idx = 0;
Btrie_slim_itm itm = null;
while (true) {
cur_len = prv_len / 2;
if (prv_len % 2 == 1) ++cur_len;
cur_idx = prv_pos + (cur_len * adj);
if (cur_idx < 0) cur_idx = 0;
else if (cur_idx >= ary_len) cur_idx = ary_len - 1;
itm = ary[cur_idx];
key_val = itm.Key_byte() & 0xff; // PATCH.JAVA:need to convert to unsigned byte;
key_val = (case_any && (key_val > 64 && key_val < 91) ? key_val + 32 : key_val);
if (find_val < key_val) adj = -1;
else if (find_val > key_val) adj = 1;
else /*(find_val == cur_val)*/ return itm;
if (cur_len == 1) {
cur_idx += adj;
if (cur_idx < 0 || cur_idx >= ary_len) return null;
itm = ary[cur_idx];
return (itm.Key_byte() & 0xff) == find_val ? itm : null; // PATCH.JAVA:need to convert to unsigned byte;
}
prv_len = cur_len;
prv_pos = cur_idx;
}
}
}
public Btrie_slim_itm Ary_add(byte b, Object val) {
int new_len = ary_len + 1;
if (new_len > ary_max) {
ary_max += 4;
ary = (Btrie_slim_itm[])ArrayUtl.Resize(ary, ary_max);
}
Btrie_slim_itm rv = new Btrie_slim_itm(b, val, case_any);
ary[ary_len] = rv;
ary_len = new_len;
synchronized (ByteHashItm_sorter.Instance) {// TS: DATE:2016-07-06
ByteHashItm_sorter.Instance.Sort(ary, ary_len);
}
return rv;
}
public void Ary_del(byte b) {
boolean found = false;
for (int i = 0; i < ary_len; i++) {
if (found) {
if (i < ary_len - 1)
ary[i] = ary[i + 1];
}
else {
if (b == ary[i].Key_byte()) found = true;
}
}
if (found) --ary_len;
}
public static final Btrie_slim_itm[] Ary_empty = new Btrie_slim_itm[0]; int ary_len = 0, ary_max = 0;
}
class ByteHashItm_sorter {// quicksort
Btrie_slim_itm[] ary; int ary_len;
public void Sort(Btrie_slim_itm[] ary, int ary_len) {
if (ary == null || ary_len < 2) return;
this.ary = ary;
this.ary_len = ary_len;
Sort_recurse(0, ary_len - 1);
}
private void Sort_recurse(int lo, int hi) {
int i = lo, j = hi;
int mid = ary[lo + (hi-lo)/2].Key_byte()& 0xFF; // get mid itm
while (i <= j) { // divide into two lists
while ((ary[i].Key_byte() & 0xFF) < mid) // if lhs.cur < mid, then get next from lhs
i++;
while ((ary[j].Key_byte() & 0xFF) > mid) // if rhs.cur > mid, then get next from rhs
j--;
// lhs.cur > mid && rhs.cur < mid; switch lhs.cur and rhs.cur; increase i and j
if (i <= j) {
Btrie_slim_itm tmp = ary[i];
ary[i] = ary[j];
ary[j] = tmp;
i++;
j--;
}
}
if (lo < j) Sort_recurse(lo, j);
if (i < hi) Sort_recurse(i, hi);
}
public static final ByteHashItm_sorter Instance = new ByteHashItm_sorter(); ByteHashItm_sorter() {}
}
/*
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.core.btries;
import gplx.types.basics.utls.ArrayUtl;
public class Btrie_slim_itm {
private Btrie_slim_itm[] ary = Btrie_slim_itm.Ary_empty;
public Btrie_slim_itm(byte key_byte, Object val, boolean case_any) {this.key_byte = key_byte; this.val = val; this.case_any = case_any;}
public byte Key_byte() {return key_byte;} private byte key_byte;
public Object Val() {return val;} public void Val_set(Object val) {this.val = val;} private Object val;
public boolean Case_any() {return case_any;} private boolean case_any;
public boolean Ary_is_empty() {return ary == Btrie_slim_itm.Ary_empty;}
public void Clear() {
val = null;
for (int i = 0; i < ary_len; i++)
ary[i].Clear();
ary = Btrie_slim_itm.Ary_empty;
ary_len = ary_max = 0;
}
public Btrie_slim_itm Ary_find(byte b) {
int find_val = (case_any && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
int key_val = 0;
switch (ary_len) {
case 0: return null;
case 1:
Btrie_slim_itm rv = ary[0];
key_val = rv.Key_byte() & 0xff;// PATCH.JAVA:need to convert to unsigned byte;
key_val = (case_any && (key_val > 64 && key_val < 91) ? key_val + 32 : key_val);
return key_val == find_val ? rv : null;
default:
int adj = 1;
int prv_pos = 0;
int prv_len = ary_len;
int cur_len = 0;
int cur_idx = 0;
Btrie_slim_itm itm = null;
while (true) {
cur_len = prv_len / 2;
if (prv_len % 2 == 1) ++cur_len;
cur_idx = prv_pos + (cur_len * adj);
if (cur_idx < 0) cur_idx = 0;
else if (cur_idx >= ary_len) cur_idx = ary_len - 1;
itm = ary[cur_idx];
key_val = itm.Key_byte() & 0xff; // PATCH.JAVA:need to convert to unsigned byte;
key_val = (case_any && (key_val > 64 && key_val < 91) ? key_val + 32 : key_val);
if (find_val < key_val) adj = -1;
else if (find_val > key_val) adj = 1;
else /*(find_val == cur_val)*/ return itm;
if (cur_len == 1) {
cur_idx += adj;
if (cur_idx < 0 || cur_idx >= ary_len) return null;
itm = ary[cur_idx];
return (itm.Key_byte() & 0xff) == find_val ? itm : null; // PATCH.JAVA:need to convert to unsigned byte;
}
prv_len = cur_len;
prv_pos = cur_idx;
}
}
}
public Btrie_slim_itm Ary_add(byte b, Object val) {
int new_len = ary_len + 1;
if (new_len > ary_max) {
ary_max += 4;
ary = (Btrie_slim_itm[])ArrayUtl.Resize(ary, ary_max);
}
Btrie_slim_itm rv = new Btrie_slim_itm(b, val, case_any);
ary[ary_len] = rv;
ary_len = new_len;
synchronized (ByteHashItm_sorter.Instance) {// TS: DATE:2016-07-06
ByteHashItm_sorter.Instance.Sort(ary, ary_len);
}
return rv;
}
public void Ary_del(byte b) {
boolean found = false;
for (int i = 0; i < ary_len; i++) {
if (found) {
if (i < ary_len - 1)
ary[i] = ary[i + 1];
}
else {
if (b == ary[i].Key_byte()) found = true;
}
}
if (found) --ary_len;
}
public static final Btrie_slim_itm[] Ary_empty = new Btrie_slim_itm[0]; int ary_len = 0, ary_max = 0;
}
class ByteHashItm_sorter {// quicksort
Btrie_slim_itm[] ary; int ary_len;
public void Sort(Btrie_slim_itm[] ary, int ary_len) {
if (ary == null || ary_len < 2) return;
this.ary = ary;
this.ary_len = ary_len;
Sort_recurse(0, ary_len - 1);
}
private void Sort_recurse(int lo, int hi) {
int i = lo, j = hi;
int mid = ary[lo + (hi-lo)/2].Key_byte()& 0xFF; // get mid itm
while (i <= j) { // divide into two lists
while ((ary[i].Key_byte() & 0xFF) < mid) // if lhs.cur < mid, then get next from lhs
i++;
while ((ary[j].Key_byte() & 0xFF) > mid) // if rhs.cur > mid, then get next from rhs
j--;
// lhs.cur > mid && rhs.cur < mid; switch lhs.cur and rhs.cur; increase i and j
if (i <= j) {
Btrie_slim_itm tmp = ary[i];
ary[i] = ary[j];
ary[j] = tmp;
i++;
j--;
}
}
if (lo < j) Sort_recurse(lo, j);
if (i < hi) Sort_recurse(i, hi);
}
public static final ByteHashItm_sorter Instance = new ByteHashItm_sorter(); ByteHashItm_sorter() {}
}

@ -1,48 +1,51 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.core.btries; import gplx.*;
import gplx.objects.strings.AsciiByte;
import org.junit.*;
public class Btrie_slim_itm_tst {
private Btrie_slim_itm itm = new Btrie_slim_itm(Byte_.Zero, null, false);
@Before public void init() {itm.Clear();}
@Test public void Find_nil() {
tst_Find(AsciiByte.Ltr_a, null);
}
@Test public void Add_one() {
run_Add(AsciiByte.Ltr_a);
tst_Find(AsciiByte.Ltr_a, "a");
}
@Test public void Add_many() {
run_Add(AsciiByte.Bang, AsciiByte.Num0, AsciiByte.Ltr_a, AsciiByte.Ltr_B);
tst_Find(AsciiByte.Ltr_a, "a");
}
@Test public void Del() {
run_Add(AsciiByte.Bang, AsciiByte.Num0, AsciiByte.Ltr_a, AsciiByte.Ltr_B);
tst_Find(AsciiByte.Ltr_a, "a");
run_Del(AsciiByte.Ltr_a);
tst_Find(AsciiByte.Ltr_a, null);
tst_Find(AsciiByte.Num0, "0");
tst_Find(AsciiByte.Ltr_B, "B");
}
private void tst_Find(byte b, String expd) {
Btrie_slim_itm actl_itm = itm.Ary_find(b);
Object actl = actl_itm == null ? null : actl_itm.Val();
Tfds.Eq(expd, actl);
}
private void run_Add(byte... ary) {for (byte b : ary) itm.Ary_add(b, Char_.To_str((char)b));}
private void run_Del(byte... ary) {for (byte b : ary) itm.Ary_del(b);}
}
/*
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.core.btries;
import gplx.frameworks.tests.GfoTstr;
import gplx.types.basics.utls.ByteUtl;
import gplx.types.basics.utls.CharUtl;
import gplx.types.basics.constants.AsciiByte;
import org.junit.*;
public class Btrie_slim_itm_tst {
private Btrie_slim_itm itm = new Btrie_slim_itm(ByteUtl.Zero, null, false);
@Before public void init() {itm.Clear();}
@Test public void Find_nil() {
tst_Find(AsciiByte.Ltr_a, null);
}
@Test public void Add_one() {
run_Add(AsciiByte.Ltr_a);
tst_Find(AsciiByte.Ltr_a, "a");
}
@Test public void Add_many() {
run_Add(AsciiByte.Bang, AsciiByte.Num0, AsciiByte.Ltr_a, AsciiByte.Ltr_B);
tst_Find(AsciiByte.Ltr_a, "a");
}
@Test public void Del() {
run_Add(AsciiByte.Bang, AsciiByte.Num0, AsciiByte.Ltr_a, AsciiByte.Ltr_B);
tst_Find(AsciiByte.Ltr_a, "a");
run_Del(AsciiByte.Ltr_a);
tst_Find(AsciiByte.Ltr_a, null);
tst_Find(AsciiByte.Num0, "0");
tst_Find(AsciiByte.Ltr_B, "B");
}
private void tst_Find(byte b, String expd) {
Btrie_slim_itm actl_itm = itm.Ary_find(b);
Object actl = actl_itm == null ? null : actl_itm.Val();
GfoTstr.EqObj(expd, actl);
}
private void run_Add(byte... ary) {for (byte b : ary) itm.Ary_add(b, CharUtl.ToStr((char)b));}
private void run_Del(byte... ary) {for (byte b : ary) itm.Ary_del(b);}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save