mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v1.6.5.1
This commit is contained in:
85
400_xowa/src_020_byte/gplx/Bit_.java
Normal file
85
400_xowa/src_020_byte/gplx/Bit_.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class Bit_ {
|
||||
public static String XtoBitStr(int val) {
|
||||
boolean[] bits = new boolean[8];
|
||||
int idx = 7;
|
||||
while (val > 0) {
|
||||
if ((val & 1) == 1) bits[idx] = true;
|
||||
idx--;
|
||||
val >>= 1;
|
||||
}
|
||||
byte[] rv = new byte[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
rv[i] = bits[i] ? Byte_ascii.Num_1 : Byte_ascii.Num_0;
|
||||
return String_.new_ascii_(rv);
|
||||
}
|
||||
public static int[] Bld_pow_ary(int... seg_ary) {
|
||||
int seg_ary_len = seg_ary.length;
|
||||
int pow = 0;
|
||||
int[] rv = new int[seg_ary_len];
|
||||
for (int i = seg_ary_len - 1; i > -1; i--) {
|
||||
rv[i] = Base2_ary[pow];
|
||||
pow += seg_ary[i];
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static int Xto_int(int[] pow_ary, int[] val_ary) {
|
||||
int pow_ary_last = pow_ary.length - 1;
|
||||
int val = 0;
|
||||
for (int i = pow_ary_last; i > -1; i--)
|
||||
val += pow_ary[i] * val_ary[i];
|
||||
return val;
|
||||
}
|
||||
public static int[] Xto_intAry(int[] pow_ary, int v) {
|
||||
int[] rv = new int[pow_ary.length];
|
||||
Xto_intAry(rv, pow_ary, v);
|
||||
return rv;
|
||||
}
|
||||
public static void Xto_intAry(int[] rv, int[] pow_ary, int v) {
|
||||
int pow_ary_len = pow_ary.length;
|
||||
int rv_len = rv.length;
|
||||
for (int i = 0; i < pow_ary_len; i++) {
|
||||
if (i >= rv_len) break;
|
||||
rv[i] = v / pow_ary[i];
|
||||
int factor = pow_ary[i] * rv[i];
|
||||
v = factor == 0 ? v : (v % factor); // NOTE: if 0, do not do modulus or else div by zero
|
||||
}
|
||||
}
|
||||
public static int Xto_int_date_short(int[] val_ary) {
|
||||
val_ary[0] -= 1900;
|
||||
return Xto_int(Pow_ary_date_short, val_ary);
|
||||
}
|
||||
public static void Xto_date_short_int_ary(int[] rv, int v) {
|
||||
Xto_intAry(rv, Pow_ary_date_short, v);
|
||||
rv[0] += 1900;
|
||||
}
|
||||
public static DateAdp Xto_date_short(int v) {
|
||||
int[] rv = new int[Pow_ary_date_short.length];
|
||||
Xto_date_short_int_ary(rv, v);
|
||||
return DateAdp_.seg_(rv);
|
||||
}
|
||||
private static final int[] Pow_ary_date_short = new int[] {1048576, 65536, 2048, 64, 1};
|
||||
private static final int[] Base2_ary = new int[]
|
||||
{ 1, 2, 4, 8, 16, 32, 64, 128
|
||||
, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
|
||||
, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608
|
||||
, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 0
|
||||
};
|
||||
}
|
||||
69
400_xowa/src_020_byte/gplx/Bit__tst.java
Normal file
69
400_xowa/src_020_byte/gplx/Bit__tst.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
public class Bit__tst {
|
||||
@Test public void XtoBitStr() {
|
||||
tst_XtoBitStr( 0, "00000000");
|
||||
tst_XtoBitStr( 1, "00000001");
|
||||
tst_XtoBitStr( 2, "00000010");
|
||||
tst_XtoBitStr( 3, "00000011");
|
||||
tst_XtoBitStr(255, "11111111");
|
||||
} void tst_XtoBitStr(int val, String expd) {Tfds.Eq(expd, Bit_.XtoBitStr(val));}
|
||||
@Test public void Bld_pow_ary() {
|
||||
tst_Bld_pow_ary(ary_(1, 1, 1, 1), ary_(8, 4, 2, 1));
|
||||
tst_Bld_pow_ary(ary_(3, 2) , ary_(4, 1));
|
||||
} void tst_Bld_pow_ary(int[] seg_ary, int[] expd) {Tfds.Eq_ary_str(expd, Bit_.Bld_pow_ary(seg_ary));}
|
||||
@Test public void Xto_int() {
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(1, 1, 1, 1), 15);
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(0, 0, 0, 0), 0);
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(1, 0, 0, 1), 9);
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(0, 1, 1, 0), 6);
|
||||
tst_Xto_int(ary_(3, 2) , ary_(7, 3) , 31);
|
||||
tst_Xto_int(ary_(3, 2, 1) , ary_(7, 3, 1) , 63);
|
||||
tst_Xto_int(ary_(11, 4, 5, 5, 6), ary_(2012, 6, 3, 23, 17), 2110135761);
|
||||
tst_Xto_int(ary_(11, 4, 5, 5, 6), ary_(2012, 6, 3, 23, 18), 2110135762);
|
||||
}
|
||||
private void tst_Xto_int(int[] seg_ary, int[] val_ary, int expd) {
|
||||
int[] pow_ary = Bit_.Bld_pow_ary(seg_ary);
|
||||
Tfds.Eq(expd, Bit_.Xto_int(pow_ary, val_ary));
|
||||
}
|
||||
@Test public void Xto_intAry() {
|
||||
tst_Xto_intAry(ary_(1, 1, 1, 1) , 15, ary_(1, 1, 1, 1));
|
||||
tst_Xto_intAry(ary_(3, 2) , 31, ary_(7, 3));
|
||||
tst_Xto_intAry(ary_(3, 2, 1) , 63, ary_(7, 3, 1));
|
||||
tst_Xto_intAry(ary_(12, 4, 5, 5, 6), 2110135761, ary_(2012, 6, 3, 23, 17));
|
||||
tst_Xto_intAry(ary_(12, 4, 5, 5, 6), 2110135762, ary_(2012, 6, 3, 23, 18));
|
||||
}
|
||||
private void tst_Xto_intAry(int[] seg_ary, int val, int[] expd) {
|
||||
int[] pow_ary = Bit_.Bld_pow_ary(seg_ary);
|
||||
Tfds.Eq_ary_str(expd, Bit_.Xto_intAry(pow_ary, val));
|
||||
}
|
||||
int[] ary_(int... v) {return v;}
|
||||
@Test public void Xto_int_date_short() {
|
||||
tst_Xto_int_date_short("20120604 2359", 117843451);
|
||||
tst_Xto_int_date_short("20120604 2358", 117843450);
|
||||
tst_Xto_int_date_short("20120605 0000", 117843968);
|
||||
}
|
||||
private void tst_Xto_int_date_short(String date_str, int expd) {
|
||||
DateAdp date = DateAdp_.parse_fmt(date_str, "yyyyMMdd HHmm");
|
||||
int date_int = Bit_.Xto_int_date_short(date.XtoSegAry());
|
||||
Tfds.Eq(expd, date_int);
|
||||
Tfds.Eq(date_str, Bit_.Xto_date_short(date_int).XtoStr_fmt("yyyyMMdd HHmm"));
|
||||
}
|
||||
}
|
||||
43
400_xowa/src_020_byte/gplx/Bry_comparer.java
Normal file
43
400_xowa/src_020_byte/gplx/Bry_comparer.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import gplx.lists.*;
|
||||
public class Bry_comparer implements ComparerAble {
|
||||
public int compare(Object lhsObj, Object rhsObj) {
|
||||
byte[] lhs = (byte[])lhsObj, rhs = (byte[])rhsObj;
|
||||
return Bry_.Compare(lhs, 0, lhs.length, rhs, 0, rhs.length);
|
||||
}
|
||||
// public static int Compare(byte[] lhs, byte[] rhs, int lhs_bgn, int lhs_end, int rhs_bgn, int rhs_end) {
|
||||
// int lhs_len = lhs_end - lhs_bgn;
|
||||
// for (int i = 0; i < lhs_len; i++) {
|
||||
// int lhs_byte = lhs[i + lhs_bgn] & 0xff; // PATCH.JAVA:need to convert to unsigned byte
|
||||
// int rhs_idx = i + rhs_bgn; if (rhs_idx == rhs_end) return CompareAble_.More;
|
||||
// int rhs_byte = rhs[rhs_idx] & 0xff; // PATCH.JAVA:need to convert to unsigned byte
|
||||
// if (lhs_byte == rhs_byte) {
|
||||
// if (lhs_byte == Byte_ascii.Pipe) return CompareAble_.Same;
|
||||
// }
|
||||
// else {
|
||||
// if (rhs_byte == Byte_ascii.Pipe) return CompareAble_.More;
|
||||
// else if (lhs_byte == Byte_ascii.Pipe) return CompareAble_.Less;
|
||||
// else return lhs_byte < rhs_byte ? CompareAble_.Less : CompareAble_.More;
|
||||
// }
|
||||
// }
|
||||
// return Int_.Compare(lhs_len, rhs_end - rhs_bgn);
|
||||
// }
|
||||
public static final Bry_comparer _ = new Bry_comparer(); Bry_comparer() {}
|
||||
}
|
||||
49
400_xowa/src_020_byte/gplx/ByteTrieItm_slim_tst.java
Normal file
49
400_xowa/src_020_byte/gplx/ByteTrieItm_slim_tst.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
public class ByteTrieItm_slim_tst {
|
||||
private ByteTrieItm_slim itm = new ByteTrieItm_slim(Byte_.Zero, null, false);
|
||||
@Before public void init() {itm.Clear();}
|
||||
@Test public void Find_nil() {
|
||||
tst_Find(Byte_ascii.Ltr_a, null);
|
||||
}
|
||||
@Test public void Add_one() {
|
||||
run_Add(Byte_ascii.Ltr_a);
|
||||
tst_Find(Byte_ascii.Ltr_a, "a");
|
||||
}
|
||||
@Test public void Add_many() {
|
||||
run_Add(Byte_ascii.Bang, Byte_ascii.Num_0, Byte_ascii.Ltr_a, Byte_ascii.Ltr_B);
|
||||
tst_Find(Byte_ascii.Ltr_a, "a");
|
||||
}
|
||||
@Test public void Del() {
|
||||
run_Add(Byte_ascii.Bang, Byte_ascii.Num_0, Byte_ascii.Ltr_a, Byte_ascii.Ltr_B);
|
||||
tst_Find(Byte_ascii.Ltr_a, "a");
|
||||
run_Del(Byte_ascii.Ltr_a);
|
||||
tst_Find(Byte_ascii.Ltr_a, null);
|
||||
tst_Find(Byte_ascii.Num_0, "0");
|
||||
tst_Find(Byte_ascii.Ltr_B, "B");
|
||||
}
|
||||
private void tst_Find(byte b, String expd) {
|
||||
ByteTrieItm_slim 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_.XtoStr((char)b));}
|
||||
private void run_Del(byte... ary) {for (byte b : ary) itm.Ary_del(b);}
|
||||
}
|
||||
87
400_xowa/src_020_byte/gplx/ByteTrieMgr_bwd_slim.java
Normal file
87
400_xowa/src_020_byte/gplx/ByteTrieMgr_bwd_slim.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class ByteTrieMgr_bwd_slim {
|
||||
public int Match_pos() {return match_pos;} private int match_pos;
|
||||
public Object MatchAtCurExact(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 MatchAtCur(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;
|
||||
ByteTrieItm_slim cur = root;
|
||||
while (true) {
|
||||
ByteTrieItm_slim 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 ByteTrieMgr_bwd_slim Add_str_byte(String key, byte val) {return Add(Bry_.new_utf8_(key), Byte_obj_val.new_(val));}
|
||||
public ByteTrieMgr_bwd_slim 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_utf8_(itm), byteVal);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public ByteTrieMgr_bwd_slim Add(String key, Object val) {return Add(Bry_.new_utf8_(key), val);}
|
||||
public ByteTrieMgr_bwd_slim Add(byte[] key, Object val) {
|
||||
if (val == null) throw Err_.new_("null objects cannot be registered").Add("key", String_.new_utf8_(key));
|
||||
int key_len = key.length;
|
||||
ByteTrieItm_slim 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;
|
||||
ByteTrieItm_slim 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;
|
||||
ByteTrieItm_slim 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 ByteTrieMgr_bwd_slim cs_() {return new ByteTrieMgr_bwd_slim(false);}
|
||||
public static ByteTrieMgr_bwd_slim ci_() {return new ByteTrieMgr_bwd_slim(true);}
|
||||
public ByteTrieMgr_bwd_slim(boolean caseAny) {
|
||||
root = new ByteTrieItm_slim(Byte_.Zero, null, caseAny);
|
||||
} private ByteTrieItm_slim root;
|
||||
}
|
||||
87
400_xowa/src_020_byte/gplx/ByteTrieMgr_bwd_slim_tst.java
Normal file
87
400_xowa/src_020_byte/gplx/ByteTrieMgr_bwd_slim_tst.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
public class ByteTrieMgr_bwd_slim_tst {
|
||||
@Before public void init() {} private ByteTrieMgr_bwd_slim trie;
|
||||
private void ini_setup1() {
|
||||
trie = new ByteTrieMgr_bwd_slim(false);
|
||||
run_Add("c" , 1);
|
||||
run_Add("abc" , 123);
|
||||
}
|
||||
@Test public void Fetch() {
|
||||
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 ByteTrieMgr_bwd_slim(false);
|
||||
run_Add("a<EFBFBD>", 1);
|
||||
tst_MatchAtCur("a<EFBFBD>" , 1);
|
||||
tst_MatchAtCur("<EFBFBD>" , null);
|
||||
}
|
||||
@Test public void Eos() {
|
||||
ini_setup1();
|
||||
tst_Match("ab", Byte_ascii.Ltr_c, 2, 123);
|
||||
}
|
||||
@Test public void MatchAtCurExact() {
|
||||
ini_setup1();
|
||||
tst_MatchAtCurExact("c", 1);
|
||||
tst_MatchAtCurExact("bc", null);
|
||||
tst_MatchAtCurExact("abc", 123);
|
||||
}
|
||||
private void ini_setup2() {
|
||||
trie = new ByteTrieMgr_bwd_slim(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 = ByteTrieMgr_bwd_slim.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_utf8_(k), val);}
|
||||
private void tst_Match(String srcStr, byte b, int bgn_pos, int expd) {
|
||||
byte[] src = Bry_.new_utf8_(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_utf8_(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_utf8_(srcStr);
|
||||
Object actl = trie.MatchAtCurExact(src, src.length - 1, -1);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
}
|
||||
154
400_xowa/src_020_byte/gplx/ByteTrieMgr_fast.java
Normal file
154
400_xowa/src_020_byte/gplx/ByteTrieMgr_fast.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class ByteTrieMgr_fast {
|
||||
private ByteTrieItm_fast root;
|
||||
public boolean CaseAny() {return root.CaseAny();} public ByteTrieMgr_fast CaseAny_(boolean v) {root.CaseAny_(v); return this;}
|
||||
public int Match_pos() {return match_pos;} private int match_pos;
|
||||
public Object MatchAtCurExact(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 MatchAtCur(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 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 ByteTrieMgr_fast Add_bry_bval(byte key, byte val) {return Add(new byte[] {key}, Byte_obj_val.new_(val));}
|
||||
public ByteTrieMgr_fast Add_bry_bval(byte[] key, byte val) {return Add(key, Byte_obj_val.new_(val));}
|
||||
public ByteTrieMgr_fast Add(byte key, Object val) {return Add(new byte[] {key}, val);}
|
||||
public ByteTrieMgr_fast Add(String key, Object val) {return Add(Bry_.new_utf8_(key), val);}
|
||||
public ByteTrieMgr_fast Add(byte[] key, Object val) {
|
||||
if (val == null) throw Err_.new_("null objects cannot be registered").Add("key", String_.new_utf8_(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 ByteTrieMgr_fast Add_stub(byte tid, String s) {
|
||||
byte[] bry = Bry_.new_utf8_(s);
|
||||
ByteTrie_stub stub = new ByteTrie_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(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.XtoAryAndClear() : src;
|
||||
}
|
||||
public static ByteTrieMgr_fast cs_() {return new ByteTrieMgr_fast(false);}
|
||||
public static ByteTrieMgr_fast ci_ascii_() {return new ByteTrieMgr_fast(true);}
|
||||
public static ByteTrieMgr_fast new_(boolean case_any) {return new ByteTrieMgr_fast(case_any);}
|
||||
ByteTrieMgr_fast(boolean caseAny) {
|
||||
root = new ByteTrieItm_fast(Byte_.Zero, null, caseAny);
|
||||
}
|
||||
}
|
||||
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 caseAny;} public ByteTrieItm_fast CaseAny_(boolean v) {caseAny = v; return this;} private boolean caseAny;
|
||||
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 = (caseAny && (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 = (caseAny && (b > 64 && b < 91) ? b + 32 : b) & 0xff;// PATCH.JAVA:need to convert to unsigned byte
|
||||
ByteTrieItm_fast rv = new ByteTrieItm_fast(b, val, caseAny);
|
||||
ary[key_byte] = rv;
|
||||
++ary_len;
|
||||
ary_is_empty = false;
|
||||
return rv;
|
||||
}
|
||||
public void Ary_del(byte b) {
|
||||
int key_byte = (caseAny && (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 caseAny) {this.key_byte = key_byte; this.val = val; this.caseAny = caseAny;}
|
||||
}
|
||||
85
400_xowa/src_020_byte/gplx/ByteTrieMgr_fast_tst.java
Normal file
85
400_xowa/src_020_byte/gplx/ByteTrieMgr_fast_tst.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
public class ByteTrieMgr_fast_tst {
|
||||
private ByteTrieMgr_fast_fxt fxt = new ByteTrieMgr_fast_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Fetch() {
|
||||
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", Byte_ascii.Ltr_a, -1, 123);
|
||||
}
|
||||
@Test public void MatchAtCurExact() {
|
||||
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 ByteTrieMgr_fast_fxt {
|
||||
private ByteTrieMgr_fast trie;
|
||||
public void Clear() {
|
||||
trie = ByteTrieMgr_fast.cs_();
|
||||
Init_add( 1 , Byte_ascii.Ltr_a);
|
||||
Init_add(123 , Byte_ascii.Ltr_a, Byte_ascii.Ltr_b, Byte_ascii.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_ascii_(src_str);
|
||||
Object actl = trie.Match(b, src, bgn_pos, src.length);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
public void Test_matchAtCur(String src_str, Object expd) {
|
||||
byte[] src = Bry_.new_ascii_(src_str);
|
||||
Object actl = trie.MatchAtCur(src, 0, src.length);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
public void Test_matchAtCurExact(String src_str, Object expd) {
|
||||
byte[] src = Bry_.new_ascii_(src_str);
|
||||
Object actl = trie.MatchAtCurExact(src, 0, src.length);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
public void Exec_del(String src_str) {
|
||||
trie.Del(Bry_.new_utf8_(src_str));
|
||||
}
|
||||
}
|
||||
237
400_xowa/src_020_byte/gplx/ByteTrieMgr_slim.java
Normal file
237
400_xowa/src_020_byte/gplx/ByteTrieMgr_slim.java
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class ByteTrieMgr_slim {
|
||||
ByteTrieMgr_slim(boolean case_match) {root = new ByteTrieItm_slim(Byte_.Zero, null, !case_match);} private ByteTrieItm_slim root;
|
||||
public int Count() {return count;} private int count;
|
||||
public int Match_pos() {return match_pos;} private int match_pos;
|
||||
public Object MatchAtCurExact(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 MatchAtCur(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 src_len) {
|
||||
Object rv = null; int cur_pos = match_pos = bgn_pos;
|
||||
ByteTrieItm_slim cur = root;
|
||||
while (true) {
|
||||
ByteTrieItm_slim 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 == src_len) return rv; // increment cur_pos and exit if src_len
|
||||
b = src[cur_pos];
|
||||
cur = nxt;
|
||||
}
|
||||
}
|
||||
public ByteTrieMgr_slim Add_str_byte(String key, byte val) {return Add(Bry_.new_utf8_(key), Byte_obj_val.new_(val));}
|
||||
public ByteTrieMgr_slim Add_bry(String key, String val) {return Add(Bry_.new_utf8_(key), Bry_.new_utf8_(val));}
|
||||
public ByteTrieMgr_slim Add_bry(String key, byte[] val) {return Add(Bry_.new_utf8_(key), val);}
|
||||
public ByteTrieMgr_slim Add_bry(byte[] v) {return Add(v, v);}
|
||||
public ByteTrieMgr_slim Add_bry_bval(byte b, byte val) {return Add(new byte[] {b}, Byte_obj_val.new_(val));}
|
||||
public ByteTrieMgr_slim Add_bry_bval(byte[] bry, byte val) {return Add(bry, Byte_obj_val.new_(val));}
|
||||
public ByteTrieMgr_slim Add_str_byte__many(byte val, String... ary) {
|
||||
int ary_len = ary.length;
|
||||
Byte_obj_val bval = Byte_obj_val.new_(val);
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
Add(Bry_.new_utf8_(ary[i]), bval);
|
||||
return this;
|
||||
}
|
||||
public ByteTrieMgr_slim Add_stub(String key, byte val) {byte[] bry = Bry_.new_utf8_(key); return Add(bry, new ByteTrie_stub(val, bry));}
|
||||
public ByteTrieMgr_slim Add_stubs(byte[][] ary) {return Add_stubs(ary, ary.length);}
|
||||
public ByteTrieMgr_slim Add_stubs(byte[][] ary, int ary_len) {
|
||||
for (byte i = 0; i < ary_len; i++) {
|
||||
byte[] bry = ary[i];
|
||||
this.Add(bry, new ByteTrie_stub(i, bry));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public ByteTrieMgr_slim Add(String key, Object val) {return Add(Bry_.new_utf8_(key), val);}
|
||||
public ByteTrieMgr_slim Add(byte[] key, Object val) {
|
||||
if (val == null) throw Err_.new_("null objects cannot be registered").Add("key", String_.new_utf8_(key));
|
||||
int key_len = key.length; int key_end = key_len - 1;
|
||||
ByteTrieItm_slim cur = root;
|
||||
for (int i = 0; i < key_len; i++) {
|
||||
byte b = key[i];
|
||||
if (root.Case_any() && (b > 64 && b < 91)) b += 32;
|
||||
ByteTrieItm_slim nxt = cur.Ary_find(b);
|
||||
if (nxt == null)
|
||||
nxt = cur.Ary_add(b, null);
|
||||
if (i == key_end)
|
||||
nxt.Val_set(val);
|
||||
cur = nxt;
|
||||
}
|
||||
count++; // FUTURE: do not increment if replacing value
|
||||
return this;
|
||||
}
|
||||
public void Del(byte[] key) {
|
||||
int key_len = key.length;
|
||||
ByteTrieItm_slim cur = root;
|
||||
for (int i = 0; i < key_len; i++) {
|
||||
byte b = key[i];
|
||||
ByteTrieItm_slim nxt = cur.Ary_find(b);
|
||||
if (nxt == null) break;
|
||||
Object nxt_val = nxt.Val();
|
||||
if (nxt_val == null) // cur is end of chain; remove entry; EX: Abc and at c
|
||||
cur.Ary_del(b);
|
||||
else // cur is mid of chain; null out entry
|
||||
nxt.Val_set(null);
|
||||
cur = nxt;
|
||||
}
|
||||
count--; // FUTURE: do not decrement if not found
|
||||
}
|
||||
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(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.XtoAryAndClear() : src;
|
||||
}
|
||||
public void Clear() {root.Clear(); count = 0;}
|
||||
public static ByteTrieMgr_slim cs_() {return new ByteTrieMgr_slim(true);}
|
||||
public static ByteTrieMgr_slim ci_ascii_() {return new ByteTrieMgr_slim(false);}
|
||||
public static ByteTrieMgr_slim ci_utf_8_() {return new ByteTrieMgr_slim(false);}
|
||||
public static ByteTrieMgr_slim new_(boolean v) {return new ByteTrieMgr_slim(v);}
|
||||
}
|
||||
class ByteTrieItm_slim {
|
||||
private ByteTrieItm_slim[] ary = ByteTrieItm_slim.Ary_empty;
|
||||
public ByteTrieItm_slim(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;} Object val;
|
||||
public boolean Case_any() {return case_any;} private boolean case_any;
|
||||
public boolean Ary_is_empty() {return ary == ByteTrieItm_slim.Ary_empty;}
|
||||
public void Clear() {
|
||||
val = null;
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i].Clear();
|
||||
ary = ByteTrieItm_slim.Ary_empty;
|
||||
ary_len = ary_max = 0;
|
||||
}
|
||||
public ByteTrieItm_slim 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:
|
||||
ByteTrieItm_slim 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;
|
||||
ByteTrieItm_slim 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 ByteTrieItm_slim Ary_add(byte b, Object val) {
|
||||
int new_len = ary_len + 1;
|
||||
if (new_len > ary_max) {
|
||||
ary_max += 4;
|
||||
ary = (ByteTrieItm_slim[])Array_.Resize(ary, ary_max);
|
||||
}
|
||||
ByteTrieItm_slim rv = new ByteTrieItm_slim(b, val, case_any);
|
||||
ary[ary_len] = rv;
|
||||
ary_len = new_len;
|
||||
ByteHashItm_sorter._.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 ByteTrieItm_slim[] Ary_empty = new ByteTrieItm_slim[0]; int ary_len = 0, ary_max = 0;
|
||||
}
|
||||
class ByteHashItm_sorter {// quicksort
|
||||
ByteTrieItm_slim[] ary; int ary_len;
|
||||
public void Sort(ByteTrieItm_slim[] 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) {
|
||||
ByteTrieItm_slim 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 _ = new ByteHashItm_sorter(); ByteHashItm_sorter() {}
|
||||
}
|
||||
92
400_xowa/src_020_byte/gplx/ByteTrieMgr_slim_tst.java
Normal file
92
400_xowa/src_020_byte/gplx/ByteTrieMgr_slim_tst.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
public class ByteTrieMgr_slim_tst {
|
||||
@Before public void init() {
|
||||
} private ByteTrieMgr_slim trie;
|
||||
private void ini_setup1() {
|
||||
trie = ByteTrieMgr_slim.cs_();
|
||||
run_Add("a" , 1);
|
||||
run_Add("abc" , 123);
|
||||
}
|
||||
@Test public void Fetch() {
|
||||
ini_setup1();
|
||||
tst_MatchAtCur("a" , 1);
|
||||
tst_MatchAtCur("abc" , 123);
|
||||
tst_MatchAtCur("ab" , 1);
|
||||
tst_MatchAtCur("abcde" , 123);
|
||||
tst_MatchAtCur(" a" , null);
|
||||
}
|
||||
@Test public void Bos() {
|
||||
ini_setup1();
|
||||
tst_Match("bc", Byte_ascii.Ltr_a, -1, 123);
|
||||
}
|
||||
@Test public void MatchAtCurExact() {
|
||||
ini_setup1();
|
||||
tst_MatchAtCurExact("a", 1);
|
||||
tst_MatchAtCurExact("ab", null);
|
||||
tst_MatchAtCurExact("abc", 123);
|
||||
}
|
||||
private void ini_setup2() {
|
||||
trie = ByteTrieMgr_slim.cs_();
|
||||
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 = ByteTrieMgr_slim.ci_ascii_(); // NOTE:ci.ascii:test
|
||||
run_Add("a" , 1);
|
||||
run_Add("b" , 2);
|
||||
}
|
||||
@Test public void CaseAny() {
|
||||
ini_setup_caseAny();
|
||||
tst_MatchAtCur("a", 1);
|
||||
tst_MatchAtCur("A", 1);
|
||||
}
|
||||
@Test public void Del() {
|
||||
ini_setup1();
|
||||
trie.Del(Bry_.new_ascii_("a")); // delete "a"; "abc" still remains;
|
||||
tst_MatchAtCur("a" , null);
|
||||
tst_MatchAtCur("abc" , 123);
|
||||
|
||||
trie.Del(Bry_.new_ascii_("abc"));
|
||||
tst_MatchAtCur("abc" , null);
|
||||
}
|
||||
|
||||
private void run_Add(String k, int val) {trie.Add(Bry_.new_ascii_(k), val);}
|
||||
private void tst_Match(String srcStr, byte b, int bgn_pos, int expd) {
|
||||
byte[] src = Bry_.new_ascii_(srcStr);
|
||||
Object actl = trie.Match(b, src, bgn_pos, src.length);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
private void tst_MatchAtCur(String srcStr, Object expd) {
|
||||
byte[] src = Bry_.new_ascii_(srcStr);
|
||||
Object actl = trie.Match(src[0], src, 0, src.length);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
private void tst_MatchAtCurExact(String srcStr, Object expd) {
|
||||
byte[] src = Bry_.new_ascii_(srcStr);
|
||||
Object actl = trie.MatchAtCurExact(src, 0, src.length);
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
}
|
||||
23
400_xowa/src_020_byte/gplx/ByteTrie_stub.java
Normal file
23
400_xowa/src_020_byte/gplx/ByteTrie_stub.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class ByteTrie_stub {
|
||||
public ByteTrie_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;
|
||||
}
|
||||
25
400_xowa/src_020_byte/gplx/Byte_xml.java
Normal file
25
400_xowa/src_020_byte/gplx/Byte_xml.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class Byte_xml {
|
||||
public static final byte Nde_bgn = Byte_ascii.Lt, Nde_end = Byte_ascii.Gt
|
||||
, Apos = Byte_ascii.Apos
|
||||
, Space = Byte_ascii.Space
|
||||
;
|
||||
public static final byte[] Nde_close_bgn = Bry_.new_ascii_("</");
|
||||
}
|
||||
48
400_xowa/src_020_byte/gplx/Gfo_fld_base.java
Normal file
48
400_xowa/src_020_byte/gplx/Gfo_fld_base.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class Gfo_fld_base {
|
||||
public byte Row_dlm() {return row_dlm;} public Gfo_fld_base Row_dlm_(byte v) {row_dlm = v; return this;} protected byte row_dlm = Byte_ascii.NewLine;
|
||||
public byte Fld_dlm() {return fld_dlm;} public Gfo_fld_base Fld_dlm_(byte v) {fld_dlm = v; return this;} protected byte fld_dlm = Byte_ascii.Pipe;
|
||||
public byte Escape_dlm() {return escape_dlm;} public Gfo_fld_base Escape_dlm_(byte v) {escape_dlm = v; return this;} protected byte escape_dlm = Byte_ascii.Tilde;
|
||||
public byte Quote_dlm() {return quote_dlm;} public Gfo_fld_base Quote_dlm_(byte v) {quote_dlm = v; return this;} protected byte quote_dlm = Byte_ascii.Nil;
|
||||
public Gfo_fld_base Escape_reg(byte b) {return Escape_reg(b, b);}
|
||||
public byte[] Escape_decode() {return decode_regy;}
|
||||
public Gfo_fld_base Escape_reg(byte key, byte val) {encode_regy[key] = val; decode_regy[val] = key; return this;} protected byte[] decode_regy = new byte[256]; protected byte[] encode_regy = new byte[256];
|
||||
public Gfo_fld_base Escape_clear() {
|
||||
for (int i = 0; i < 256; i++)
|
||||
decode_regy[i] = Byte_ascii.Nil;
|
||||
for (int i = 0; i < 256; i++)
|
||||
encode_regy[i] = Byte_ascii.Nil;
|
||||
return this;
|
||||
}
|
||||
Gfo_fld_base Ini_common() {
|
||||
return Escape_reg(Byte_ascii.NewLine, Byte_ascii.Ltr_n).Escape_reg(Byte_ascii.Tab, Byte_ascii.Ltr_t).Escape_reg(Byte_ascii.CarriageReturn, Byte_ascii.Ltr_r)
|
||||
.Escape_reg(Byte_ascii.Backfeed, Byte_ascii.Ltr_b); // .Escape_reg(Byte_ascii.Nil, Byte_ascii.Num_0)
|
||||
}
|
||||
protected Gfo_fld_base Ctor_xdat_base() {
|
||||
return Escape_clear().Ini_common()
|
||||
.Fld_dlm_(Byte_ascii.Pipe).Row_dlm_(Byte_ascii.NewLine).Escape_dlm_(Byte_ascii.Tilde).Quote_dlm_(Byte_ascii.Nil)
|
||||
.Escape_reg(Byte_ascii.Pipe, Byte_ascii.Ltr_p).Escape_reg(Byte_ascii.Tilde);
|
||||
}
|
||||
protected Gfo_fld_base Ctor_sql_base() {
|
||||
return Escape_clear().Ini_common()
|
||||
.Fld_dlm_(Byte_ascii.Comma).Row_dlm_(Byte_ascii.Paren_end).Escape_dlm_(Byte_ascii.Backslash).Quote_dlm_(Byte_ascii.Apos)
|
||||
.Escape_reg(Byte_ascii.Backslash).Escape_reg(Byte_ascii.Quote).Escape_reg(Byte_ascii.Apos); // , Escape_eof = Bry_.new_utf8_("\\Z")
|
||||
}
|
||||
}
|
||||
124
400_xowa/src_020_byte/gplx/Gfo_fld_rdr.java
Normal file
124
400_xowa/src_020_byte/gplx/Gfo_fld_rdr.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
public class Gfo_fld_rdr extends Gfo_fld_base {
|
||||
private Bry_bfr bfr = Bry_bfr.new_(); private static final byte[] Bry_nil = Bry_.new_ascii_("\\0");
|
||||
public byte[] Data() {return data;} public Gfo_fld_rdr Data_(byte[] v) {data = v; data_len = v.length; pos = 0; return this;} private byte[] data; int data_len;
|
||||
public int Pos() {return pos;} public Gfo_fld_rdr Pos_(int v) {pos = v; return this;} private int pos;
|
||||
public int Fld_bgn() {return fld_bgn;} public Gfo_fld_rdr Fld_bgn_(int v) {fld_bgn = v; return this;} private int fld_bgn;
|
||||
public int Fld_end() {return fld_end;} public Gfo_fld_rdr Fld_end_(int v) {fld_end = v; return this;} private int fld_end;
|
||||
public int Fld_idx() {return fld_idx;} private int fld_idx;
|
||||
public int Row_idx() {return row_idx;} private int row_idx;
|
||||
public void Ini(byte[] data, int pos) {this.data = data; this.data_len = data.length; this.pos = pos;}
|
||||
|
||||
public String Read_str_simple() {Move_next_simple(); return String_.new_utf8_(data, fld_bgn, fld_end);}
|
||||
public byte[] Read_bry_simple() {Move_next_simple(); return Bry_.Mid(data, fld_bgn, fld_end);} // was Mid_by_len???; 20120915
|
||||
public int Read_int_base85_lenN(int len) {fld_bgn = pos; fld_end = pos + len - 1 ; pos = pos + len + 1 ; return Base85_utl.XtoIntByAry(data, fld_bgn, fld_end);}
|
||||
public int Read_int_base85_len5() {fld_bgn = pos; fld_end = pos + 4 ; pos = pos + 6 ; return Base85_utl.XtoIntByAry(data, fld_bgn, fld_end);}
|
||||
public int Read_int() {Move_next_simple(); return Bry_.X_to_int_or(data, fld_bgn, fld_end, -1);}
|
||||
public byte Read_int_as_byte() {Move_next_simple(); return (byte)Bry_.X_to_int_or(data, fld_bgn, fld_end, -1);}
|
||||
public byte Read_byte() {Move_next_simple(); return data[fld_bgn];}
|
||||
public double Read_double() {Move_next_simple(); return Bry_.XtoDoubleByPos(data, fld_bgn, fld_end);}
|
||||
public DateAdp Read_dte() {// NOTE: fmt = yyyyMMdd HHmmss.fff
|
||||
int y = 0, M = 0, d = 0, H = 0, m = 0, s = 0, f = 0;
|
||||
if (pos < data_len && data[pos] == row_dlm) {++pos; ++row_idx; fld_idx = 0;} fld_bgn = pos;
|
||||
y += (data[fld_bgn + 0] - Byte_ascii.Num_0) * 1000;
|
||||
y += (data[fld_bgn + 1] - Byte_ascii.Num_0) * 100;
|
||||
y += (data[fld_bgn + 2] - Byte_ascii.Num_0) * 10;
|
||||
y += (data[fld_bgn + 3] - Byte_ascii.Num_0);
|
||||
M += (data[fld_bgn + 4] - Byte_ascii.Num_0) * 10;
|
||||
M += (data[fld_bgn + 5] - Byte_ascii.Num_0);
|
||||
d += (data[fld_bgn + 6] - Byte_ascii.Num_0) * 10;
|
||||
d += (data[fld_bgn + 7] - Byte_ascii.Num_0);
|
||||
H += (data[fld_bgn + 9] - Byte_ascii.Num_0) * 10;
|
||||
H += (data[fld_bgn + 10] - Byte_ascii.Num_0);
|
||||
m += (data[fld_bgn + 11] - Byte_ascii.Num_0) * 10;
|
||||
m += (data[fld_bgn + 12] - Byte_ascii.Num_0);
|
||||
s += (data[fld_bgn + 13] - Byte_ascii.Num_0) * 10;
|
||||
s += (data[fld_bgn + 14] - Byte_ascii.Num_0);
|
||||
f += (data[fld_bgn + 16] - Byte_ascii.Num_0) * 100;
|
||||
f += (data[fld_bgn + 17] - Byte_ascii.Num_0) * 10;
|
||||
f += (data[fld_bgn + 18] - Byte_ascii.Num_0);
|
||||
if (data[fld_bgn + 19] != fld_dlm) throw Err_.new_("csv date is invalid").Add("txt", String_.new_utf8_len_safe_(data, fld_bgn, 20));
|
||||
fld_end = pos + 20;
|
||||
pos = fld_end + 1; ++fld_idx;
|
||||
return DateAdp_.new_(y, M, d, H, m, s, f);
|
||||
}
|
||||
public void Move_next_simple() {
|
||||
if (pos < data_len) {
|
||||
byte b_cur = data[pos];
|
||||
if (b_cur == row_dlm) {
|
||||
fld_bgn = fld_end = pos;
|
||||
++pos; ++row_idx;
|
||||
fld_idx = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fld_bgn = pos;
|
||||
if (fld_bgn == data_len) {fld_end = data_len; return;}
|
||||
for (int i = fld_bgn; i < data_len; i++) {
|
||||
byte b = data[i];
|
||||
if (b == fld_dlm || b == row_dlm) {
|
||||
fld_end = i; pos = i + 1; ++fld_idx; // position after dlm
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw Err_.new_("fld_dlm failed").Add("fld_dlm", (char)fld_dlm).Add("bgn", fld_bgn);
|
||||
}
|
||||
public String Read_str_escape() {Move_next_escaped(bfr); return String_.new_utf8_(bfr.XtoAryAndClear());}
|
||||
public byte[] Read_bry_escape() {Move_next_escaped(bfr); return bfr.XtoAryAndClear();}
|
||||
public void Move_1() {++pos;}
|
||||
public void Move_next_escaped() {Move_next_escaped(bfr); bfr.Clear();}
|
||||
public int Move_next_simple_fld() {
|
||||
Move_next_simple();
|
||||
return fld_end;
|
||||
}
|
||||
public int Move_next_escaped(Bry_bfr trg) {
|
||||
//if (pos < data_len && data[pos] == row_dlm) {++pos; ++row_idx; fld_idx = 0;} // REMOVE:20120919: this will fail for empty fields at end of line; EX: "a|\n"; intent was probably to auto-advance to new row, but this intent should be explicit
|
||||
fld_bgn = pos;
|
||||
boolean quote_on = false;
|
||||
for (int i = fld_bgn; i < data_len; i++) {
|
||||
byte b = data[i];
|
||||
if ((b == fld_dlm || b == row_dlm) && !quote_on) {
|
||||
fld_end = i; pos = i + 1; ++fld_idx; // position after dlm
|
||||
return pos;
|
||||
}
|
||||
else if (b == escape_dlm) {
|
||||
++i;
|
||||
// if (i == data_len) throw Err_.new_("escape char at end of String");
|
||||
b = data[i];
|
||||
byte escape_val = decode_regy[b];
|
||||
if (escape_val == Byte_ascii.Nil) {trg.Add_byte(escape_dlm).Add_byte(b);} //throw Err_.new_fmt_("unknown escape key: key={0}", data[i]);
|
||||
else trg.Add_byte(escape_val);
|
||||
}
|
||||
else if (b == Byte_ascii.Nil) {
|
||||
trg.Add(Bry_nil);
|
||||
}
|
||||
else if (b == quote_dlm) {
|
||||
quote_on = !quote_on;
|
||||
}
|
||||
else
|
||||
trg.Add_byte(b);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public Gfo_fld_rdr Ctor_xdat() {return (Gfo_fld_rdr)super.Ctor_xdat_base();}
|
||||
public Gfo_fld_rdr Ctor_sql() {return (Gfo_fld_rdr)super.Ctor_sql_base();}
|
||||
public static Gfo_fld_rdr xowa_() {return new Gfo_fld_rdr().Ctor_xdat();}
|
||||
public static Gfo_fld_rdr sql_() {return new Gfo_fld_rdr().Ctor_sql();}
|
||||
}
|
||||
56
400_xowa/src_020_byte/gplx/Gfo_fld_rdr_tst.java
Normal file
56
400_xowa/src_020_byte/gplx/Gfo_fld_rdr_tst.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
import gplx.ios.*;
|
||||
public class Gfo_fld_rdr_tst {
|
||||
Gfo_fld_rdr_fxt fxt = new Gfo_fld_rdr_fxt();
|
||||
@Test public void Read_int() {fxt.ini_xdat().Raw_("123|") .tst_Read_int(123);}
|
||||
@Test public void Read_double() {fxt.ini_xdat().Raw_("1.23|") .tst_Read_double(1.23);}
|
||||
@Test public void Read_str_simple() {fxt.ini_xdat().Raw_("ab|") .tst_Read_str_simple("ab");}
|
||||
@Test public void Read_str_escape_pipe() {fxt.ini_xdat().Raw_("a~pb|") .tst_Read_str_escape("a|b");}
|
||||
@Test public void Read_str_escape_tilde() {fxt.ini_xdat().Raw_("a~~b|") .tst_Read_str_escape("a~b");}
|
||||
@Test public void Read_str_escape_nl() {fxt.ini_xdat().Raw_("a~nb|") .tst_Read_str_escape("a\nb");}
|
||||
@Test public void Read_str_escape_tab() {fxt.ini_xdat().Raw_("a~tb|") .tst_Read_str_escape("a\tb");}
|
||||
@Test public void Write_str_escape_pipe() {fxt.ini_xdat().tst_Write_str_escape("a|b", "a~pb|");}
|
||||
@Test public void Read_str_quoted_comma() {fxt.ini_sql ().Raw_("'a,b',") .tst_Read_str_escape("a,b");}
|
||||
@Test public void Read_str_quoted_apos() {fxt.ini_sql ().Raw_("'a\\'b',") .tst_Read_str_escape("a'b");}
|
||||
@Test public void Read_multiple() {
|
||||
fxt.ini_xdat().Raw_("ab|1|.9|\n")
|
||||
.tst_Read_str_escape("ab").tst_Read_int(1).tst_Read_double(.9)
|
||||
;
|
||||
}
|
||||
@Test public void Read_dlm_nl() {fxt.ini_xdat().Raw_("123\n") .tst_Read_int(123);}
|
||||
}
|
||||
class Gfo_fld_rdr_fxt {
|
||||
Gfo_fld_rdr rdr = new Gfo_fld_rdr(); Gfo_fld_wtr wtr = Gfo_fld_wtr.xowa_();
|
||||
public Gfo_fld_rdr_fxt Raw_(String v) {rdr.Data_(Bry_.new_utf8_(v)); return this;}
|
||||
public Gfo_fld_rdr_fxt ini_xdat() {rdr.Ctor_xdat(); return this;}
|
||||
public Gfo_fld_rdr_fxt ini_sql() {rdr.Ctor_sql(); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_int(int expd) {Tfds.Eq(expd, rdr.Read_int()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_double(double expd) {Tfds.Eq(expd, rdr.Read_double()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_str_simple(String expd) {Tfds.Eq(expd, rdr.Read_str_simple()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_str_escape(String expd) {Tfds.Eq(expd, rdr.Read_str_escape()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Write_str_escape(String val, String expd) {
|
||||
byte[] bry = Bry_.new_utf8_(val);
|
||||
wtr.Bfr_(bfr);
|
||||
wtr.Write_bry_escape_fld(bry);
|
||||
Tfds.Eq(expd, bfr.XtoStr());
|
||||
return this;
|
||||
} private Bry_bfr bfr = Bry_bfr.new_();
|
||||
}
|
||||
59
400_xowa/src_020_byte/gplx/Gfo_fld_wtr.java
Normal file
59
400_xowa/src_020_byte/gplx/Gfo_fld_wtr.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import gplx.ios.*;
|
||||
public class Gfo_fld_wtr extends Gfo_fld_base {
|
||||
public Bry_bfr Bfr() {return bfr;} public Gfo_fld_wtr Bfr_(Bry_bfr v) {bfr = v; return this;} Bry_bfr bfr;
|
||||
public Gfo_fld_wtr() {this.bfr = Bry_bfr.new_();}
|
||||
public Gfo_fld_wtr Write_int_base85_len5_fld(int v) {bfr.Add_base85(v, Base85_utl.Len_int); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_base85_lenN_fld(int v, int len) {bfr.Add_base85(v, len); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_variable_fld(int v) {bfr.Add_int_variable(v); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_fixed_fld(int v, int len) {bfr.Add_int_fixed(v, len); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_double_fld(double v) {bfr.Add_double(v); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_byte_fld(byte v) {bfr.Add_byte(v); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_fld(byte[] val) {Write_bry_escape(val, 0, val.length); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_fld(byte[] val, int bgn, int end) {Write_bry_escape(val, bgn, end); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_dlm_row() { bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_dlm_fld() { bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_base85_lenN_row(int v, int len) {bfr.Add_base85(v, len); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_base85_len5_row(int v) {bfr.Add_base85(v, Base85_utl.Len_int); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_row(byte[] val) {Write_bry_escape(val, 0, val.length); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_row(byte[] val, int bgn, int end) {Write_bry_escape(val, bgn, end); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_double_row(double v) {bfr.Add_double(v); bfr.Add_byte(row_dlm); return this;}
|
||||
Gfo_fld_wtr Write_bry_escape(byte[] val, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = val[i];
|
||||
byte escape_val = encode_regy[b & 0xFF]; // PATCH.JAVA:need to convert to unsigned byte
|
||||
if (escape_val == Byte_ascii.Nil) bfr.Add_byte(b);
|
||||
else {bfr.Add_byte(escape_dlm); bfr.Add_byte(escape_val);}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Gfo_fld_wtr Rls() {bfr.Rls(); return this;}
|
||||
|
||||
public Io_url_gen Fil_gen() {return fil_gen;} public Gfo_fld_wtr Fil_gen_(Io_url_gen v) {fil_gen = v; return this;} Io_url_gen fil_gen;
|
||||
public int Bfr_max() {return bfr_max;} public Gfo_fld_wtr Bfr_max_(int v) {bfr_max = v; return this;} private int bfr_max = Io_mgr.Len_mb;
|
||||
public boolean Flush_needed(int v) {return bfr.Len() + v > bfr_max;}
|
||||
public void Flush() {
|
||||
if (Fil_gen().Cur_url() == null) fil_gen.Nxt_url();
|
||||
Io_mgr._.AppendFilBfr(fil_gen.Cur_url(), bfr);
|
||||
}
|
||||
public void Flush_nxt() {Flush(); fil_gen.Nxt_url();}
|
||||
public Gfo_fld_wtr Ctor_xdat() {return (Gfo_fld_wtr)super.Ctor_xdat_base();}
|
||||
public static Gfo_fld_wtr xowa_() {return new Gfo_fld_wtr().Ctor_xdat();}
|
||||
}
|
||||
71
400_xowa/src_020_byte/gplx/Io_buffer_rdr.java
Normal file
71
400_xowa/src_020_byte/gplx/Io_buffer_rdr.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import gplx.ios.*;/*IoStream*/
|
||||
public class Io_buffer_rdr implements RlsAble { //_20120115
|
||||
Io_buffer_rdr(Io_stream_rdr rdr, Io_url url, int bfr_len) {
|
||||
if (bfr_len <= 0) throw Err_.new_("bfr_len must be > 0").Add("bfr_len", bfr_len);
|
||||
bfr = new byte[bfr_len]; this.bfr_len = bfr_len;
|
||||
this.rdr = rdr;
|
||||
IoItmFil fil = Io_mgr._.QueryFil(url); if (!fil.Exists()) throw Err_.new_("fil does not exist").Add("url", url);
|
||||
fil_len = fil.Size();
|
||||
fil_pos = 0;
|
||||
fil_eof = false;
|
||||
} Io_stream_rdr rdr;
|
||||
public byte[] Bfr() {return bfr;} private byte[] bfr;
|
||||
public int Bfr_len() {return bfr_len;} private int bfr_len;
|
||||
public long Fil_len() {return fil_len;} long fil_len;
|
||||
public long Fil_pos() {return fil_pos;} long fil_pos;
|
||||
public boolean Fil_eof() {return fil_eof;} private boolean fil_eof;
|
||||
public boolean Bfr_load_all() {return Bfr_load(0, bfr_len);}
|
||||
public boolean Bfr_load_from(int bfr_pos) {
|
||||
if (bfr_pos < 0 || bfr_pos > bfr_len) throw Err_.new_("invalid bfr_pos").Add("bfr_pos", bfr_pos).Add("bfr_len", bfr_len);
|
||||
for (int i = bfr_pos; i < bfr_len; i++) // shift end of bfr to bgn; EX: bfr[10] and load_from(8); [8] -> [0]; [9] -> [1];
|
||||
bfr[i - bfr_pos] = bfr[i];
|
||||
return Bfr_load(bfr_len - bfr_pos, bfr_pos); // fill rest of bfr; EX: [2]... will come from file
|
||||
}
|
||||
boolean Bfr_load(int bgn, int len) {
|
||||
int read = rdr.Read(bfr, bgn, len);
|
||||
if (read == gplx.ios.Io_stream_rdr_.Read_done) {fil_eof = true; return false;}
|
||||
fil_pos += read;
|
||||
bfr_len = bgn + read;
|
||||
if (read < len) fil_eof = true;
|
||||
return true;
|
||||
}
|
||||
public void Seek(long fil_pos) {
|
||||
this.fil_pos = fil_pos;
|
||||
rdr.Skip(fil_pos);
|
||||
this.Bfr_load_all();
|
||||
}
|
||||
public void Rls() {
|
||||
bfr = null;
|
||||
bfr_len = -1;
|
||||
if (rdr != null) rdr.Rls();
|
||||
}
|
||||
@gplx.Internal protected void DumpToFil(int bgn, int len, String urlStr, String msg) {
|
||||
String text = String_.new_utf8_len_safe_(bfr, bgn, len);
|
||||
Io_mgr._.AppendFilStr(Io_url_.new_any_(urlStr), msg + text + "\n");
|
||||
}
|
||||
public static Io_buffer_rdr new_(Io_stream_rdr rdr, int bfr_len) {
|
||||
Io_buffer_rdr rv = new Io_buffer_rdr(rdr, rdr.Url(), bfr_len);
|
||||
rdr.Open();
|
||||
rv.Bfr_load(0, bfr_len);
|
||||
return rv;
|
||||
} Io_buffer_rdr() {}
|
||||
public static final Io_buffer_rdr Null = new Io_buffer_rdr();
|
||||
}
|
||||
64
400_xowa/src_020_byte/gplx/Io_buffer_rdr_tst.java
Normal file
64
400_xowa/src_020_byte/gplx/Io_buffer_rdr_tst.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*; import gplx.ios.*;
|
||||
public class Io_buffer_rdr_tst {
|
||||
@Before public void init() {
|
||||
Io_mgr._.InitEngine_mem();
|
||||
fil = Io_url_.mem_fil_("mem/byteStreamRdr.txt");
|
||||
ini_Write("0123456789");
|
||||
rdr = Io_buffer_rdr.new_(Io_stream_rdr_.file_(fil), 4);
|
||||
} Io_buffer_rdr rdr; Io_url fil;
|
||||
@After public void teardown() {rdr.Rls();}
|
||||
@Test public void Bfr_load_all() {
|
||||
tst_Bfr("0", "1", "2", "3").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_all();
|
||||
tst_Bfr("4", "5", "6", "7").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_all();
|
||||
tst_Bfr("8", "9");
|
||||
rdr.Bfr_load_all(); // NOTE: change to zip_rdrs make eof detection difficult; force another load to ensure that file_pos goes past file_len
|
||||
tst_ReadDone(true); // NOTE: bfr truncated from 4 to 2
|
||||
}
|
||||
@Test public void Bfr_load_from() {
|
||||
tst_Bfr("0", "1", "2", "3").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(3); // read from pos 3
|
||||
tst_Bfr("3", "4", "5", "6").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(1); // read from pos 1
|
||||
tst_Bfr("4", "5", "6", "7").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(1);
|
||||
tst_Bfr("5", "6", "7", "8").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(3);
|
||||
rdr.Bfr_load_all(); // NOTE: change to zip_rdrs make eof detection difficult; force another load to ensure that file_pos goes past file_len
|
||||
tst_Bfr("8", "9").tst_ReadDone(true);
|
||||
}
|
||||
private void ini_Write(String s) {Io_mgr._.SaveFilStr(fil, s);}
|
||||
Io_buffer_rdr_tst tst_Bfr(String... expdAry) {
|
||||
String[] actlAry = new String[rdr.Bfr_len()];
|
||||
for (int i = 0; i < actlAry.length; i++)
|
||||
actlAry[i] = String_.new_utf8_(rdr.Bfr(), i, i + 1);
|
||||
Tfds.Eq_ary(expdAry, actlAry);
|
||||
return this;
|
||||
}
|
||||
Io_buffer_rdr_tst tst_ReadDone(boolean expd) {Tfds.Eq(expd, rdr.Fil_eof()); return this;}
|
||||
}
|
||||
Reference in New Issue
Block a user