mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Refactor: Pull more classes into baselib
This commit is contained in:
parent
48559edffe
commit
0e80d7ef6d
4
.gitignore
vendored
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); // ∃
|
||||
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<EFBFBD>ne Delacroix - La libert<EFBFBD> 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&"'<>b"); // escape=all; code handles first escape differently
|
||||
fxt.Test__add_bry_escape_html("a&b&c" , "a&b&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<EFBFBD>", 1);
|
||||
tst_MatchAtCur("a<EFBFBD>" , 1);
|
||||
tst_MatchAtCur("<EFBFBD>" , 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<EFBFBD>", 1);
|
||||
tst_MatchAtCur("a<EFBFBD>" , 1);
|
||||
tst_MatchAtCur("<EFBFBD>" , 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…
Reference in New Issue
Block a user