v3.3.4 v2.7.2.1
gnosygnu 9 years ago
commit 794b5a232f

@ -0,0 +1,4 @@
[Dolphin]
Timestamp=2015,7,12,21,9,46
Version=3
ViewMode=1

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src_000_err"/>
<classpathentry kind="src" path="src_100_interface"/>
<classpathentry kind="src" path="src_110_primitive"/>
<classpathentry kind="src" path="src_120_basicDataType"/>
<classpathentry kind="src" path="src_140_list"/>
<classpathentry kind="src" path="src_150_text"/>
<classpathentry kind="src" path="src_160_hash"/>
<classpathentry kind="src" path="src_200_io"/>
<classpathentry kind="src" path="src_210_env"/>
<classpathentry kind="src" path="src_220_console"/>
<classpathentry kind="src" path="src_300_classXtn"/>
<classpathentry kind="src" path="src_310_gfoNde"/>
<classpathentry kind="src" path="src_311_gfoObj"/>
<classpathentry kind="src" path="src_330_store"/>
<classpathentry kind="src" path="src_340_dsv"/>
<classpathentry kind="src" path="src_400_gfs"/>
<classpathentry kind="src" path="src_410_gfoCfg"/>
<classpathentry kind="src" path="src_420_usrMsg"/>
<classpathentry kind="src" path="src_800_tst"/>
<classpathentry kind="src" path="src_900_xml"/>
<classpathentry kind="src" path="tst"/>
<classpathentry kind="src" path="xtn"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="lib" path="lib/commons-compress-1.5.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>100_core</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

@ -0,0 +1,70 @@
/*
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 Exc extends RuntimeException {
private final String stack;
private Exc_msg[] msgs_ary = new Exc_msg[8]; private int msgs_len = 8, msgs_idx = 0;
public Exc(String stack, String type, String msg, Object... args) {
Msgs_add(type, msg, args);
this.stack = stack;
}
public int Stack_erase() {return stack_erase;} public Exc Stack_erase_1_() {stack_erase = 1; return this;} private int stack_erase = 0;
public Exc Args_add(Object... args) {msgs_ary[msgs_idx - 1].Args_add(args); return this;} // i - 1 to get current
@gplx.Internal protected boolean Type_match(String type) {
for (int i = 0; i < msgs_len; ++i) {
if (String_.Eq(type, msgs_ary[i].Type())) return true;
}
return false;
}
@gplx.Internal protected void Msgs_add(String type, String msg, Object[] args) {
if (msgs_idx == msgs_len) {
int new_len = msgs_len * 2;
Exc_msg[] new_ary = new Exc_msg[new_len];
Array_.CopyTo(msgs_ary, new_ary, 0);
this.msgs_ary = new_ary;
this.msgs_len = new_len;
}
msgs_ary[msgs_idx] = new Exc_msg(type, msg, args);
++msgs_idx;
}
public String To_str_all() {
String rv = "";
for (int i = msgs_idx - 1; i > -1; --i) {
rv += "[err " + Int_.Xto_str(i) + "] " + msgs_ary[i].To_str() + "\n";
}
rv += "[stack]\n " + Stack_to_str(this, stack);
return rv;
}
@Override public String getMessage() {return To_str_all();}
private static String Stack_to_str(Exception e, String stack) {
String rv = stack;
if (rv == Exc_.Stack_null) { // occurs for thrown gplx exceptions; EX: throw Exc_.new_unimplemented
rv = ""; // set to "" b/c String concat below;
String[] lines = String_.Split_lang(Exc_.Stack_lang(e), '\n');
int len = lines.length;
for (int i = 0; i < len; ++i) {
String line = lines[i];
if (String_.Has_at_bgn(line, "gplx.Exc_.new")) continue; // ignore stack frames with "gplx.Exc_.new"; EX: throw Exc_.new_unimplemented
if (String_.Len(rv) > 0) rv += "\n";
rv += line;
}
}
rv = String_.Replace(rv, "\n", "\n "); // " " is to indent stack stack
return rv;
}
}

@ -0,0 +1,67 @@
/*
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 Exc_ {
private static String Type__none = ""; @gplx.Internal protected static String Stack_null = null;
public static final String Type__op_canceled = "gplx.op_canceled";
public static void Noop(Exception e) {}
public static Exc as_(Object obj) {return obj instanceof Exc ? (Exc)obj : null;}
public static Exc new_(String msg, Object... args) {return new Exc(Stack_null, Type__none, msg, args);}
public static Exc new_w_type(String type, String msg, Object... args) {return new Exc(Stack_null, type, msg, args);}
public static Exc new_exc(Exception e, String type, String msg, Object... args) {
Exc rv = ClassAdp_.Eq_typeSafe(e, Exc.class) ? (Exc)e : new Exc(Exc_.Stack_lang(e), Type__none, Exc_.Message_lang(e));
rv.Msgs_add(type, msg, args);
return rv;
}
public static Exc new_unhandled(Object val) {return new Exc(Stack_null, Type__none, "val is not in switch/if", "val", val);}
public static Exc new_unimplemented() {return new Exc(Stack_null, Type__none, "method not implemented");}
public static Exc new_unimplemented_w_msg(String msg, Object... args) {return new Exc(Stack_null, Type__none, msg, args);}
public static Exc new_deprecated(String s) {return new Exc(Stack_null, Type__none, "deprecated", "method", s);}
public static Exc new_parse_type(Class<?> c, String raw) {return new_parse(ClassAdp_.FullNameOf_type(c), raw);}
public static Exc new_parse_exc(Exception e, Class<?> c, String raw) {return new_parse(ClassAdp_.FullNameOf_type(c), raw).Args_add("e", Err_.Message_lang(e));}
public static Exc new_parse(String type, String raw) {return new Exc(Stack_null, Type__none, "parse failed", "type", type, "raw", raw);}
public static Exc new_null(String s) {return new Exc(Stack_null, Type__none, "null obj", "obj", s);}
public static Exc new_missing_idx(int idx, int len) {return new Exc(Stack_null, Type__none, "index is out of bounds", "idx", idx, "len", len);}
public static Exc new_missing_key(String key) {return new Exc(Stack_null, Type__none, "key not found", "key", key);}
public static Exc new_invalid_op(String msg) {return new Exc(Stack_null, Type__none, msg);}
public static Exc new_op_canceled() {return new Exc(Stack_null, Type__op_canceled, "canceled by usr");}
public static Exc new_type_mismatch_w_exc(Exception ignore, Class<?> t, Object o) {return new_type_mismatch(t, o);}
public static Exc new_type_mismatch(Class<?> t, Object o) {return new Exc(Stack_null, Type__none, "type mismatch", "expdType", ClassAdp_.FullNameOf_type(t), "actlType", ClassAdp_.NameOf_obj(o), "actlObj", Object_.Xto_str_strict_or_null_mark(o));}
public static Exc 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>"; Exc_.Noop(e);}
return new Exc(Stack_null, Type__none, "cast failed", "type", ClassAdp_.NameOf_type(t), "obj", o_str);
}
public static String Message_lang(Exception e) {return e.getMessage();}
public static String Stack_lang(Exception e) {
String rv = "";
StackTraceElement[] ary = e.getStackTrace();
int len = ary.length;
for (int i = 0; i < len; i++) {
if (i != 0) rv += "\n";
rv += ary[i].toString();
}
return rv;
}
public static boolean Type_match(Exception e, String type) {
Exc exc = Exc_.as_(e);
return exc == null ? false : exc.Type_match(type);
}
}

@ -0,0 +1,44 @@
/*
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;
class Exc_msg {
private final String msg; private Object[] args;
public Exc_msg(String type, String msg, Object[] args) {
this.type = type;
this.msg = msg;
this.args = args;
}
public String Type() {return type;} private final String type;
public void Args_add(Object[] add) {
this.args = (Object[])Array_.Resize_add(args, add);
}
public String To_str() {
String rv = String_.Len_eq_0(type) ? "" : "[" + type + "] ";
rv += msg;
int len = args.length;
if (len > 0) {
rv += ":";
for (int i = 0; i < len; i += 2) {
Object key = args[i];
Object val = i < len ? args[i + 1] : "MISSING_VAL";
rv += " " + Object_.Xto_str_strict_or_null_mark(key) + "=" + Object_.Xto_str_strict_or_null_mark(val);
}
}
return rv;
}
}

@ -0,0 +1,155 @@
/*
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.core.brys; import gplx.*; import gplx.core.*;
public class Bry_rdr {
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(src, 0);}
public void Init(byte[] src, int pos) {
this.src = src; this.src_len = src.length; this.pos = pos;
}
public int Pos() {return pos;} public Bry_rdr 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 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_.MinValue;
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_finder.Find_fwd(src, find, pos);}
public int Find_fwd_ws() {return Bry_finder.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, Bool_.N);}
public int Find_fwd__pos_at_rhs(byte[] find_bry) {return Find_fwd__pos_at(find_bry, Bool_.Y);}
public int Find_fwd__pos_at(byte[] find_bry, boolean pos_at_rhs) {
int find_pos = Bry_finder.Find_fwd(src, find_bry, pos, src_len);
if (pos_at_rhs) find_pos += find_bry.length;
if (find_pos != Bry_finder.Not_found) pos = find_pos;
return find_pos;
}
public int Read_int_to_semic() {return Read_int_to(Byte_ascii.Semic);}
public int Read_int_to_comma() {return Read_int_to(Byte_ascii.Comma);}
public int Read_int_to_pipe() {return Read_int_to(Byte_ascii.Pipe);}
public int Read_int_to_nl() {return Read_int_to(Byte_ascii.Nl);}
public int Read_int_to_quote() {return Read_int_to(Byte_ascii.Quote);}
public int Read_int_to_non_num(){return Read_int_to(Byte_ascii.Nil);}
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 Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
rv = (rv * 10) + (b - Byte_ascii.Num_0);
break;
case Byte_ascii.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 == Byte_ascii.Nil) {// 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(Byte_ascii.Nl);}
public byte[] Read_bry_to_semic() {return Read_bry_to(Byte_ascii.Semic);}
public byte[] Read_bry_to_pipe() {return Read_bry_to(Byte_ascii.Pipe);}
public byte[] Read_bry_to_quote() {return Read_bry_to(Byte_ascii.Quote);}
public byte[] Read_bry_to_apos() {return Read_bry_to(Byte_ascii.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() == Byte_ascii.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(Byte_ascii.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
}
@gplx.Virtual public Bry_rdr Skip_ws() {
while (pos < src_len) {
switch (src[pos]) {
case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Space:
++pos;
break;
default:
return this;
}
}
return this;
}
public Bry_rdr Skip_alpha_num_under() {
while (pos < src_len) {
switch (src[pos]) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
case Byte_ascii.Ltr_A: case Byte_ascii.Ltr_B: case Byte_ascii.Ltr_C: case Byte_ascii.Ltr_D: case Byte_ascii.Ltr_E:
case Byte_ascii.Ltr_F: case Byte_ascii.Ltr_G: case Byte_ascii.Ltr_H: case Byte_ascii.Ltr_I: case Byte_ascii.Ltr_J:
case Byte_ascii.Ltr_K: case Byte_ascii.Ltr_L: case Byte_ascii.Ltr_M: case Byte_ascii.Ltr_N: case Byte_ascii.Ltr_O:
case Byte_ascii.Ltr_P: case Byte_ascii.Ltr_Q: case Byte_ascii.Ltr_R: case Byte_ascii.Ltr_S: case Byte_ascii.Ltr_T:
case Byte_ascii.Ltr_U: case Byte_ascii.Ltr_V: case Byte_ascii.Ltr_W: case Byte_ascii.Ltr_X: case Byte_ascii.Ltr_Y: case Byte_ascii.Ltr_Z:
case Byte_ascii.Ltr_a: case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_e:
case Byte_ascii.Ltr_f: case Byte_ascii.Ltr_g: case Byte_ascii.Ltr_h: case Byte_ascii.Ltr_i: case Byte_ascii.Ltr_j:
case Byte_ascii.Ltr_k: case Byte_ascii.Ltr_l: case Byte_ascii.Ltr_m: case Byte_ascii.Ltr_n: case Byte_ascii.Ltr_o:
case Byte_ascii.Ltr_p: case Byte_ascii.Ltr_q: case Byte_ascii.Ltr_r: case Byte_ascii.Ltr_s: case Byte_ascii.Ltr_t:
case Byte_ascii.Ltr_u: case Byte_ascii.Ltr_v: case Byte_ascii.Ltr_w: case Byte_ascii.Ltr_x: case Byte_ascii.Ltr_y: case Byte_ascii.Ltr_z:
case Byte_ascii.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 Exc_.new_("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 Exc_.new_("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);
}
}

@ -0,0 +1,88 @@
/*
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.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_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 Exc_.new_("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 Btrie_bwd_mgr(boolean caseAny) {
root = new Btrie_slim_itm(Byte_.Zero, null, caseAny);
} private Btrie_slim_itm root;
}

@ -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.core.btries; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Btrie_bwd_mgr_tst {
@Before public void init() {} private Btrie_bwd_mgr trie;
private void ini_setup1() {
trie = new Btrie_bwd_mgr(false);
run_Add("c" , 1);
run_Add("abc" , 123);
}
@Test public void Get_by() {
ini_setup1();
tst_MatchAtCur("c" , 1);
tst_MatchAtCur("abc" , 123);
tst_MatchAtCur("bc" , 1);
tst_MatchAtCur("yzabc" , 123);
tst_MatchAtCur("ab" , null);
}
@Test public void Fetch_intl() {
trie = new Btrie_bwd_mgr(false);
run_Add("a<>", 1);
tst_MatchAtCur("a<>" , 1);
tst_MatchAtCur("<22>" , null);
}
@Test public void Eos() {
ini_setup1();
tst_Match("ab", Byte_ascii.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);
}
}

@ -0,0 +1,156 @@
/*
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.core.btries; import gplx.*; import gplx.core.*;
import gplx.core.primitives.*;
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_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_bval(byte key, byte val) {return Add(new byte[] {key}, Byte_obj_val.new_(val));}
public Btrie_fast_mgr Add_bry_bval(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 Exc_.new_("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.Xto_bry_and_clear() : src;
}
public static Btrie_fast_mgr cs_() {return new Btrie_fast_mgr(false);}
public static Btrie_fast_mgr ci_ascii_() {return new Btrie_fast_mgr(true);}
public static Btrie_fast_mgr new_(boolean case_any) {return new Btrie_fast_mgr(case_any);}
Btrie_fast_mgr(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;}
}

@ -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.core.btries; import gplx.*; import gplx.core.*;
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", Byte_ascii.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 , 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_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));
}
}

@ -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.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;
}

@ -0,0 +1,24 @@
/*
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.core.btries; import gplx.*; import gplx.core.*;
public interface Btrie_mgr {
int Match_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);
}

@ -0,0 +1,130 @@
/*
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.core.btries; import gplx.*; import gplx.core.*;
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[])Array_.Resize(ary, ary_max);
}
Btrie_slim_itm rv = new Btrie_slim_itm(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 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 _ = new ByteHashItm_sorter(); ByteHashItm_sorter() {}
}

@ -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.core.btries; import gplx.*; import gplx.core.*;
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(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) {
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_.XtoStr((char)b));}
private void run_Del(byte... ary) {for (byte b : ary) itm.Ary_del(b);}
}

@ -0,0 +1,128 @@
/*
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.core.btries; import gplx.*; import gplx.core.*;
import gplx.core.primitives.*;
public class Btrie_slim_mgr implements Btrie_mgr {
Btrie_slim_mgr(boolean case_match) {root = new Btrie_slim_itm(Byte_.Zero, null, !case_match);} private Btrie_slim_itm root;
public int Count() {return count;} private int count;
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_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) {
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 == src_len) return rv; // increment cur_pos and exit if src_len
b = src[cur_pos];
cur = nxt;
}
}
public Btrie_slim_mgr Add_bry_tid(byte[] bry, byte tid) {return (Btrie_slim_mgr)Add_obj(bry, Byte_obj_val.new_(tid));}
public Btrie_slim_mgr Add_str_byte(String key, byte val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), Byte_obj_val.new_(val));}
public Btrie_slim_mgr Add_str_int(String key, int val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), Int_obj_val.new_(val));}
public Btrie_slim_mgr Add_bry(String key, String val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), Bry_.new_u8(val));}
public Btrie_slim_mgr Add_bry(String key, byte[] val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), val);}
public Btrie_slim_mgr Add_bry(byte[] v) {return (Btrie_slim_mgr)Add_obj(v, v);}
public Btrie_slim_mgr Add_bry_bval(byte b, byte val) {return (Btrie_slim_mgr)Add_obj(new byte[] {b}, Byte_obj_val.new_(val));}
public Btrie_slim_mgr Add_bry_bval(byte[] bry, byte val) {return (Btrie_slim_mgr)Add_obj(bry, Byte_obj_val.new_(val));}
public Btrie_slim_mgr 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_obj(Bry_.new_u8(ary[i]), bval);
return this;
}
public Btrie_slim_mgr Add_stub(String key, byte val) {byte[] bry = Bry_.new_u8(key); return (Btrie_slim_mgr)Add_obj(bry, new Btrie_itm_stub(val, bry));}
public Btrie_slim_mgr Add_stubs(byte[][] ary) {return Add_stubs(ary, ary.length);}
public Btrie_slim_mgr Add_stubs(byte[][] ary, int ary_len) {
for (byte i = 0; i < ary_len; i++) {
byte[] bry = ary[i];
Add_obj(bry, new Btrie_itm_stub(i, bry));
}
return this;
}
public Btrie_mgr Add_obj(String key, Object val) {return Add_obj(Bry_.new_u8(key), val);}
public Btrie_mgr Add_obj(byte[] key, Object val) {
if (val == null) throw Exc_.new_("null objects cannot be registered", "key", String_.new_u8(key));
int key_len = key.length; int key_end = key_len - 1;
Btrie_slim_itm cur = root;
for (int i = 0; i < key_len; 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 == 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;
Btrie_slim_itm cur = root;
for (int i = 0; i < key_len; i++) {
byte b = key[i];
Btrie_slim_itm 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_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.Xto_bry_and_clear() : src;
}
public void Clear() {root.Clear(); count = 0;}
public static Btrie_slim_mgr cs_() {return new Btrie_slim_mgr(true);}
public static Btrie_slim_mgr ci_ascii_() {return new Btrie_slim_mgr(false);}
public static Btrie_slim_mgr ci_utf_8_() {return new Btrie_slim_mgr(false);}
public static Btrie_slim_mgr new_(boolean v) {return new Btrie_slim_mgr(v);}
}

@ -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.core.btries; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Btrie_slim_mgr_tst {
@Before public void init() {
} private Btrie_slim_mgr trie;
private void ini_setup1() {
trie = Btrie_slim_mgr.cs_();
run_Add("a" , 1);
run_Add("abc" , 123);
}
@Test public void Get_by() {
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 Match_exact() {
ini_setup1();
tst_MatchAtCurExact("a", 1);
tst_MatchAtCurExact("ab", null);
tst_MatchAtCurExact("abc", 123);
}
private void ini_setup2() {
trie = Btrie_slim_mgr.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 = Btrie_slim_mgr.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_a7("a")); // delete "a"; "abc" still remains;
tst_MatchAtCur("a" , null);
tst_MatchAtCur("abc" , 123);
trie.Del(Bry_.new_a7("abc"));
tst_MatchAtCur("abc" , null);
}
private void run_Add(String k, int val) {trie.Add_obj(Bry_.new_a7(k), val);}
private void tst_Match(String srcStr, byte b, int bgn_pos, int expd) {
byte[] src = Bry_.new_a7(srcStr);
Object actl = trie.Match_bgn_w_byte(b, src, bgn_pos, src.length);
Tfds.Eq(expd, actl);
}
private void tst_MatchAtCur(String srcStr, Object expd) {
byte[] src = Bry_.new_a7(srcStr);
Object actl = trie.Match_bgn_w_byte(src[0], src, 0, src.length);
Tfds.Eq(expd, actl);
}
private void tst_MatchAtCurExact(String srcStr, Object expd) {
byte[] src = Bry_.new_a7(srcStr);
Object actl = trie.Match_exact(src, 0, src.length);
Tfds.Eq(expd, actl);
}
}

@ -0,0 +1,68 @@
/*
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.core.btries; import gplx.*; import gplx.core.*;
import gplx.intl.*;
class Btrie_utf8_itm {
private Hash_adp_bry nxts;
private byte[] asymmetric_bry;
public Btrie_utf8_itm(byte[] key, Object val) {this.key = key; this.val = val;}
public byte[] Key() {return key;} private byte[] key;
public Object Val() {return val;} public void Val_set(Object val) {this.val = val;} private Object val;
public boolean Nxts_is_empty() {return nxts == null;}
public void Clear() {
val = null;
nxts.Clear();
nxts = null;
}
public Btrie_utf8_itm Nxts_find(byte[] src, int c_bgn, int c_end, boolean called_by_match) {
if (nxts == null) return null;
Object rv_obj = nxts.Get_by_mid(src, c_bgn, c_end);
if (rv_obj == null) return null;
Btrie_utf8_itm rv = (Btrie_utf8_itm)rv_obj;
byte[] asymmetric_bry = rv.asymmetric_bry;
if (asymmetric_bry == null) // itm doesn't have asymmetric_bry; note that this is the case for most items
return rv;
else { // itm has asymmetric_bry; EX: "İ" was added to trie, must match "İ" and "i";
if (called_by_match) { // called by mgr.Match
return
( Bry_.Eq(rv.key, src, c_bgn, c_end) // key matches src; EX: "aİ"
|| Bry_.Eq(rv.asymmetric_bry, src, c_bgn, c_end) // asymmetric_bry matches src; EX: "ai"; note that "aI" won't match
)
? rv : null;
}
else { // called by mgr.Add; this means that an asymmetric_itm was already added; happens when "İ" added first and then "I" added next
rv.asymmetric_bry = null; // always null out asymmetric_bry; note that this noops non-asymmetric itms, while making an asymmetric_itm case-insenstivie (matches İ,i,I); see tests
return rv;
}
}
}
public Btrie_utf8_itm Nxts_add(Gfo_case_mgr case_mgr, byte[] key, Object val) {
Btrie_utf8_itm rv = new Btrie_utf8_itm(key, val);
if (nxts == null) nxts = Hash_adp_bry.ci_utf8_(case_mgr);
nxts.Add_bry_obj(key, rv);
Gfo_case_itm case_itm = case_mgr.Get_or_null(key[0], key, 0, key.length); // get case_item
if (case_itm != null) { // note that case_itm may be null; EX: "__TOC__" and "_"
byte[] asymmetric_bry = case_itm.Asymmetric_bry();
if (asymmetric_bry != null) { // case_itm has asymmetry_bry; only itms in Xol_case_itm_ that are created with Tid_upper and Tid_lower will be non-null
rv.asymmetric_bry = asymmetric_bry; // set itm to asymmetric_bry; EX: for İ, asymmetric_bry = i
nxts.Add_bry_obj(asymmetric_bry, rv); // add the asymmetric_bry to the hash; in above example, this allows "i" to match "İ"
}
}
return rv;
}
}

@ -0,0 +1,68 @@
/*
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.core.btries; import gplx.*; import gplx.core.*;
import gplx.intl.*;
public class Btrie_utf8_mgr implements Btrie_mgr {
private Btrie_utf8_itm root; private Gfo_case_mgr case_mgr;
Btrie_utf8_mgr(Gfo_case_mgr case_mgr) {
this.case_mgr = case_mgr;
this.root = new Btrie_utf8_itm(Bry_.Empty, null);
}
public int Count() {return count;} private int count;
public int Match_pos() {return match_pos;} private int match_pos;
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 end_pos) {
Object rv = null; int cur_pos = match_pos = bgn_pos;
Btrie_utf8_itm cur = root;
while (true) {
int c_len = Utf8_.Len_of_char_by_1st_byte(b);
int c_end = cur_pos + c_len;
Btrie_utf8_itm nxt = cur.Nxts_find(src, cur_pos, c_end, true); if (nxt == null) return rv; // nxts does not have key; return rv;
cur_pos = c_end;
if (nxt.Nxts_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 end
b = src[cur_pos];
cur = nxt;
}
}
public void Clear() {root.Clear(); count = 0;}
public Btrie_mgr Add_obj(String key, Object val) {return Add_obj(Bry_.new_u8(key), val);}
public Btrie_mgr Add_obj(byte[] key, Object val) {
if (val == null) throw Exc_.new_("null objects cannot be registered", "key", String_.new_u8(key));
int key_len = key.length;
Btrie_utf8_itm cur = root;
int c_bgn = 0;
while (c_bgn < key_len) {
byte c = key[c_bgn];
int c_len = Utf8_.Len_of_char_by_1st_byte(c);
int c_end = c_bgn + c_len;
Btrie_utf8_itm nxt = cur.Nxts_find(key, c_bgn, c_end, false);
if (nxt == null)
nxt = cur.Nxts_add(case_mgr, Bry_.Mid(key, c_bgn, c_end), null);
c_bgn = c_end;
if (c_bgn == key_len)
nxt.Val_set(val);
cur = nxt;
}
++count;
return this;
}
public static Btrie_utf8_mgr new_(Gfo_case_mgr case_mgr) {return new Btrie_utf8_mgr(case_mgr);}
}

@ -0,0 +1,24 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public interface Criteria extends XtoStrAble {
byte Tid();
boolean Matches(Object obj);
void Val_from_args(Hash_adp args);
void Val_as_obj_(Object obj);
}

@ -0,0 +1,53 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
import gplx.texts.*; /*RegxPatn_cls_like*/
public class Criteria_ {
public static final Criteria All = new Criteria_const(true);
public static final Criteria None = new Criteria_const(false);
public static Criteria Not(Criteria arg) {return new Criteria_not(arg);}
public static Criteria And(Criteria lhs, Criteria rhs) {return new Criteria_and(lhs, rhs);}
public static Criteria And_many(Criteria... ary) {
int len = Array_.Len(ary); if (len == 0) throw Exc_.new_("cannot AND 0 criterias;");
Criteria rv = ary[0];
for (int i = 1; i < len; i++)
rv = And(rv, ary[i]);
return rv;
}
public static Criteria Or(Criteria lhs, Criteria rhs) {return new Criteria_or(lhs, rhs);}
public static Criteria Or_many(Criteria... ary) {
int len = Array_.Len(ary); if (len == 0) throw Exc_.new_("cannot OR 0 criterias;");
Criteria rv = ary[0];
for (int i = 1; i < len; i++)
rv = Or(rv, ary[i]);
return rv;
}
public static Criteria eq_(Object arg) {return new Criteria_eq(false, arg);}
public static Criteria eqn_(Object arg) {return new Criteria_eq(true, arg);}
public static Criteria in_(Object... array) {return new Criteria_in(false, array);}
public static Criteria inn_(Object... array) {return new Criteria_in(true, array);}
public static Criteria lt_(Comparable val) {return new Criteria_comp(CompareAble_.Less, val);}
public static Criteria lte_(Comparable val) {return new Criteria_comp(CompareAble_.LessOrSame, val);}
public static Criteria mt_(Comparable val) {return new Criteria_comp(CompareAble_.More, val);}
public static Criteria mte_(Comparable val) {return new Criteria_comp(CompareAble_.MoreOrSame, val);}
public static Criteria between_(Comparable lhs, Comparable rhs) {return new Criteria_between(false, lhs, rhs);}
public static Criteria between_(boolean negated, Comparable lhs, Comparable rhs) {return new Criteria_between(negated, lhs, rhs);}
public static Criteria like_(String pattern) {return new Criteria_like(false, RegxPatn_cls_like_.parse_(pattern, RegxPatn_cls_like.EscapeDefault));}
public static Criteria liken_(String pattern) {return new Criteria_like(true, RegxPatn_cls_like_.parse_(pattern, RegxPatn_cls_like.EscapeDefault));}
public static final byte Tid_custom = 0, Tid_const = 1, Tid_not = 2, Tid_and = 3, Tid_or = 4, Tid_eq = 5, Tid_between = 6, Tid_in = 7, Tid_like = 8, Tid_comp = 9, Tid_wrapper = 10, Tid_iomatch = 11, Tid_db_obj_ary = 12;
}

@ -0,0 +1,40 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public class Criteria_between implements Criteria {
public Criteria_between(boolean negate, Comparable lhs, Comparable rhs) {this.negate = negate; this.lhs = lhs; this.rhs = rhs;}
public byte Tid() {return Criteria_.Tid_between;}
public boolean Negated() {return negate;} private final boolean negate;
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public void Val_as_obj_(Object v) {
Object[] ary = (Object[])v;
lhs = (Comparable)ary[0];
rhs = (Comparable)ary[1];
}
public Comparable Lhs() {return lhs;} private Comparable lhs;
public Comparable Rhs() {return rhs;} private Comparable rhs;
public String XtoStr() {return String_.Concat_any("BETWEEN ", lhs, " AND ", rhs);}
public boolean Matches(Object compObj) {
Comparable comp = CompareAble_.as_(compObj);
int lhsResult = CompareAble_.CompareComparables(lhs, comp);
int rhsResult = CompareAble_.CompareComparables(rhs, comp);
boolean rv = (lhsResult * rhsResult) != 1;
return negate ? !rv : rv;
}
public static Criteria_between as_(Object obj) {return obj instanceof Criteria_between ? (Criteria_between)obj : null;}
}

@ -0,0 +1,57 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public abstract class Criteria_bool_base implements Criteria {
@gplx.Internal protected void Ctor(String op_literal, Criteria lhs, Criteria rhs) {this.op_literal = op_literal; this.lhs = lhs; this.rhs = rhs;}
public abstract byte Tid();
public abstract boolean Matches(Object curVal);
public void Val_from_args(Hash_adp args) {lhs.Val_from_args(args); rhs.Val_from_args(args);}
public void Val_as_obj_(Object v) {throw Exc_.new_unimplemented();}
public String XtoStr() {return String_.Concat(lhs.XtoStr(), " ", this.op_literal, " ", rhs.XtoStr());}
public String Op_literal() {return op_literal;} private String op_literal;
public Criteria Lhs() {return lhs;} private Criteria lhs;
public Criteria Rhs() {return rhs;} private Criteria rhs;
public static Criteria_bool_base as_(Object obj) {return obj instanceof Criteria_bool_base ? (Criteria_bool_base)obj : null;}
}
class Criteria_and extends Criteria_bool_base {
public Criteria_and(Criteria lhs, Criteria rhs) {this.Ctor("AND", lhs, rhs);}
@Override public byte Tid() {return Criteria_.Tid_not;}
@Override public boolean Matches(Object curVal) {return this.Lhs().Matches(curVal) && this.Rhs().Matches(curVal);}
}
class Criteria_or extends Criteria_bool_base {
public Criteria_or(Criteria lhs, Criteria rhs) {this.Ctor("OR", lhs, rhs);}
@Override public byte Tid() {return Criteria_.Tid_or;}
@Override public boolean Matches(Object curVal) {return this.Lhs().Matches(curVal) || this.Rhs().Matches(curVal);}
}
class Criteria_const implements Criteria {
public Criteria_const(boolean val) {this.val = val;}
public byte Tid() {return Criteria_.Tid_const;}
public boolean Matches(Object comp) {return val;} private final boolean val;
public void Val_from_args(Hash_adp args) {;}
public void Val_as_obj_(Object v) {throw Exc_.new_unimplemented();}
public String XtoStr() {return String_.Concat(" IS ", Bool_.Xto_str_lower(val));}
}
class Criteria_not implements Criteria {
private final Criteria criteria;
public Criteria_not(Criteria v) {this.criteria = v;}
public byte Tid() {return Criteria_.Tid_not;}
public boolean Matches(Object obj) {return !criteria.Matches(obj);}
public void Val_from_args(Hash_adp args) {criteria.Val_from_args(args);}
public void Val_as_obj_(Object v) {criteria.Val_as_obj_(v);}
public String XtoStr() {return String_.Concat_any(" NOT ", criteria.XtoStr());}
}

@ -0,0 +1,37 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public class Criteria_comp implements Criteria {
private final int comp_mode;
@gplx.Internal protected Criteria_comp(int comp_mode, Comparable val) {this.comp_mode = comp_mode; this.val = val;}
public byte Tid() {return Criteria_.Tid_comp;}
public Comparable Val() {return val;} private Comparable val;
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public void Val_as_obj_(Object v) {val = (Comparable)v;}
public boolean Matches(Object compObj) {
Comparable comp = CompareAble_.as_(compObj);
return CompareAble_.Is(comp_mode, comp, val);
}
public String XtoStr() {return String_.Concat_any(XtoSymbol(), " ", val);}
public String XtoSymbol() {
String comp_sym = comp_mode < CompareAble_.Same ? "<" : ">";
String eq_sym = comp_mode % 2 == CompareAble_.Same ? "=" : "";
return comp_sym + eq_sym;
}
public static Criteria_comp as_(Object obj) {return obj instanceof Criteria_comp ? (Criteria_comp)obj : null;}
}

@ -0,0 +1,34 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public class Criteria_eq implements Criteria {
@gplx.Internal protected Criteria_eq(boolean negated, Object val) {this.negated = negated; this.val = val;}
public byte Tid() {return Criteria_.Tid_eq;}
public boolean Negated() {return negated;} private final boolean negated;
public Object Val() {return val;} private Object val;
public void Val_as_obj_(Object v) {this.val = v;}
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public boolean Matches(Object comp) {
Class<?> val_type = ClassAdp_.ClassOf_obj(val);
if (!ClassAdp_.Eq_typeSafe(comp, val_type)) throw Exc_.new_type_mismatch(val_type, comp);
boolean rv = Object_.Eq(val, comp);
return negated ? !rv : rv;
}
public String XtoStr() {return String_.Concat_any("= ", val);}
public static Criteria_eq as_(Object obj) {return obj instanceof Criteria_eq ? (Criteria_eq)obj : null;}
}

@ -0,0 +1,67 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public class Criteria_fld implements Criteria {
Criteria_fld(String key, Criteria crt) {this.key = key; this.crt = crt;}
public byte Tid() {return Criteria_.Tid_wrapper;}
public String Key() {return key;} private final String key;
public Criteria Crt() {return crt;} private final Criteria crt;
public void Val_as_obj_(Object v) {throw Exc_.new_unimplemented();}
public void Val_from_args(Hash_adp args) {
List_adp list = (List_adp)args.Get_by(key); if (list == null) throw Exc_.new_("criteria.fld key not found", "key", key);
Object o = Fill_val(key, crt.Tid(), list);
crt.Val_as_obj_(o);
}
public boolean Matches(Object invkObj) {
GfoInvkAble invk = (GfoInvkAble)invkObj;
if (key == Criteria_fld.Key_null) return crt.Matches(invkObj);
Object comp = GfoInvkAble_.InvkCmd(invk, key);
return crt.Matches(comp);
}
public String XtoStr() {return String_.Concat(key, " ", crt.XtoStr());}
public static final String Key_null = null;
public static Criteria_fld as_(Object obj) {return obj instanceof Criteria_fld ? (Criteria_fld)obj : null;}
public static Criteria_fld new_(String key, Criteria crt) {return new Criteria_fld(key, crt);}
public static Object Fill_val(String key, byte tid, List_adp list) {
int len = list.Count();
switch (tid) {
case Criteria_.Tid_eq:
case Criteria_.Tid_comp:
case Criteria_.Tid_like:
case Criteria_.Tid_iomatch:
if (len != 1) throw Exc_.new_("list.len should be 1", "key", key, "tid", tid, "len", len);
return list.Get_at(0);
case Criteria_.Tid_between:
if (len != 2) throw Exc_.new_("list.len should be 2", "key", key, "tid", tid, "len", len);
return new Object[] {list.Get_at(0), list.Get_at(1)};
case Criteria_.Tid_in:
if (len == 0) throw Exc_.new_("list.len should be > 0", "key", key, "tid", tid, "len", len);
return list.To_obj_ary();
case Criteria_.Tid_const:
case Criteria_.Tid_not:
case Criteria_.Tid_and:
case Criteria_.Tid_or:
if (len != 0) throw Exc_.new_("list.len should be 0", "key", key, "tid", tid, "len", len);
return key; // no values to fill in; return back key
case Criteria_.Tid_wrapper: // not recursive
case Criteria_.Tid_db_obj_ary: // unsupported
case Criteria_.Tid_custom:
default: throw Exc_.new_unhandled(tid);
}
}
}

@ -0,0 +1,46 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
public class Criteria_in implements Criteria {
public Criteria_in(boolean negated, Object[] ary) {this.negated = negated; Val_as_obj_ary_(ary);}
public byte Tid() {return Criteria_.Tid_in;}
public boolean Negated() {return negated;} private final boolean negated;
public Object[] Val_as_obj_ary() {return ary;} private Object[] ary; private Class<?> ary_type; private int ary_len;
private void Val_as_obj_ary_(Object[] v) {
this.ary = v;
ary_len = Array_.Len(ary);
ary_type = ary_len == 0 ? Object.class : ClassAdp_.ClassOf_obj(ary[0]);
}
public void Val_as_obj_(Object v) {Val_as_obj_ary_((Object[])v);}
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public boolean Matches(Object comp) {
if (ary_len == 0) return false; // empty array never matches
if (!ClassAdp_.Eq_typeSafe(comp, ary_type)) throw Exc_.new_type_mismatch(ary_type, comp);
boolean rv = false;
for (int i = 0; i < ary_len; i++) {
Object val = ary[i];
if (Object_.Eq(val, comp)) {
rv = true;
break;
}
}
return negated ? !rv : rv;
}
public String XtoStr() {return String_.Concat_any("IN ", String_.Concat_any(ary));}
public static Criteria_in as_(Object obj) {return obj instanceof Criteria_in ? (Criteria_in)obj : null;}
}

@ -0,0 +1,50 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
import org.junit.*;
import gplx.ios.*;
public class Criteria_ioItm_tst {
IoItmFil fil; Criteria crt; IoItm_fxt fx = IoItm_fxt.new_();
@Test public void IoType() {
crt = crt_(IoItm_base_.Prop_Type, Criteria_.eq_(IoItmFil.Type_Fil));
tst_Match(true, crt, fx.fil_wnt_("C:\\fil.txt"));
tst_Match(false, crt, fx.dir_wnt_("C:\\dir"));
}
@Test public void Ext() {
crt = crt_(IoItm_base_.Prop_Ext, Criteria_.eq_(".txt"));
tst_Match(true, crt, fx.fil_wnt_("C:\\fil.txt"));
tst_Match(false, crt, fx.fil_wnt_("C:\\fil.xml"), fx.fil_wnt_("C:\\fil.txt1"), fx.fil_wnt_("C:\\fil1.txt.xml"), fx.dir_wnt_("C:\\.txt"));
}
@Test public void Modified() {
fil = fx.fil_wnt_("C:\\fil.txt");
crt = crt_(IoItmFil_.Prop_Modified, Criteria_.mte_(DateAdp_.parse_gplx("2001-01-01")));
tst_Match(true, crt, fil.ModifiedTime_(DateAdp_.parse_gplx("2001-01-02")), fil.ModifiedTime_(DateAdp_.parse_gplx("2001-01-01")));
tst_Match(false, crt, fil.ModifiedTime_(DateAdp_.parse_gplx("2000-12-31")));
}
@Test public void IoMatch() {
Criteria crt = Criteria_ioMatch.parse_(true, "*.txt", false);
CriteriaFxt fx_crt = new CriteriaFxt();
fx_crt.tst_Matches(crt, Io_url_.new_any_("file.txt"));
fx_crt.tst_MatchesNot(crt, Io_url_.new_any_("file.xml"));
}
Criteria crt_(String fld, Criteria crt) {return Criteria_fld.new_(fld, crt);}
void tst_Match(boolean expt, Criteria fieldCrt, IoItm_base... ary) {
for (IoItm_base itm : ary)
Tfds.Eq(expt, fieldCrt.Matches(itm));
}
}

@ -0,0 +1,37 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
import gplx.texts.*;
public class Criteria_ioMatch implements Criteria { // EX: url IOMATCH '*.xml|*.txt'
public Criteria_ioMatch(boolean match, RegxPatn_cls_ioMatch pattern) {this.match = match; this.pattern = pattern;}
public byte Tid() {return Criteria_.Tid_iomatch;}
public boolean Negated() {return !match;} private final boolean match;
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public void Val_as_obj_(Object v) {this.pattern = (RegxPatn_cls_ioMatch)v;}
public RegxPatn_cls_ioMatch Pattern() {return pattern;} private RegxPatn_cls_ioMatch pattern;
public boolean Matches(Object compObj) {
Io_url comp = (Io_url)compObj;
boolean rv = pattern.Matches(comp.XtoCaseNormalized());
return match ? rv : !rv;
}
public String XtoStr() {return String_.Concat_any("IOMATCH ", pattern);}
public static final String TokenName = "IOMATCH";
public static Criteria_ioMatch as_(Object obj) {return obj instanceof Criteria_ioMatch ? (Criteria_ioMatch)obj : null;}
public static Criteria_ioMatch parse_(boolean match, String raw, boolean caseSensitive) {return new Criteria_ioMatch(match, RegxPatn_cls_ioMatch_.parse_(raw, caseSensitive));}
}

@ -0,0 +1,36 @@
/*
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.core.criterias; import gplx.*; import gplx.core.*;
import gplx.texts.*; /*RegxPatn_cls_like*/
public class Criteria_like implements Criteria {
@gplx.Internal protected Criteria_like(boolean negated, RegxPatn_cls_like pattern) {
this.negated = negated; this.pattern = pattern;
}
public byte Tid() {return Criteria_.Tid_like;}
public boolean Negated() {return negated;} private final boolean negated;
public RegxPatn_cls_like Pattern() {return pattern;} private RegxPatn_cls_like pattern;
public void Val_from_args(Hash_adp args) {throw Exc_.new_unimplemented();}
public void Val_as_obj_(Object v) {this.pattern = (RegxPatn_cls_like)v;}
public boolean Matches(Object compObj) {
String comp = String_.as_(compObj); if (comp == null) throw Exc_.new_type_mismatch(String.class, compObj);
boolean rv = pattern.Matches(comp);
return negated ? !rv : rv;
}
public String XtoStr() {return String_.Concat_any("LIKE ", pattern);}
public static Criteria_like as_(Object obj) {return obj instanceof Criteria_like ? (Criteria_like)obj : null;}
}

@ -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.core.criterias; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Criteria_tst {
@Test public void Equal() {
Criteria crt = Criteria_.eq_(true);
fx.tst_Matches(crt, true);
fx.tst_MatchesNot(crt, false);
fx.tst_MatchesFail(crt, "true");
fx.tst_Matches(Criteria_.eq_(1), 1);
fx.tst_Matches(Criteria_.eq_("equal"), "equal");
fx.tst_Matches(Criteria_.eq_(date), date);
}
@Test public void Not() {
Criteria crt = Criteria_.eqn_(true);
fx.tst_Matches(crt, false);
fx.tst_MatchesNot(crt, true);
fx.tst_MatchesFail(crt, "false");
fx.tst_Matches(Criteria_.eqn_(1), -1);
fx.tst_Matches(Criteria_.eqn_("equal"), "not equal");
fx.tst_Matches(Criteria_.eqn_(date), date.Add_minute(1));
}
@Test public void MoreThan() {
Criteria crt = Criteria_.mt_(0);
fx.tst_Matches(crt, 1, 2);
fx.tst_MatchesNot(crt, 0, -1);
fx.tst_MatchesFail(crt, "1");
fx.tst_Matches(Criteria_.mt_(0), 1);
fx.tst_Matches(Criteria_.mt_("a"), "b");
fx.tst_Matches(Criteria_.mt_(date), date.Add_minute(1));
fx.tst_Matches(Criteria_.mt_(false), true); // MISC: thus truth is greater than falsehood
}
@Test public void MoreThanEq() {
Criteria crt = Criteria_.mte_(0);
fx.tst_Matches(crt, 0);
}
@Test public void Less() {
Criteria crt = Criteria_.lt_(0);
fx.tst_Matches(crt, -1, -2);
fx.tst_MatchesNot(crt, 0, 1);
fx.tst_MatchesFail(crt, "-1");
}
@Test public void LessEq() {
Criteria crt = Criteria_.lte_(0);
fx.tst_Matches(crt, 0);
}
@Test public void Between() {
Criteria crt = Criteria_.between_(-1, 1);
fx.tst_Matches(crt, 0, 1, -1);
fx.tst_MatchesNot(crt, -2, 2);
fx.tst_MatchesFail(crt, "0");
fx.tst_Matches(Criteria_.between_(1, -1), 0); // reverse range
fx.tst_Matches(Criteria_.between_("a", "c"), "b");
}
@Test public void In() {
Criteria crt = Criteria_.in_(0, 1, 2);
fx.tst_Matches(crt, 0, 1, 2);
fx.tst_MatchesNot(crt, 3, -1);
fx.tst_MatchesFail(crt, "0");
}
CriteriaFxt fx = new CriteriaFxt();
DateAdp date = DateAdp_.parse_gplx("2001-01-01");
}
class CriteriaFxt {
public void tst_Matches(Criteria crt, Object... ary) {for (Object val : ary) Tfds.Eq(true, crt.Matches(val));}
public void tst_MatchesNot(Criteria crt, Object... ary) {for (Object val : ary) Tfds.Eq(false, crt.Matches(val));}
public void tst_MatchesFail(Criteria crt, Object val) {
try {crt.Matches(val);}
catch(Exception exc) {Exc_.Noop(exc); return;}
Tfds.Fail_expdError();
}
}

@ -0,0 +1,107 @@
/*
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.core.js; import gplx.*; import gplx.core.*;
public class Js_wtr {
private final Bry_bfr bfr = Bry_bfr.reset_(255);
private int arg_idx = 0, ary_idx = 0;
public byte Quote_char() {return quote_char;} public Js_wtr Quote_char_(byte v) {quote_char = v; return this;} private byte quote_char = Byte_ascii.Quote;
public void Clear() {bfr.Clear();}
public String To_str() {return bfr.Xto_str();}
public String To_str_and_clear() {return bfr.Xto_str_and_clear();}
public Js_wtr Func_init(String name) {return Func_init(Bry_.new_u8(name));}
public Js_wtr Func_init(byte[] name) {
bfr.Add(name).Add_byte(Byte_ascii.Paren_bgn);
arg_idx = 0;
return this;
}
public Js_wtr Func_term() {
bfr.Add_byte(Byte_ascii.Paren_end).Add_byte_semic();
return this;
}
public Js_wtr Prm_bry(byte[] bry) {
Prm_spr();
Write_val(bry);
return this;
}
public Js_wtr Prm_obj_ary(Object[] ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; ++i) {
Object itm = ary[i];
if (i != 0) bfr.Add_byte(Byte_ascii.Comma);
boolean val_needs_quotes = true;
if ( ClassAdp_.Eq_typeSafe(itm, Bool_.Cls_ref_type)
|| ClassAdp_.Eq_typeSafe(itm, Int_.Cls_ref_type)
|| ClassAdp_.Eq_typeSafe(itm, Long_.Cls_ref_type)
) {
val_needs_quotes = false;
}
if (val_needs_quotes)
Write_val(Bry_.new_u8(Object_.Xto_str_strict_or_null_mark(itm)));
else
bfr.Add_obj_strict(itm);
}
return this;
}
public Js_wtr Ary_init() {
ary_idx = 0;
bfr.Add_byte(Byte_ascii.Brack_bgn);
return this;
}
public Js_wtr Ary_term() {
bfr.Add_byte(Byte_ascii.Brack_end);
return this;
}
public void Prm_spr() {
if (arg_idx != 0) bfr.Add_byte(Byte_ascii.Comma);
++arg_idx;
}
private void Ary_spr() {
if (ary_idx != 0) bfr.Add_byte(Byte_ascii.Comma);
++ary_idx;
}
public Js_wtr Ary_bry(byte[] bry) {
Ary_spr();
Write_val(bry);
return this;
}
private Js_wtr Write_keyword_return() {bfr.Add(Keyword_return); return this;}
public Js_wtr Write_statement_return_func(String func, Object... args) {
this.Write_keyword_return();
this.Func_init(func);
this.Prm_obj_ary(args);
this.Func_term();
return this;
}
public void Write_val(byte[] bry) {
bfr.Add_byte(quote_char);
int len = bry.length;
for (int i = 0; i < len; i++) {
byte b = bry[i];
switch (b) {
case Byte_ascii.Backslash: // "\" -> "\\"; needed else js will usurp \ as escape; EX: "\&" -> "&"; DATE:2014-06-24
case Byte_ascii.Quote:
case Byte_ascii.Apos: bfr.Add_byte(Byte_ascii.Backslash).Add_byte(b); break;
case Byte_ascii.Nl: bfr.Add_byte(Byte_ascii.Backslash).Add_byte(Byte_ascii.Ltr_n); break; // "\n" -> "\\n"
case Byte_ascii.Cr: break;// skip
default: bfr.Add_byte(b); break;
}
}
bfr.Add_byte(quote_char);
}
private static final byte[] Keyword_return = Bry_.new_a7("return ");
}

@ -0,0 +1,41 @@
/*
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.core.js; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Js_wtr_tst {
@Before public void Init() {fxt.Clear();} private Js_wtr_fxt fxt = new Js_wtr_fxt();
@Test public void Basic() {
fxt.Test_write_val_html("abc" , "'abc'");
fxt.Test_write_val_html("a'b" , "'a\\'b'");
fxt.Test_write_val_html("a\"b" , "'a\\\"b'");
fxt.Test_write_val_html("a\nb" , "'a\\nb'");
fxt.Test_write_val_html("a\rb" , "'ab'");
fxt.Test_write_val_html("a\\&b" , "'a\\\\&b'"); // PURPOSE: backslashes need to be escaped; need for MathJax and "\&"; PAGE:Electromagnetic_field_tensor; DATE:2014-06-24
}
}
class Js_wtr_fxt {
private Js_wtr wtr = new Js_wtr();
public void Clear() {
wtr.Clear();
wtr.Quote_char_(Byte_ascii.Apos);
}
public void Test_write_val_html(String raw, String expd) {
wtr.Write_val(Bry_.new_u8(raw));
Tfds.Eq(expd, wtr.To_str_and_clear());
}
}

@ -0,0 +1,36 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Bool_obj_ref {
public boolean Val() {return val;} private boolean val;
public boolean Val_y() {return val;}
public boolean Val_n() {return !val;}
public String Val_as_str_yn() {return Yn.Xto_str(val);}
public Bool_obj_ref Val_y_() {val = true; return this;}
public Bool_obj_ref Val_n_() {val = false; return this;}
public Bool_obj_ref Val_(boolean v) {val = v; return this;}
public Bool_obj_ref Val_toggle_() {val = !val; return this;}
@Override public String toString() {return Bool_.Xto_str_lower(val);}
public static Bool_obj_ref n_() {return new_(false);}
public static Bool_obj_ref y_() {return new_(true);}
public static Bool_obj_ref new_(boolean val) {
Bool_obj_ref rv = new Bool_obj_ref();
rv.val = val;
return rv;
} Bool_obj_ref() {}
}

@ -0,0 +1,34 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Bool_obj_val {
Bool_obj_val(int v) {val = v;} private final int val;
public boolean Val() {return val == 1;}
public static final Bool_obj_val
Null = new Bool_obj_val(-1)
, False = new Bool_obj_val(0)
, True = new Bool_obj_val(1)
;
public static Bool_obj_val read_(Object o) {String s = String_.as_(o); return s == null ? (Bool_obj_val)o : parse_(s);}
public static Bool_obj_val parse_(String raw) {
if (String_.Eq(raw, "y")) return Bool_obj_val.True;
else if (String_.Eq(raw, "n")) return Bool_obj_val.False;
else if (String_.Eq(raw, "")) return Bool_obj_val.Null;
else throw Exc_.new_parse_type(Bool_obj_val.class, raw);
}
}

@ -0,0 +1,35 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Bry_obj_ref {
public byte[] Val() {return val;} public Bry_obj_ref Val_(byte[] v) {val = v; return this;} private byte[] val;
@Override public int hashCode() {return CalcHashCode(val, 0, val.length);}
@Override public boolean equals(Object obj) {return obj == null ? false : Bry_.Eq(val, ((Bry_obj_ref)obj).Val());} // NOTE: strange, but null check needed; throws null error; EX.WP: File:Eug<75>ne Delacroix - La libert<72> guidant le peuple.jpg
public static int CalcHashCode(byte[] ary, int bgn, int end) {
int rv = 0;
for (int i = bgn; i < end; i++)
rv = (31 * rv) + ary[i];
return rv;
}
public static Bry_obj_ref null_() {return new_(null);}
public static Bry_obj_ref new_(byte[] val) {
Bry_obj_ref rv = new Bry_obj_ref();
rv.val = val;
return rv;
} private Bry_obj_ref() {}
}

@ -0,0 +1,31 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Byte_obj_ref {
public byte Val() {return val;} private byte val;
public Byte_obj_ref Val_(byte v) {val = v; return this;}
@Override public int hashCode() {return val;}
@Override public boolean equals(Object obj) {return obj == null ? false : val == ((Byte_obj_ref)obj).Val();}
@Override public String toString() {return Int_.Xto_str(val);}
public static Byte_obj_ref zero_() {return new_(Byte_.Zero);}
public static Byte_obj_ref new_(byte val) {
Byte_obj_ref rv = new Byte_obj_ref();
rv.val = val;
return rv;
} private Byte_obj_ref() {}
}

@ -0,0 +1,29 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Byte_obj_val {
public byte Val() {return val;} private byte val;
@Override public String toString() {return Int_.Xto_str(val);}
@Override public int hashCode() {return val;}
@Override public boolean equals(Object obj) {return obj == null ? false : val == ((Byte_obj_val)obj).Val();}
public static Byte_obj_val new_(byte val) {
Byte_obj_val rv = new Byte_obj_val();
rv.val = val;
return rv;
} private Byte_obj_val() {}
}

@ -0,0 +1,32 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Double_obj_val implements CompareAble {
public double Val() {return val;} double val;
@Override public String toString() {return Double_.Xto_str(val);}
@Override public int hashCode() {return (int)val;}
@Override public boolean equals(Object obj) {return obj == null ? false : val == ((Double_obj_val)obj).Val();}
public int compareTo(Object obj) {Double_obj_val comp = (Double_obj_val)obj; return Double_.Compare(val, comp.val);}
public static Double_obj_val neg1_() {return new_(-1);}
public static Double_obj_val zero_() {return new_(0);}
public static Double_obj_val new_(double val) {
Double_obj_val rv = new Double_obj_val();
rv.val = val;
return rv;
} Double_obj_val() {}
}

@ -0,0 +1,45 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Int_obj_ref {
public int Val() {return val;} public Int_obj_ref Val_(int v) {val = v; return this;} int val;
public int Val_add() {val++; return val;}
public int Val_add_post() {return val++;}
public int Val_add(int v) {val += v; return val;}
public Int_obj_ref Val_zero_() {val = 0; return this;}
public Int_obj_ref Val_neg1_() {val = -1; return this;}
public String Val_as_str() {return Int_.Xto_str(val);}
@Override public String toString() {return Int_.Xto_str(val);}
@Override public int hashCode() {return val;}
@Override public boolean equals(Object obj) {return val == ((Int_obj_ref)obj).Val();}
public static Int_obj_ref neg1_() {return new_(-1);}
public static Int_obj_ref zero_() {return new_(0);}
public static Int_obj_ref new_(int val) {
Int_obj_ref rv = new Int_obj_ref();
rv.val = val;
return rv;
} Int_obj_ref() {}
public static int[] Ary_xto_int_ary(Int_obj_ref[] ary) {
int len = ary.length;
int[] rv = new int[len];
for (int i = 0; i < len; ++i)
rv[i] = ary[i].val;
return rv;
}
}

@ -0,0 +1,32 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class Int_obj_val implements CompareAble {
public int Val() {return val;} int val;
@Override public String toString() {return Int_.Xto_str(val);}
@Override public int hashCode() {return val;}
@Override public boolean equals(Object obj) {return obj == null ? false : val == ((Int_obj_val)obj).Val();}
public int compareTo(Object obj) {Int_obj_val comp = (Int_obj_val)obj; return Int_.Compare(val, comp.val);}
public static Int_obj_val neg1_() {return new_(-1);}
public static Int_obj_val zero_() {return new_(0);}
public static Int_obj_val new_(int val) {
Int_obj_val rv = new Int_obj_val();
rv.val = val;
return rv;
} Int_obj_val() {}
}

@ -0,0 +1,30 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class String_obj_ref {
public String Val() {return val;} public String_obj_ref Val_(String v) {val = v; return this;} private String val;
public String_obj_ref Val_null_() {return Val_(null);}
@Override public String toString() {return val;}
public static String_obj_ref empty_() {return new_("");}
public static String_obj_ref null_() {return new_(null);}
public static String_obj_ref new_(String val) {
String_obj_ref rv = new String_obj_ref();
rv.val = val;
return rv;
} String_obj_ref() {}
}

@ -0,0 +1,27 @@
/*
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.core.primitives; import gplx.*; import gplx.core.*;
public class String_obj_val implements CompareAble {
public String Val() {return val;} private final String val;
@Override public String toString() {return val;}
public int compareTo(Object obj) {
String_obj_val comp = (String_obj_val)obj;
return String_.Compare_strict(val, comp.val);
}
public static String_obj_val new_(String val) {return new String_obj_val(val);} String_obj_val(String val) {this.val = val;}
}

@ -0,0 +1,115 @@
/*
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.core.strings; import gplx.*; import gplx.core.*;
public interface String_bldr {
boolean Has_none();
boolean Has_some();
String_bldr Add_many(String... array);
String_bldr Add_fmt(String format, Object... args);
String_bldr Add_fmt_line(String format, Object... args);
String_bldr Add_kv(String hdr, String val);
String_bldr Add_kv_obj(String k, Object v);
String_bldr Add_char_pipe();
String_bldr Add_char_nl();
String_bldr Add_char_crlf();
String_bldr Add_str_w_crlf(String v);
String_bldr Add_spr_unless_first(String s, String spr, int i);
String_bldr Clear();
String Xto_str_and_clear();
String XtoStr();
int Count();
String_bldr Add(byte[] v);
String_bldr Add(String s);
String_bldr Add(char c);
String_bldr Add(int i);
String_bldr Add_obj(Object o);
String_bldr Add_mid(char[] ary, int bgn, int count);
String_bldr Add_at(int idx, String s);
String_bldr Del(int bgn, int len);
}
abstract class String_bldr_base implements String_bldr {
public boolean Has_none() {return this.Count() == 0;}
public boolean Has_some() {return this.Count() > 0;}
public String_bldr Add_many(String... array) {for (String s : array) Add(s); return this;}
public String_bldr Add_fmt(String format, Object... args) {Add(String_.Format(format, args)); return this;}
public String_bldr Add_fmt_line(String format, Object... args) {Add_str_w_crlf(String_.Format(format, args)); return this;}
public String_bldr Add_kv_obj(String k, Object v) {
if (this.Count() != 0) this.Add(" ");
this.Add_fmt("{0}={1}", k, Object_.Xto_str_strict_or_null_mark(v));
return this;
}
public String_bldr Add_char_pipe() {return Add("|");}
public String_bldr Add_char_nl() {Add(Op_sys.Lnx.Nl_str()); return this;}
public String_bldr Add_char_crlf() {Add(Op_sys.Wnt.Nl_str()); return this;}
public String_bldr Add_str_w_crlf(String line) {Add(line); Add(String_.CrLf); return this;}
public String_bldr Add_spr_unless_first(String s, String spr, int i) {
if (i != 0) Add(spr);
Add(s);
return this;
}
public String_bldr Add_kv(String hdr, String val) {
if (String_.Len_eq_0(val)) return this;
if (this.Count() != 0) this.Add(' ');
this.Add(hdr);
this.Add(val);
return this;
}
public String_bldr Clear() {Del(0, Count()); return this;}
public String Xto_str_and_clear() {
String rv = XtoStr();
Clear();
return rv;
}
@Override public String toString() {return XtoStr();}
public abstract String XtoStr();
public abstract int Count();
public abstract String_bldr Add_at(int idx, String s);
public abstract String_bldr Add(byte[] v);
public abstract String_bldr Add(String s);
public abstract String_bldr Add(char c);
public abstract String_bldr Add(int i);
public abstract String_bldr Add_mid(char[] ary, int bgn, int count);
public abstract String_bldr Add_obj(Object o);
public abstract String_bldr Del(int bgn, int len);
}
class String_bldr_thread_single extends String_bldr_base {
private java.lang.StringBuilder sb = new java.lang.StringBuilder();
@Override public String XtoStr() {return sb.toString();}
@Override public int Count() {return sb.length();}
@Override public String_bldr Add_at(int idx, String s) {sb.insert(idx, s); return this;}
@Override public String_bldr Add(byte[] v) {sb.append(String_.new_u8(v)); return this;}
@Override public String_bldr Add(String s) {sb.append(s); return this;}
@Override public String_bldr Add(char c) {sb.append(c); return this;}
@Override public String_bldr Add(int i) {sb.append(i); return this;}
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
}
class String_bldr_thread_multiple extends String_bldr_base {
private java.lang.StringBuffer sb = new java.lang.StringBuffer();
@Override public String XtoStr() {return sb.toString();}
@Override public int Count() {return sb.length();}
@Override public String_bldr Add_at(int idx, String s) {sb.insert(idx, s); return this;}
@Override public String_bldr Add(byte[] v) {sb.append(String_.new_u8(v)); return this;}
@Override public String_bldr Add(String s) {sb.append(s); return this;}
@Override public String_bldr Add(char c) {sb.append(c); return this;}
@Override public String_bldr Add(int i) {sb.append(i); return this;}
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
}

@ -0,0 +1,22 @@
/*
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.core.strings; import gplx.*; import gplx.core.*;
public class String_bldr_ {
public static String_bldr new_() {return new String_bldr_thread_single();}
public static String_bldr new_thread() {return new String_bldr_thread_multiple();}
}

@ -0,0 +1,61 @@
/*
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.core.strings; import gplx.*; import gplx.core.*;
public class String_ring {
String[] ary = String_.Ary_empty;
public int Len() {return len;} int len;
public String_ring Max_(int v) {
if (v != max) {
ary = new String[v];
max = v;
}
return this;
} int max;
public void Clear() {
for (int i = 0; i < max; i++) {
ary[i] = null;
}
len = nxt = 0;
}
int nxt;
public void Push(String v) {
int idx = nxt++;
if (idx == max) {
idx = 0;
}
if (nxt == max) {
nxt = 0;
}
ary[idx] = v;
if (len < max)
++len;
}
public String[] Xto_str_ary() {
String[] rv = new String[len];
int ary_i = nxt - 1;
for (int rv_i = len - 1; rv_i > -1; rv_i--) {
if (ary_i == -1) {
ary_i = max - 1;
}
rv[rv_i] = ary[ary_i];
--ary_i;
}
return rv;
}
// public String Get_at(int i) {return }
}

@ -0,0 +1,46 @@
/*
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.core.strings; import gplx.*; import gplx.core.*;
import org.junit.*;
public class String_ring_tst {
String_ring_fxt fxt = new String_ring_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Basic() {
fxt.Clear().Max_(3).Push_many("a") .Expd("a");
fxt.Clear().Max_(3).Push_many("a", "b") .Expd("a", "b");
fxt.Clear().Max_(3).Push_many("a", "b", "c") .Expd("a", "b", "c");
fxt.Clear().Max_(3).Push_many("a", "b", "c", "d") .Expd("b", "c", "d");
fxt.Clear().Max_(3).Push_many("a", "b", "c", "d", "e") .Expd("c", "d", "e");
fxt.Clear().Max_(3).Push_many("a", "b", "c", "d", "e", "f") .Expd("d", "e", "f");
}
}
class String_ring_fxt {
String_ring ring = new String_ring();
public String_ring_fxt Clear() {ring.Clear(); return this;}
public String_ring_fxt Max_(int v) {ring.Max_(v); return this;}
public String_ring_fxt Push_many(String... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
ring.Push(ary[i]);
return this;
}
public String_ring_fxt Expd(String... expd) {
Tfds.Eq_ary_str(expd, ring.Xto_str_ary());
return this;
}
}

@ -0,0 +1,28 @@
/*
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.core.threads; import gplx.*; import gplx.core.*;
import java.util.concurrent.locks.*;
public class Gfo_lock {
private final ReentrantLock lock = new ReentrantLock(true);
public void Lock() {
lock.lock();
}
public void Unlock() {
lock.unlock();
}
}

@ -0,0 +1,45 @@
/*
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.core.threads; import gplx.*; import gplx.core.*;
import java.lang.*;
public class Thread_adp implements Runnable {
private String name; private GfoInvkAble invk; private String cmd; private GfoMsg msg;
@gplx.Internal protected Thread_adp(String name, GfoInvkAble invk, String cmd, GfoMsg msg) {
this.name = name; this.invk = invk; this.cmd = cmd; this.msg = msg;
this.ctor_ThreadAdp();
}
void ctor_ThreadAdp() {
this.thread = name == null ? new Thread(this) : new Thread(this, name);
}
public Thread Under_thread() {return thread;} private Thread thread;
public Thread_adp Start() {
thread.start();
return this;
}
public void Interrupt() {thread.interrupt();}
public void Join() {
try {thread.join();}
catch (Exception e) {Exc_.Noop(e);}
}
// public void Stop() {thread.stop();}
public boolean IsAlive() {return thread.isAlive();}
@Override public void run() {
invk.Invk(GfsCtx._, 0, cmd, msg);
}
public static final Thread_adp Null = new Thread_adp(Thread_adp_.Name_null, GfoInvkAble_.Null, "", GfoMsg_.Null);
}

@ -0,0 +1,36 @@
/*
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.core.threads; import gplx.*; import gplx.core.*;
public class Thread_adp_ {
public static void Sleep(int milliseconds) {
try {Thread.sleep(milliseconds);} catch (InterruptedException e) {throw Exc_.new_exc(e, "core", "thread interrupted", "milliseconds", milliseconds);}
}
public static void Notify_all(Object o) {o.notifyAll();}
public static void Wait(Object o) {
try {o.wait();}
catch (InterruptedException e) {throw Exc_.new_exc(e, "core", "thread wait");}
}
public static Thread_adp invk_(GfoInvkAble invk, String cmd) {return invk_(Name_null, invk, cmd);}
public static Thread_adp invk_(String name, GfoInvkAble invk, String cmd) {return new Thread_adp(name, invk, cmd, GfoMsg_.Null);}
public static Thread_adp invk_msg_(GfoInvkAble invk, GfoMsg msg) {return invk_msg_(Name_null, invk, msg);}
public static Thread_adp invk_msg_(String name, GfoInvkAble invk, GfoMsg msg) {return new Thread_adp(name, invk, msg.Key(), msg);}
public static void Run_invk_msg(String name, GfoInvkAble invk, GfoMsg m) {
Thread_adp_.invk_msg_(name, invk, m).Start();
}
public static final String Name_null = null;
}

@ -0,0 +1,63 @@
/*
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 Err extends RuntimeException {
@Override public String getMessage() {return Message_gplx();}
public String Key() {return key;} public Err Key_(String v) {key = v; return this;} private String key = "";
public String Hdr() {return hdr;} public Err Hdr_(String v) {hdr = v; return this;} private String hdr = "";
public List_adp Args() {return args;} List_adp args = List_adp_.new_();
public Err Add(String k, Object o) {args.Add(KeyVal_.new_(k, o)); return this;}
@gplx.Internal protected ErrProcData Proc() {return proc;} ErrProcData proc = ErrProcData.Null;
public Ordered_hash CallStack() {return callStack;} Ordered_hash callStack = Ordered_hash_.new_();
public int CallLevel() {return callLevel;} public Err CallLevel_(int val) {callLevel = val; return this;} public Err CallLevel_1_() {return CallLevel_(1);} int callLevel;
public Err Inner() {return inner;} Err inner;
@gplx.Internal protected static Err hdr_(String hdr) {
Err rv = new Err();
rv.hdr = hdr;
return rv;
} @gplx.Internal protected Err() {}
@gplx.Internal protected static Err exc_(Exception thrown, String hdr) {
Err rv = hdr_(hdr + ":" + Err_.Message_lang(thrown)); // add a better error description; DATE:2014-08-15
rv.inner = convert_(thrown);
for (int i = 0; i < rv.inner.callStack.Count(); i++) {
ErrProcData itm = (ErrProcData)rv.inner.callStack.Get_at(i);
rv.callStack.Add(itm.Raw(), itm);
}
return rv;
}
@gplx.Internal protected static Err convert_(Exception thrown) {
Err rv = Err_.as_(thrown);
if (rv == null)
rv = Err_.new_key_1(ClassAdp_.NameOf_obj(thrown), Err_.Message_lang(thrown));
CallStack_fill(rv, Err_.StackTrace_lang(rv));
return rv;
}
static void CallStack_fill(Err err, String stackTrace) {
ErrProcData[] ary = ErrProcData.parse_ary_(stackTrace); if (Array_.Len(ary) == 0) return; // no callStack; shouldn't happen, but don't throw error
err.proc = ary[0];
for (ErrProcData itm : ary) {
String key = itm.Raw();
if (err.callStack.Has(key)) continue;
err.callStack.Add(key, itm);
}
}
String Message_gplx() {
try {return Err_.Message_gplx(this);}
catch (Exception exc) {Exc_.Noop(exc); return super.getMessage();}
}
}

@ -0,0 +1,112 @@
/*
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.core.strings.*;
public class ErrMsgWtr {
public String Message_gplx(Exception thrown) {
Err err = Err.convert_(thrown); // convert thrown to Err to make rest of class easier
Err[] innerAry = InnerAsAry(err);
String_bldr sb = String_bldr_.new_();
WriteError(innerAry, sb, 0);
WriteInner(innerAry, sb);
WriteStack(innerAry, sb);
return sb.XtoStr();
}
public String Message_gplx_brief(Exception thrown) {
Err err = Err.convert_(thrown); // convert thrown to Err to make rest of proc easier
String_bldr sb = String_bldr_.new_();
sb.Add(err.Hdr());
if (err.Args().Count() > 0) sb.Add(" --");
for (Object kvo : err.Args()) {
KeyVal kv = (KeyVal)kvo;
String key = kv.Key(), val = kv.Val_to_str_or_empty();
sb.Add_fmt(" {0}='{1}'", key, val);
}
sb.Add_fmt(" [{0}]", err.Key());
return sb.XtoStr();
}
void WriteInner(Err[] errAry, String_bldr sb) {
int len = Array_.Len(errAry); if (len <= 1) return; // no inners; return;
for (int i = 1; i < len; i++)
WriteError(errAry, sb, i);
}
void WriteError(Err[] errAry, String_bldr sb, int i) {
Err err = errAry[i];
String msg = err.Hdr();
String typ = String_.Eq(err.Key(), "") ? "" : String_.Concat(" <", err.Key(), ">");
boolean onlyOne = errAry.length == 1;
String idxStr = onlyOne ? "" : Int_.Xto_str(i);
sb.Add(idxStr).Add("\t").Add(msg).Add(typ).Add_char_crlf(); // ex: " @count must be > 0 <gplx.arg>"
WriteKeyValAry(sb, err.Args());
sb.Add("\t").Add(err.Proc().SignatureRaw()).Add_char_crlf();
// WriteKeyValAry(sb, err.ProcArgs());
}
void WriteKeyValAry(String_bldr sb, List_adp ary) {
// calc keyMax for valIndentLen
int keyMax = 0;
for (Object o : ary) {
KeyVal kv = (KeyVal)o;
int keyLen = String_.Len(kv.Key());
if (keyLen > keyMax) keyMax = keyLen + 1; // +1 to guarantee one space between key and val
}
if (keyMax < 8)keyMax = 8; // separate by at least 8 chars
for (Object o : ary) {
KeyVal kv = (KeyVal)o;
String key = kv.Key(); int keyLen = String_.Len(key);
String valIndent = String_.Repeat(" ", keyMax - keyLen);
sb.Add("\t\t@").Add(key).Add(valIndent).Add(kv.Val_to_str_or_empty()).Add_char_crlf();
}
}
void WriteStack(Err[] errAry, String_bldr sb) {
if (Env_.Mode_testing()) return; // only write stack when not testing
int len = Array_.Len(errAry); if (len == 0) return; // shouldn't happen, but don't want to throw err
Err first = errAry[0];
boolean onlyOne = len == 1;
sb.Add_str_w_crlf(String_.Repeat("-", 80));
List_adp tmp = List_adp_.new_();
Ordered_hash callStack = first.CallStack(); int callStackCount = callStack.Count();
for (int i = 0; i < callStackCount ; i++) {
ErrProcData proc = (ErrProcData)callStack.Get_at(i);
// get procIndex
int idx = -1;
for (int j = 0; j < len; j++) {
ErrProcData comp = errAry[j].Proc();
if (String_.Eq(proc.Raw(), comp.Raw())) {idx = j; break;}
}
String idxStr = onlyOne ? "" : Int_.Xto_str(idx);
String hdr = idx == -1 ? "\t" : idxStr + "\t";
String ideAddressSpr = String_.CrLf + "\t\t";
String ideAddress = String_.Eq(proc.IdeAddress(), "") ? "" : ideAddressSpr + proc.IdeAddress(); // NOTE: ideAddress will be blank in compiled mode
String msg = String_.Concat(hdr, proc.SignatureRaw(), ideAddress);
tmp.Add(msg);
}
tmp.Reverse();
for (Object o : tmp)
sb.Add_str_w_crlf((String)o);
}
static Err[] InnerAsAry(Err err) {
List_adp errAry = List_adp_.new_();
Err cur = Err_.as_(err);
while (cur != null) {
errAry.Add(cur);
cur = cur.Inner();
}
return (Err[])errAry.To_ary(Err.class);
}
public static final ErrMsgWtr _ = new ErrMsgWtr(); ErrMsgWtr() {}
}

@ -0,0 +1,67 @@
/*
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;
class ErrProcData {
public String Raw() {return raw;} public ErrProcData Raw_(String val) {raw = val; return this;} private String raw = String_.Empty;
public String SignatureRaw() {return signatureRaw;} public ErrProcData SignatureRaw_(String val) {signatureRaw = val; return this;} private String signatureRaw = String_.Empty;
public String SourceFileRaw() {return sourceFileRaw;} public ErrProcData SourceFileRaw_(String val) {sourceFileRaw = val; return this;} private String sourceFileRaw = String_.Empty;
public int SourceLine() {return sourceLine;} public ErrProcData SourceLine_(int val) {sourceLine = val; return this;} int sourceLine;
public String IdeAddress() {return ideAddress;} public ErrProcData IdeAddress_(String val) {ideAddress = val; return this;} private String ideAddress = String_.Empty;
public static ErrProcData[] parse_ary_(String stackTrace) {
/*
.java
' at gplx.Err.new_(Err.java:92)
at gplx.Err.exc_(Err.java:43)
at gplx.Err_.err_(Err_.java:4)
at gplx._tst.Err__tst.RdrLoad(Err__tst.java:77)
at gplx._tst.Err__tst.MgrInit(Err__tst.java:76)'
.cs
' at gplx._tst.Err__tst.RdrLoad() in c:\000\200_dev\100.gplx\100.framework\100.core\gplx\tst\gplx\err__tst.cs:line 77
at gplx._tst.Err__tst.MgrInit(String s) in c:\000\200_dev\100.gplx\100.framework\100.core\gplx\tst\gplx\err__tst.cs:line 76'
*/
if (stackTrace == null) return new ErrProcData[0];
String[] lines = String_.SplitLines_any(stackTrace);
List_adp list = List_adp_.new_();
int len = Array_.Len(lines);
for (int i = 0; i < len; i++) {
ErrProcData md = ErrProcData.parse_(lines[i]);
if (md.SourceLine() == 0) break; // ASSUME: java code; not interested
if (String_.Has_at_bgn(md.signatureRaw, "gplx.Err_") || String_.Has_at_bgn(md.signatureRaw, "gplx.Err.")) continue; // java includes entire stackTrace from point of creation; only care about point of throw
list.Add(md);
}
return (ErrProcData[])list.To_ary(ErrProcData.class);
}
public static ErrProcData parse_(String raw) {
ErrProcData rv = new ErrProcData().Raw_(raw);
// ex:'gplx.Err.new_(Err.java:92)'
int sigEnd = String_.FindFwd(raw, "("); if (sigEnd == String_.Find_none) return rv;
rv.signatureRaw = String_.Mid(raw, 0, sigEnd);
int filBgn = sigEnd + 1; // 1="("
int filEnd = String_.FindFwd(raw, ":", filBgn); if (filEnd == String_.Find_none) return rv;
rv.sourceFileRaw = String_.Mid(raw, filBgn, filEnd);
int linBgn = filEnd + 1; // 1=":"
int linEnd = String_.FindFwd(raw, ")", linBgn); if (linEnd == String_.Find_none) return rv;
String linRaw = String_.Mid(raw, linBgn, linEnd);
rv.sourceLine = Int_.parse_(linRaw);
rv.ideAddress = String_.Concat("(", rv.sourceFileRaw, ":", Int_.Xto_str(rv.sourceLine), ")");
return rv;
}
public static ErrProcData new_() {return new ErrProcData();} ErrProcData() {}
public static final ErrProcData Null = new ErrProcData();
}

@ -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;
import org.junit.*;
public class ErrProcData_tst {
@Test public void parse_() {
tst_parse_("gplx._tst.Err__tst.RdrLoad(MethodData_tst.java:1)"
, ErrProcData.new_()
.SignatureRaw_("gplx._tst.Err__tst.RdrLoad")
.SourceFileRaw_("MethodData_tst.java")
.SourceLine_(1)
.IdeAddress_("(MethodData_tst.java:1)")
);
}
@Test public void parse_ary_() {
String stackTrace = "";
try {ThrowException();} catch (Exception exc) {stackTrace = Err_.StackTrace_lang(exc);}
ErrProcData[] ary = ErrProcData.parse_ary_(stackTrace);
Tfds.Eq(2, Array_.Len(ary));
Tfds.Eq("gplx.ErrProcData_tst.ThrowException", ary[0].SignatureRaw());
Tfds.Eq("gplx.ErrProcData_tst.parse_ary_", ary[1].SignatureRaw());
}
Exception ThrowException() {
throw new RuntimeException("msg");
}
void tst_parse_(String raw, ErrProcData expd) {
ErrProcData actl = ErrProcData.parse_(raw);
Tfds.Eq(expd.SignatureRaw(), actl.SignatureRaw());
Tfds.Eq(expd.SourceFileRaw(), actl.SourceFileRaw());
Tfds.Eq(expd.SourceLine(), actl.SourceLine());
Tfds.Eq(expd.IdeAddress(), actl.IdeAddress());
}
}

@ -0,0 +1,36 @@
/*
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.core.strings.*;
public class Err_ { //_20110415
public static Err as_(Object obj) {return obj instanceof Err ? (Err)obj : null;}
@gplx.Internal protected static Err new_key_1(String key, String hdr) {return Err.hdr_(hdr).Key_(key);}
public static String Message_lang(Exception e) {return e.getMessage();}
public static String Message_gplx(Exception e) {return ErrMsgWtr._.Message_gplx(e);}
public static String Message_gplx_brief(Exception e) {return ErrMsgWtr._.Message_gplx_brief(e);}
@gplx.Internal protected static String StackTrace_lang(Exception e) {
String_bldr sb = String_bldr_.new_();
StackTraceElement[] stackTraceAry = e.getStackTrace();
int len = stackTraceAry.length;
for (int i = 0; i < len; i++) {
if (i != 0) sb.Add_char_crlf();
sb.Add(stackTraceAry[i].toString());
}
return sb.XtoStr();
}
}

@ -0,0 +1,53 @@
/*
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 Err_arg extends Err {
public String ArgName() {return argName;} private String argName;
public Object ArgValue() {return argValue;} Object argValue;
public static Err_arg null_(String argName) {
Err_arg rv = new Err_arg();
rv.Key_("gplx.arg").Hdr_("@" + rv.argName + " cannot be null");
rv.argName = argName;
return rv;
}
public static Err_arg cannotBe_(String msg, String argName, Object argValue) {
Err_arg rv = new Err_arg();
rv.Key_("gplx.arg");
rv.Hdr_("val cannot be " + msg);
rv.Add("key", argName);
rv.Add("val", argValue);
return rv;
}
public static Err_arg notFound_key_(String argName, Object argValue) {
Err_arg rv = new Err_arg();
rv.Key_("gplx.arg").Hdr_("arg not found").Add(argName, argValue);
rv.argName = argName;
rv.argValue = argValue;
return rv;
}
public static Err_arg outOfBounds_(String argName, int i, int count) {
Err_arg rv = new Err_arg();
rv.Key_("gplx.arg").Hdr_("arg out of bounds").Add("argName", argName).Add("argVal", i).Add("count", count);
rv.argName = argName;
rv.argValue = i;
return rv;
}
public static boolean ClassCheck(Exception e) {
return ClassAdp_.Eq_typeSafe(e, Err_arg.class);
}
}

@ -0,0 +1,34 @@
/*
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_msg_data {
public int Uid() {return uid;} int uid = uid_next++;
public Gfo_msg_itm Item() {return item;} Gfo_msg_itm item;
public Object[] Vals() {return vals;} Object[] vals;
public byte[] Src_bry() {return src_bry;} private byte[] src_bry;
public int Src_bgn() {return src_bgn;} int src_bgn;
public int Src_end() {return src_end;} int src_end;
public Gfo_msg_data Ctor_val_many(Gfo_msg_itm item, Object[] vals) {this.item = item; this.vals = vals; return this;}
public Gfo_msg_data Ctor_src_many(Gfo_msg_itm item, byte[] src_bry, int src_bgn, int src_end, Object[] vals) {this.item = item; this.src_bry = src_bry; this.src_bgn = src_bgn; this.src_end = src_end; this.vals = vals; return this;}
public void Clear() {
item = null; vals = null; src_bry = null;
}
public String Gen_str_ary() {return item.Gen_str_ary(vals);}
static int uid_next = 0;
public static final Gfo_msg_data[] Ary_empty = new Gfo_msg_data[0];
}

@ -0,0 +1,46 @@
/*
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_msg_grp implements Gfo_msg_obj {
public Gfo_msg_grp(Gfo_msg_grp owner, int uid, byte[] key) {
this.owner = owner; this.uid = uid; this.key = key; this.key_str = String_.new_a7(key);
if (owner != null) {
owner.subs.Add(this);
path = Gfo_msg_grp_.Path(owner.path, key);
}
else
path = Bry_.Empty;
}
public void Subs_clear() {subs.Clear();}
public Gfo_msg_grp Owner() {return owner;} Gfo_msg_grp owner;
public int Uid() {return uid;} int uid;
public byte[] Key() {return key;} private byte[] key;
public String Key_str() {return key_str;} private String key_str;
public byte[] Path() {return path;} private byte[] path;
public String Path_str() {return String_.new_a7(path);}
public Gfo_msg_obj Subs_get_by_key(String sub_key) {
int subs_len = subs.Count();
for (int i = 0; i < subs_len; i++) {
Gfo_msg_obj sub = (Gfo_msg_obj)subs.Get_at(i);
if (String_.Eq(sub_key, sub.Key_str())) return sub;
}
return null;
}
public void Subs_add(Gfo_msg_itm item) {subs.Add(item);}
List_adp subs = List_adp_.new_();
}

@ -0,0 +1,30 @@
/*
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_msg_grp_ {
public static final Gfo_msg_grp Root_gplx = new Gfo_msg_grp(null, Gfo_msg_grp_.Uid_next(), Bry_.new_a7("gplx"));
public static final Gfo_msg_grp Root = new Gfo_msg_grp(null, Gfo_msg_grp_.Uid_next(), Bry_.Empty);
public static Gfo_msg_grp prj_(String key) {return new Gfo_msg_grp(Root , Gfo_msg_grp_.Uid_next(), Bry_.new_a7(key));}
public static Gfo_msg_grp new_(Gfo_msg_grp owner, String key) {return new Gfo_msg_grp(owner , Gfo_msg_grp_.Uid_next(), Bry_.new_a7(key));}
public static int Uid_next() {return uid_next++;} static int uid_next = 0;
public static byte[] Path(byte[] owner_path, byte[] key) {
if (owner_path != Bry_.Empty) tmp_bfr.Add(owner_path).Add_byte(Byte_ascii.Dot); // only add "." if owner_path is available; prevents creating ".gplx"
return tmp_bfr.Add(key).Xto_bry_and_clear();
}
static Bry_bfr tmp_bfr = Bry_bfr.reset_(256);
}

@ -0,0 +1,57 @@
/*
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_msg_itm implements Gfo_msg_obj {
public Gfo_msg_itm(Gfo_msg_grp owner, int uid, byte cmd, byte[] key_bry, byte[] fmt, boolean add_to_owner) {
this.owner = owner; this.uid = uid; this.cmd = cmd; this.key_bry = key_bry; this.fmt = fmt;
this.key_str = String_.new_a7(key_bry);
this.path_bry = Gfo_msg_grp_.Path(owner.Path(), key_bry);
if (add_to_owner) owner.Subs_add(this);
}
public Gfo_msg_grp Owner() {return owner;} Gfo_msg_grp owner;
public int Uid() {return uid;} int uid;
public byte[] Path_bry() {return path_bry;} private byte[] path_bry;
public String Path_str() {return String_.new_u8(path_bry);}
public byte[] Key_bry() {return key_bry;} private byte[] key_bry;
public String Key_str() {return key_str;} private String key_str;
public Gfo_msg_obj Subs_get_by_key(String sub_key) {return null;}
public byte Cmd() {return cmd;} private byte cmd;
public byte[] Fmt() {return fmt;} private byte[] fmt;
public Bry_fmtr Fmtr() {if (fmtr == null) fmtr = Bry_fmtr.new_bry_(fmt).Compile(); return fmtr;} Bry_fmtr fmtr;
public String Gen_str_many(Object... vals) {return Gen_str_ary(vals);}
public String Gen_str_ary(Object[] vals) {
if (fmtr == null) fmtr = Bry_fmtr.new_bry_(fmt).Compile();
if (fmtr.Fmt_args_exist()) {
fmtr.Bld_bfr_many(tmp_bfr, vals);
return tmp_bfr.Xto_str_and_clear();
}
else
return String_.new_u8(fmt);
}
public String Gen_str_one(Object val) {
if (fmtr == null) fmtr = Bry_fmtr.new_bry_(fmt).Compile();
if (fmtr.Fmt_args_exist()) {
fmtr.Bld_bfr_one(tmp_bfr, val);
return tmp_bfr.Xto_str_and_clear();
}
else
return String_.new_u8(fmt);
}
public String Gen_str_none() {return key_str;}
static Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
}

@ -0,0 +1,27 @@
/*
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_msg_itm_ {
public static final byte Cmd_null = 0, Cmd_log = 1, Cmd_note = 2, Cmd_warn = 3, Cmd_stop = 4, Cmd_fail = 5;
public static final byte[][] CmdBry = new byte[][] {Bry_.new_a7("null"), Bry_.new_a7("log"), Bry_.new_a7("note"), Bry_.new_a7("warn"), Bry_.new_a7("stop"), Bry_.new_a7("fail")};
public static Gfo_msg_itm new_note_(Gfo_msg_grp owner, String key) {return new_(owner, Cmd_note, key, key);}
public static Gfo_msg_itm new_fail_(Gfo_msg_grp owner, String key, String fmt) {return new_(owner, Cmd_warn, key, fmt);}
public static Gfo_msg_itm new_warn_(Gfo_msg_grp owner, String key) {return new_(owner, Cmd_warn, key, key);}
public static Gfo_msg_itm new_warn_(Gfo_msg_grp owner, String key, String fmt) {return new_(owner, Cmd_warn, key, fmt);}
public static Gfo_msg_itm new_(Gfo_msg_grp owner, byte cmd, String key, String fmt) {return new Gfo_msg_itm(owner, Gfo_msg_grp_.Uid_next(), cmd, Bry_.new_a7(key), Bry_.new_a7(fmt), false);}
}

@ -0,0 +1,54 @@
/*
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_msg_log {
public Gfo_msg_log(String root_key) {root = new Gfo_msg_root(root_key);} Gfo_msg_root root;
public int Ary_len() {return ary_idx;}
public Gfo_msg_data Ary_get(int i) {return ary[i];}
public Gfo_msg_log Clear() {
for (int i = 0; i < ary_idx; i++)
ary[i].Clear();
ary_idx = 0;
return this;
}
public Gfo_msg_log Add_str_warn_key_none(String grp, String itm, byte[] src, int pos) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, null, src, pos, pos + 1, null);}
public Gfo_msg_log Add_str_warn_key_none(String grp, String itm, byte[] src, int bgn, int end) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, null, src, bgn, end, null);}
public Gfo_msg_log Add_str_warn_fmt_none(String grp, String itm, String fmt) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , Bry_.Empty, -1, -1, null);}
public Gfo_msg_log Add_str_warn_fmt_none(String grp, String itm, String fmt, byte[] src, int pos) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , src, pos, pos + 1, null);}
public Gfo_msg_log Add_str_warn_fmt_none(String grp, String itm, String fmt, byte[] src, int bgn, int end) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , src, bgn, end, null);}
public Gfo_msg_log Add_str_warn_fmt_many(String grp, String itm, String fmt, Object... vals) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , Bry_.Empty, -1, -1, vals);}
Gfo_msg_log Add_str(byte cmd, String owner_key, String itm, String fmt, byte[] src, int bgn, int end, Object[] vals) {
if (ary_idx >= ary_max) ary_expand();
ary[ary_idx++] = root.Data_new_many(cmd, src, bgn, end, owner_key, itm, fmt, vals);
return this;
}
public Gfo_msg_log Add_itm_none(Gfo_msg_itm itm, byte[] src, int bgn, int end) {return Add_itm(itm, src, bgn, end, null);}
public Gfo_msg_log Add_itm_many(Gfo_msg_itm itm, byte[] src, int bgn, int end, Object... val_ary) {return Add_itm(itm, src, bgn, end, val_ary);}
Gfo_msg_log Add_itm(Gfo_msg_itm itm, byte[] src, int bgn, int end, Object[] vals) {
if (ary_idx >= ary_max) ary_expand();
ary[ary_idx++] = root.Data_new_many(itm, src, bgn, end, vals);
return this;
}
void ary_expand() {
int new_max = ary_max == 0 ? 2 : ary_max * 2;
ary = (Gfo_msg_data[])Array_.Expand(ary, new Gfo_msg_data[new_max], ary_max);
ary_max = new_max;
}
Gfo_msg_data[] ary = Gfo_msg_data.Ary_empty; int ary_idx, ary_max;
public static Gfo_msg_log Test() {return new Gfo_msg_log("test");}
}

@ -0,0 +1,22 @@
/*
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 interface Gfo_msg_obj {
String Key_str();
Gfo_msg_obj Subs_get_by_key(String sub_key);
}

@ -0,0 +1,80 @@
/*
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_msg_root {
public Gfo_msg_root(String root_key) {
this.root_key = root_key;
this.root = Gfo_msg_grp_.new_(Gfo_msg_grp_.Root, root_key);
} String root_key;
public void Data_ary_clear() {
for (int i = 0; i < data_ary_idx; i++)
data_ary[i].Clear();
data_ary_idx = 0;
}
public void Data_ary_len_(int v) {
data_ary_len = v;
data_ary = new Gfo_msg_data[data_ary_len];
for (int i = 0; i < data_ary_len; i++)
data_ary[i] = new Gfo_msg_data();
data_ary_idx = 0;
} int data_ary_len; int data_ary_idx; Gfo_msg_data[] data_ary;
public void Reset() {
root.Subs_clear();
owners.Clear();
uid_list_next = uid_item_next = 0;
Data_ary_clear();
}
public Gfo_msg_data Data_new_note_many(String owner_key, String key, String fmt, Object... vals) {return Data_new_many(Gfo_msg_itm_.Cmd_note, Bry_.Empty, -1, -1, owner_key, key, fmt, vals);}
public Gfo_msg_data Data_new_many(byte cmd, String owner_key, String key, String fmt, Object[] vals) {return Data_new_many(cmd, Bry_.Empty, -1, -1, owner_key, key, fmt, vals);}
public Gfo_msg_data Data_new_many(byte cmd, byte[] src, int bgn, int end, String owner_key, String key, String fmt, Object[] vals) {
Object owner_obj = owners.Get_by(owner_key);
Gfo_msg_grp owner = null;
if (owner_obj == null) {
owner = New_list_by_key(owner_key);
owners.Add(owner_key, owner);
}
else
owner = (Gfo_msg_grp)owner_obj;
Gfo_msg_itm itm = (Gfo_msg_itm)owner.Subs_get_by_key(key);
if (itm == null)
itm = new Gfo_msg_itm(owner, uid_item_next++, cmd, Bry_.new_u8(key), fmt == null ? Bry_.Empty : Bry_.new_a7(fmt), false);
return Data_new_many(itm, src, bgn, end, vals);
}
public Gfo_msg_data Data_new_many(Gfo_msg_itm itm, byte[] src, int bgn, int end, Object... vals) {return Data_get().Ctor_src_many(itm, src, bgn, end, vals);}
public Gfo_msg_data Data_get() {
return data_ary_idx < data_ary_len ? data_ary[data_ary_idx++] : new Gfo_msg_data();
}
Gfo_msg_grp New_list_by_key(String key) {
String[] segs = String_.Split(key, '.');
int segs_len = segs.length; int segs_last = segs_len - 1;
Gfo_msg_grp cur_list = root;
for (int i = 0; i < segs_last; i++) {
String seg = segs[i];
Gfo_msg_grp sub_list = (Gfo_msg_grp)cur_list.Subs_get_by_key(seg);
if (sub_list == null)
sub_list = new Gfo_msg_grp(cur_list, uid_list_next++, Bry_.new_a7(key));
cur_list = sub_list;
}
return cur_list;
}
Gfo_msg_grp root;
Ordered_hash owners = Ordered_hash_.new_();
int uid_list_next = 0;
int uid_item_next = 0;
public static final Gfo_msg_root _ = new Gfo_msg_root("gplx");
}

@ -0,0 +1,62 @@
/*
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 Gfo_msg_root_tst {
Gfo_msg_root_fxt fxt = new Gfo_msg_root_fxt();
@Before public void setup() {fxt.Reset();}
@Test public void Str() {
fxt.Clear().Expd_data_str_("failed a0 b0").Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a0", "b0");
fxt.Clear().Expd_data_str_("failed a1 b1").Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a1", "b1");
}
// @Test public void Item() { // DISABLED: no longer registering items with owner;
// fxt.Clear().Expd_item_uid_(0).Expd_item_fmtr_arg_exists_(Bool_.Y).Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a0", "b0");
// fxt.Clear().Expd_item_uid_(1).Expd_item_fmtr_arg_exists_(Bool_.N).Tst_data_new_many("proj.cls.proc", "err_1", "failed");
// fxt.Clear().Expd_item_uid_(0).Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a0", "b0"); // make sure item_uid stays the same
// }
@Test public void Cache() {
fxt.Mgr().Data_ary_len_(2);
fxt.Clear().Expd_data_uid_(0).Tst_data_new_many("x", "err_0", "a");
fxt.Clear().Expd_data_uid_(1).Tst_data_new_many("x", "err_0", "b");
fxt.Clear().Expd_data_uid_(2).Tst_data_new_many("x", "err_0", "a");
fxt.Mgr().Data_ary_clear();
fxt.Clear().Expd_data_uid_(0).Tst_data_new_many("x", "err_0", "a");
}
}
class Gfo_msg_root_fxt {
Gfo_msg_root root = new Gfo_msg_root("tst");
public Gfo_msg_root_fxt Reset() {root.Reset(); this.Clear(); return this;}
public Gfo_msg_root_fxt Clear() {
expd_item_uid = -1;
expd_item_fmtr_arg_exists = Bool_.__byte;
expd_data_uid = -1;
expd_data_str = null;
return this;
}
public Gfo_msg_root Mgr() {return root;}
public Gfo_msg_root_fxt Expd_data_uid_(int v) {this.expd_data_uid = v; return this;} int expd_data_uid;
public Gfo_msg_root_fxt Expd_data_str_(String v) {this.expd_data_str = v; return this;} private String expd_data_str;
public Gfo_msg_root_fxt Expd_item_uid_(int v) {this.expd_item_uid = v; return this;} int expd_item_uid;
public Gfo_msg_root_fxt Expd_item_fmtr_arg_exists_(boolean v) {this.expd_item_fmtr_arg_exists = v ? Bool_.Y_byte : Bool_.N_byte; return this;} private byte expd_item_fmtr_arg_exists;
public void Tst_data_new_many(String path, String key, String fmt, Object... vals) {
Gfo_msg_data data = root.Data_new_many(Gfo_msg_itm_.Cmd_note, path, key, fmt, vals);
if (expd_item_uid != -1) Tfds.Eq(expd_item_uid, data.Item().Uid());;
if (expd_item_fmtr_arg_exists != Bool_.__byte) Tfds.Eq(Bool_.By_int(expd_item_fmtr_arg_exists), data.Item().Fmtr().Fmt_args_exist());
if (expd_data_str != null) Tfds.Eq(expd_data_str, data.Item().Gen_str_many(data.Vals()));
}
}

@ -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 interface Cancelable {
boolean Canceled();
void Cancel();
void Cancel_reset();
}

@ -0,0 +1,26 @@
/*
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 Cancelable_ {
public static final Cancelable Never = new Cancelable_never();
}
class Cancelable_never implements Cancelable {
public boolean Canceled() {return false;}
public void Cancel() {}
public void Cancel_reset() {}
}

@ -0,0 +1,20 @@
/*
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 interface CompareAble extends Comparable {} // URL:/doc/gplx/CompareAble_.txt
// public int compareTo(Object obj) {Type comp = (Type)obj; return prop.compareTo(comp.prop);}

@ -0,0 +1,78 @@
/*
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 CompareAble_ {
public static Comparable as_(Object obj) {return obj instanceof Comparable ? (Comparable)obj : null;}
public static int Compare_obj(Object lhs, Object rhs) {return CompareComparables(as_(lhs), as_(rhs));}
public static int CompareComparables(Comparable lhs, Comparable rhs) {
if (lhs == null && rhs == null) return CompareAble_.Same;
else if (lhs == null) return CompareAble_.More;
else if (rhs == null) return CompareAble_.Less;
else return Compare(lhs, rhs);
}
public static boolean Is_more(Comparable lhs, Comparable rhs) {return Is(More, lhs, rhs);}
public static boolean Is_moreOrSame(Comparable lhs, Comparable rhs) {return Is(MoreOrSame, lhs, rhs);}
public static boolean Is_less(Comparable lhs, Comparable rhs) {return Is(Less, lhs, rhs);}
public static boolean Is_lessOrSame(Comparable lhs, Comparable rhs) {return Is(LessOrSame, lhs, rhs);}
public static boolean Is_same(Comparable lhs, Comparable rhs) {return Is(Same, lhs, rhs);}
public static boolean Is(int expt, Comparable lhs, Comparable rhs) {
int actl = CompareComparables(lhs, rhs);
if (actl == Same && expt % 2 == Same) // actl=Same and expt=(Same||MoreOrSame||LessOrSame)
return true;
else
return (actl * expt) > 0; // actl=More||Less; expd will match if on same side of 0 (ex: expt=Less; actl=Less; -1 * -1 = 1)
}
// public static int FindSlot(ComparerAble comparer, Object[] ary, Object itm) {return FindSlot(comparer, ary, itm, false);}
public static int FindSlot(ComparerAble comparer, Object[] ary, Object itm) {if (itm == null) throw Exc_.new_null("itm is null");
int aryLen = ary.length;
switch (aryLen) {
case 0: throw Exc_.new_("ary cannot have 0 itms");
case 1: return 0;
}
int lo = -1, hi = aryLen - 1; // NOTE: -1 is necessary; see test
int curPos = (hi - lo) / 2;
int delta = 1;
while (true) {
Object curSeg = ary[curPos];
int comp = curSeg == null ? CompareAble_.More : comparer.compare(itm, curSeg); // nulls should only happen for lastAry
// if (dbg) {
// Tfds.Write(curPos, itm.toString(), comp, comp.toString(), curSeg.toString());
// }
if (comp == CompareAble_.Same) return curPos;
else if (comp > CompareAble_.Same) {lo = curPos; delta = 1;}
else if (comp < CompareAble_.Same) {hi = curPos; delta = -1;}
int dif = hi - lo;
if (dif == 1 || dif == 0) return hi; // NOTE: can be 0 when ary.length == 1 || 2; also, sometimes 0 in some situations
else curPos += (dif / 2) * delta;
}
}
public static int Compare(Comparable lhs, Comparable rhs) {return lhs.compareTo(rhs);}
public static final int
More = 1
, Less = -1
, Same = 0
, MoreOrSame = 2
, LessOrSame = -2
, ReverseMult = -1
, OffsetCompare = 1 // handle srcPos >= 1 -> srcPosChk > 0
;
public static int Multiplier(boolean v) {return v ? 1 : -1;}
}

@ -0,0 +1,38 @@
/*
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.lists.*;
public class CompareAble_tst implements ComparerAble {
@Test public void Basic() {
String[] slotAry = new String[] {"b", "e", "h"}; // 0=b 1=e 2=h
tst_FindSlot(slotAry, "f", "h"); // f -> 1 2 -> 2
tst_FindSlot(slotAry, "c", "e"); // c -> -1 1 -> 0 -> 0 1 -> 1
tst_FindSlot(slotAry, "a", "b"); // a -> -1 1 -> 0 -> -1 0 -> 0
}
@Test public void Null() {
String[] slotAry = new String[] {"b", "g", "l", "q", "v", null};
tst_FindSlot(slotAry, "a", "b");
tst_FindSlot(slotAry, "b", "b");
tst_FindSlot(slotAry, "c", "g");
tst_FindSlot(slotAry, "v", "v");
tst_FindSlot(slotAry, "w", null);
}
public int compare(Object lhsObj, Object rhsObj) {return CompareAble_.Compare_obj(lhsObj, rhsObj);}
void tst_FindSlot(String[] slotAry, String s, String expd) {Tfds.Eq(expd, slotAry[CompareAble_.FindSlot(this, slotAry, s)]);}
}

@ -0,0 +1,21 @@
/*
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 interface EqAble {
boolean Eq(Object comp);
}

@ -0,0 +1,21 @@
/*
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 interface InjectAble {
void Inject(Object owner);
}

@ -0,0 +1,21 @@
/*
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 interface NewAble {
Object NewByKey(Object o);
}

@ -0,0 +1,21 @@
/*
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 interface ParseAble {
Object ParseAsObj(String raw);
}

@ -0,0 +1,21 @@
/*
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 ParseAble_ {
public static final ParseAble Null = null;
}

@ -0,0 +1,21 @@
/*
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 interface RlsAble {
void Rls();
}

@ -0,0 +1,22 @@
/*
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 RlsAble_ {
public static RlsAble as_(Object obj) {return obj instanceof RlsAble ? (RlsAble)obj : null;}
public static RlsAble cast_(Object obj) {try {return (RlsAble)obj;} catch(Exception exc) {throw Exc_.new_type_mismatch_w_exc(exc, RlsAble.class, obj);}}
}

@ -0,0 +1,21 @@
/*
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 interface SrlAble {
Object Srl(GfoMsg owner);
}

@ -0,0 +1,65 @@
/*
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.core.strings.*;
public class SrlAble_ {
public static SrlAble as_(Object obj) {return obj instanceof SrlAble ? (SrlAble)obj : null;}
public static String XtoStr(GfoMsg owner) {
String_bldr sb = String_bldr_.new_();
XtoStr(owner, sb, 0, false);
return sb.XtoStr();
}
public static String XtoStr(Object o) {
SrlAble s = SrlAble_.as_(o); if (s == null) return Object_.Xto_str_strict_or_null_mark(o);
GfoMsg m = GfoMsg_.new_parse_("root");
s.Srl(m);
return XtoStr(m);
}
static void XtoStr(GfoMsg owner, String_bldr sb, int depth, boolean indentOn) {
String indent = String_.Repeat(" ", depth * 4);
if (indentOn) sb.Add(indent);
sb.Add(owner.Key()).Add(":");
for (int i = 0; i < owner.Args_count(); i++) {
if (i != 0) sb.Add(" ");
KeyVal kv = owner.Args_getAt(i);
sb.Add(kv.Key()).Add("=").Add("'").Add(Object_.Xto_str_strict_or_null_mark(kv.Val())).Add("'");
}
int subsCount = owner.Subs_count();
if (subsCount == 0) {
sb.Add(";");
return;
}
else if (subsCount == 1) {
sb.Add("{");
XtoStr(owner.Subs_getAt(0), sb, depth + 1, false);
sb.Add("}");
return;
}
else {
sb.Add("{");
if (subsCount > 1) sb.Add_char_crlf();
for (int i = 0; i < subsCount; i++) {
GfoMsg sub = owner.Subs_getAt(i);
XtoStr(sub, sb, depth + 1, true);
sb.Add_char_crlf();
}
sb.Add(indent);
sb.Add("}");
}
}
}

@ -0,0 +1,66 @@
/*
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 SrlAble__tst {
@Test public void Basic() {
tst_Srl_
( GfoMsg_.new_cast_("itm").Add("key", "a").Add("val", 1)
, "itm:key='a' val='1';"
);
}
@Test public void Depth1_1() {
tst_Srl_
( GfoMsg_.new_cast_("itm").Add("key", "a").Add("val", 1).Subs_
( GfoMsg_.new_cast_("itm").Add("key", "aa").Add("val", 11)
)
, String_.Concat_lines_crlf_skipLast
( "itm:key='a' val='1'{itm:key='aa' val='11';}"
)
);
}
@Test public void Depth1_2() {
tst_Srl_
( GfoMsg_.new_cast_("itm").Add("key", "a").Add("val", 1).Subs_
( GfoMsg_.new_cast_("itm").Add("key", "aa").Add("val", 11)
, GfoMsg_.new_cast_("itm").Add("key", "ab").Add("val", 12)
)
, String_.Concat_lines_crlf_skipLast
( "itm:key='a' val='1'{"
, " itm:key='aa' val='11';"
, " itm:key='ab' val='12';"
, "}"
)
);
}
@Test public void Depth1_1_2() {
tst_Srl_
( GfoMsg_.new_cast_("itm").Add("key", "a").Add("val", 1).Subs_
( GfoMsg_.new_cast_("itm").Add("key", "aa").Add("val", 11).Subs_(
GfoMsg_.new_cast_("itm").Add("key", "aab").Add("val", 112)
)
)
, String_.Concat_lines_crlf_skipLast
( "itm:key='a' val='1'{itm:key='aa' val='11'{itm:key='aab' val='112';}}"
)
);
}
void tst_Srl_(GfoMsg m, String expd) {Tfds.Eq(expd, SrlAble_.XtoStr(m));}
}
//class SrlAble__tst

@ -0,0 +1,21 @@
/*
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 interface XtoStrAble {
String XtoStr();
}

@ -0,0 +1,21 @@
/*
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 XtoStrAble_ {
public static XtoStrAble as_(Object obj) {return obj instanceof XtoStrAble ? (XtoStrAble)obj : null;}
}

@ -0,0 +1,99 @@
/*
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 java.lang.reflect.Array;
import gplx.core.strings.*;
public class Array_ {
public static void Sort(Object[] obj) {List_adp_sorter.new_().Sort(obj, obj.length);}
public static void Sort(Object[] obj, gplx.lists.ComparerAble comparer) {List_adp_sorter.new_().Sort(obj, obj.length, true, comparer);}
public static List_adp XtoList(Object ary) {
int aryLen = Array_.Len(ary);
List_adp rv = List_adp_.new_();
for (int i = 0; i < aryLen; i++)
rv.Add(Array_.Get(ary, i));
return rv;
}
public static Object[] Insert(Object[] cur, Object[] add, int addPos) {
int curLen = cur.length, addLen = add.length;
Object[] rv = (Object[])Array_.Create(Array_.ComponentType(cur), curLen + addLen);
for (int i = 0; i < addPos; i++) // copy old up to addPos
rv[i] = cur[i];
for (int i = 0; i < addLen; i++) // insert add
rv[i + addPos] = add[i];
for (int i = addPos; i < curLen; i++) // copy old after addPos
rv[i + addLen] = cur[i];
return rv;
}
public static Object[] ReplaceInsert(Object[] cur, Object[] add, int curReplacePos, int addInsertPos) {
int curLen = cur.length, addLen = add.length; int newLen = addLen - addInsertPos;
Object[] rv = (Object[])Array_.Create(Array_.ComponentType(cur), curLen + newLen);
for (int i = 0; i < curReplacePos; i++) // copy old up to curInsertPos; EX: curReplacePos=5, addInsertPos=2; copy up to element 3; 4, 5 are dropped
rv[i] = cur[i];
for (int i = 0; i < addLen; i++) // insert add
rv[i + curReplacePos] = add[i];
for (int i = curReplacePos + addInsertPos; i < curLen; i++) // copy old after curReplacePos
rv[i + newLen] = cur[i];
return rv;
}
public static Object Resize_add_one(Object src, int src_len, Object new_obj) {
Object rv = Resize(src, src_len + 1);
Set(rv, src_len, new_obj);
return rv;
}
public static Object Resize(Object src, int trg_len) {
Object trg = Create(ComponentType(src), trg_len);
int src_len = Array.getLength(src);
int copy_len = src_len > trg_len ? trg_len : src_len; // trg_len can either expand or shrink
CopyTo(src, 0, trg, 0, copy_len);
return trg;
}
public static String XtoStr(Object ary) {
String_bldr sb = String_bldr_.new_();
int ary_len = Len(ary);
for (int i = 0; i < ary_len; i++)
sb.Add_obj(Get(ary, i)).Add_char_nl();
return sb.XtoStr();
}
public static int Len(Object ary) {return Array.getLength(ary);}
public static final int LenAry(Object[] ary) {return ary == null ? 0 : ary.length;}
public static Object Get_at(Object ary, int i) {return Array.get(ary, i); }
public static Object Create(Class<?> t, int count) {return Array.newInstance(t, count);}
public static Object Get(Object ary, int i) {return Array.get(ary, i);}
public static void Set(Object ary, int i, Object o) {Array.set(ary, i, o);}
public static Object Expand(Object src, Object trg, int src_len) {
try {System.arraycopy(src, 0, trg, 0, src_len);}
catch (Exception e) {throw Exc_.new_exc(e, "core", "Array_.Expand failed", "src_len", src_len);}
return trg;
}
public static void Copy(Object src, Object trg) {System.arraycopy(src, 0, trg, 0, Len(src));}
public static void CopyTo(Object src, Object trg, int trgPos) {System.arraycopy(src, 0, trg, trgPos, Len(src));}
public static void CopyTo(Object src, int srcBgn, Object trg, int trgBgn, int srcLen) {System.arraycopy(src, srcBgn, trg, trgBgn, srcLen);}
public static Class<?> ComponentType(Object ary) {
if (ary == null) throw Exc_.new_null("ary");
return ary.getClass().getComponentType();
}
public static Object Resize_add(Object src, Object add) {
int srcLen = Len(src);
int trgLen = srcLen + Len(add);
Object trg = Create(ComponentType(src), trgLen);
Copy(src, trg);
for (int i = srcLen; i < trgLen; i++)
Set(trg, i, Get(add, i - srcLen));
return trg;
}
}

@ -0,0 +1,41 @@
/*
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 Array__tst {
@Test public void Resize_add() {
tst_Resize_add(ary_(), ary_(1), ary_(1)); // 0 + 1 = 1
tst_Resize_add(ary_(0), ary_(), ary_(0)); // 1 + 0 = 1
tst_Resize_add(ary_(0), ary_(1), ary_(0, 1)); // 1 + 1 = 2
} void tst_Resize_add(int[] source, int[] added, int[] expd) {Tfds.Eq_ary(expd, (int[])Array_.Resize_add(source, added));}
@Test public void Resize() {
tst_Resize(ary_(0), 0, ary_()); // 1 -> 0
tst_Resize(ary_(0, 1), 1, ary_(0)); // 2 -> 1
} void tst_Resize(int[] source, int length, int[] expd) {Tfds.Eq_ary(expd, (int[])Array_.Resize(source, length));}
@Test public void Insert() {
tst_Insert(ary_obj(0, 1, 4, 5), ary_obj(2, 3), 2, ary_obj(0, 1, 2, 3, 4, 5));
} void tst_Insert(Object[] cur, Object[] add, int addPos, Object[] expd) {Tfds.Eq_ary(expd, Array_.Insert(cur, add, addPos));}
@Test public void ReplaceInsert() {
tst_ReplaceInsert(ary_obj(0, 1, 4, 5) , ary_obj(1, 2, 3), 1, 1, ary_obj(0, 1, 2, 3, 4, 5));
tst_ReplaceInsert(ary_obj(0, 1, 2, 4, 5) , ary_obj(1, 2, 3), 1, 2, ary_obj(0, 1, 2, 3, 4, 5));
tst_ReplaceInsert(ary_obj(0, 1, 2, 3, 4, 5) , ary_obj(1, 2, 3), 1, 3, ary_obj(0, 1, 2, 3, 4, 5));
tst_ReplaceInsert(ary_obj(0, 1, 9, 4, 5) , ary_obj(2, 3) , 2, 1, ary_obj(0, 1, 2, 3, 4, 5));
} void tst_ReplaceInsert(Object[] cur, Object[] add, int curReplacePos, int addInsertPos, Object[] expd) {Tfds.Eq_ary(expd, Array_.ReplaceInsert(cur, add, curReplacePos, addInsertPos));}
Object[] ary_obj(Object... ary) {return ary;}
int[] ary_(int... ary) {return ary;}
}

@ -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;
public class Bool_ implements GfoInvkAble {
public static final String Cls_val_name = "boolean";
public static final Class<?> Cls_ref_type = Boolean.class;
public static final boolean N = false , Y = true;
public static final byte N_byte = 0 , Y_byte = 1 , __byte = 127;
public static final int N_int = 0 , Y_int = 1 , __int = -1;
public static final String N_str = "n" , Y_str = "y";
public static final byte[] Y_bry = new byte[] {Byte_ascii.Ltr_y}, N_bry = new byte[] {Byte_ascii.Ltr_n};
public static final String True_str = "true", False_str = "false";
public static final byte[] True_bry = Bry_.new_a7(True_str), False_bry = Bry_.new_a7(False_str);
public static boolean cast_(Object obj) {try {return (Boolean)obj;} catch (Exception e) {throw Exc_.new_type_mismatch_w_exc(e, boolean.class, obj);}}
public static boolean cast_or_(Object obj, boolean v) {try {return (Boolean)obj;} catch (Exception e) {Exc_.Noop(e); return v;}}
public static boolean By_int(int v) {return v != 0;}
public static boolean parse_(String raw) {
if ( String_.Eq(raw, "true")
|| String_.Eq(raw, "True") // needed for Store_Wtr(){boolVal.toString();}
)
return true;
else if ( String_.Eq(raw, "false")
|| String_.Eq(raw, "False")
)
return false;
throw Exc_.new_parse_type(boolean.class, raw);
}
public static byte Xto_byte(boolean v) {return v ? Y_byte : N_byte;}
public static int Xto_int(boolean v) {return v ? 1 : 0;}
public static String Xto_str_lower(boolean v) {return v ? "true" : "false";}
public static final boolean[] Ary_empty = new boolean[0];
public static final Bool_ Gfs = new Bool_();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_to_str)) {
boolean v = m.ReadBool(GfsCore_.Arg_primitive);
String fmt = m.ReadStrOr("fmt", null);
if (fmt == null) return v ? "true" : "false";
else if (String_.Eq(fmt, "yn")) return v ? "y" : "n";
else if (String_.Eq(fmt, "yes_no")) return v ? "yes" : "no";
else return v ? "true" : "false";
}
else return GfoInvkAble_.Rv_unhandled;
} public static final String Invk_to_str = "to_str";
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,280 @@
/*
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.core.primitives.*;
import gplx.texts.*;
public class Bry__tst {
@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_.MaxValue, 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 : Bry_.XtoStrByte(expdAryAsInt[i]);
}
Tfds.Eq_ary(expd, Bry_.XtoStrBytesByInt(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.zero_(); tst_ReadCsvStr("a|b|c|", bgn, "a"); tst_ReadCsvStr("a|b|c|", bgn, "b"); tst_ReadCsvStr("a|b|c|", bgn, "c");
tst_ReadCsvStr("|", "");
tst_ReadCsvStr_err("a");
tst_ReadCsvStr("'a'|" , "a");
tst_ReadCsvStr("'a''b'|" , "a'b");
tst_ReadCsvStr("'a|b'|" , "a|b");
tst_ReadCsvStr("''|", "");
tst_ReadCsvStr_err("''");
tst_ReadCsvStr_err("'a'b'");
tst_ReadCsvStr_err("'a");
tst_ReadCsvStr_err("'a|");
tst_ReadCsvStr_err("'a'");
}
@Test public void XtoIntBy4Bytes() { // test len=1, 2, 3, 4
tst_XtoIntBy4Bytes(32, (byte)32); // space
tst_XtoIntBy4Bytes(8707, (byte)34, (byte)3); // &exist;
tst_XtoIntBy4Bytes(6382179, Byte_ascii.Ltr_a, Byte_ascii.Ltr_b, Byte_ascii.Ltr_c);
tst_XtoIntBy4Bytes(1633837924, Byte_ascii.Ltr_a, Byte_ascii.Ltr_b, Byte_ascii.Ltr_c, Byte_ascii.Ltr_d);
}
@Test public void XtoInt() {
tst_XtoInt("1", 1);
tst_XtoInt("123", 123);
tst_XtoInt("a", Int_.MinValue, Int_.MinValue);
tst_XtoInt("-1", Int_.MinValue, -1);
tst_XtoInt("-123", Int_.MinValue, -123);
tst_XtoInt("123-1", Int_.MinValue, Int_.MinValue);
tst_XtoInt("+123", Int_.MinValue, 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_.Xto_int_or(Bry_.new_u8(val), or));}
void tst_XtoIntBy4Bytes(int expd, byte... ary) {Tfds.Eq(expd, Bry_.XtoIntBy4Bytes(ary), "XtoInt"); Tfds.Eq_ary(ary, Bry_.XbyInt(expd), "XbyInt");}
void tst_ReadCsvStr(String raw, String expd) {tst_ReadCsvStr(raw, Int_obj_ref.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.zero_(), (byte)'|');}
catch (Exception e) {Exc_.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.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.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_.Xto_int_or_lax(Bry_.new_u8(val), 0, String_.Len(val), 0));}
@Test public void Xto_int_or_trim() {
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_.Xto_int_or_trim(Bry_.new_u8(val), 0, String_.Len(val), -1));}
@Test public void Compare() {
tst_Compare("abcde", 0, 1, "abcde", 0, 1, CompareAble_.Same);
tst_Compare("abcde", 0, 1, "abcde", 1, 2, CompareAble_.Less);
tst_Compare("abcde", 1, 2, "abcde", 0, 1, CompareAble_.More);
tst_Compare("abcde", 0, 1, "abcde", 0, 2, CompareAble_.Less);
tst_Compare("abcde", 0, 2, "abcde", 0, 1, CompareAble_.More);
tst_Compare("abcde", 2, 3, "abçde", 2, 3, CompareAble_.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 Split() {
tst_Split("a|b|c" , Byte_ascii.Pipe, "a", "b", "c");
tst_Split("a|b|c|" , Byte_ascii.Pipe, "a", "b", "c");
tst_Split("|" , Byte_ascii.Pipe, "");
tst_Split("" , Byte_ascii.Pipe);
}
void tst_Split(String raw_str, byte dlm, String... expd) {
byte[][] actl_bry = Bry_.Split(Bry_.new_a7(raw_str), dlm);
Tfds.Eq_ary_str(expd, String_.Ary(actl_bry));
}
@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(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_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)));
}
private Bry__fxt fxt = new Bry__fxt();
@Test public void Trim_end() {
fxt.Test_trim_end("a " , Byte_ascii.Space, "a"); // trim.one
fxt.Test_trim_end("a " , Byte_ascii.Space, "a"); // trim.many
fxt.Test_trim_end("a" , Byte_ascii.Space, "a"); // trim.none
fxt.Test_trim_end("" , Byte_ascii.Space, ""); // empty
}
@Test public void new_ascii_() {
fxt.Test_new_a7("a" , Bry_.ints_(97)); // one
fxt.Test_new_a7("abc" , Bry_.ints_(97, 98, 99)); // many
fxt.Test_new_a7("" , Bry_.Empty); // none
fxt.Test_new_a7("¢€𤭢" , Bry_.ints_(63, 63, 63, 63)); // non-ascii -> ?
}
@Test public void new_u8() {
fxt.Test_new_u8("a" , Bry_.ints_(97)); // one
fxt.Test_new_u8("abc" , Bry_.ints_(97, 98, 99)); // many
fxt.Test_new_u8("¢" , Bry_.ints_(194, 162)); // bry_len=2; cent
fxt.Test_new_u8("€" , Bry_.ints_(226, 130, 172)); // bry_len=3; euro
fxt.Test_new_u8("𤭢" , Bry_.ints_(240, 164, 173, 162)); // bry_len=3; example from en.w:UTF-8
}
@Test public void Add_w_dlm() {
fxt.Test_add_w_dlm(Byte_ascii.Pipe, String_.Ary("a", "b", "c") , "a|b|c"); // basic
fxt.Test_add_w_dlm(Byte_ascii.Pipe, String_.Ary("a") , "a"); // one item
fxt.Test_add_w_dlm(Byte_ascii.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");
}
}
class Bry__fxt {
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_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_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))));}
}

@ -0,0 +1,567 @@
/*
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.core.primitives.*;
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 (mkr_mgr) {
mkr_mgr.Rls(mkr_idx);
}
synchronized (this) {
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 = Xto_bry();
this.Clear();
if (reset > 0) Reset_if_gt(reset);
synchronized (mkr_mgr) {
mkr_mgr.Rls(mkr_idx);
}
mkr_mgr = null;
mkr_idx = -1;
}
return rv;
}
private 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 ? Byte_ascii.Nil : 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_by_pos(val, 0, val_len, bfr, bfr_len);
// Array_.CopyTo(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 Exc_.new_("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_by_pos(val, bgn, end, bfr, bfr_len);
// Array_.CopyTo(val, bgn, bfr, bfr_len, len);
bfr_len += len;
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_by_pos(src.bfr, 0, len, bfr, bfr_len);
// Array_.CopyTo(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] == Byte_ascii.Nil) {
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] == Byte_ascii.Nil) {
src_end = i + 1;
i = -1;
all_ws = false;
}
}
if (all_ws) return this;
}
src_len = src_end - src_bgn;
Bry_.Copy_by_pos(src.bfr, src_bgn, src_end, bfr, bfr_len);
// Array_.CopyTo(src.bfr, src_bgn, bfr, bfr_len, src_len);
bfr_len += src_len;
src.Clear();
return this;
}
public Bry_bfr Add_byte_eq() {return Add_byte(Byte_ascii.Eq);}
public Bry_bfr Add_byte_pipe() {return Add_byte(Byte_ascii.Pipe);}
public Bry_bfr Add_byte_comma() {return Add_byte(Byte_ascii.Comma);}
public Bry_bfr Add_byte_semic() {return Add_byte(Byte_ascii.Semic);}
public Bry_bfr Add_byte_apos() {return Add_byte(Byte_ascii.Apos);}
public Bry_bfr Add_byte_slash() {return Add_byte(Byte_ascii.Slash);}
public Bry_bfr Add_byte_backslash() {return Add_byte(Byte_ascii.Backslash);}
public Bry_bfr Add_byte_quote() {return Add_byte(Byte_ascii.Quote);}
public Bry_bfr Add_byte_space() {return Add_byte(Byte_ascii.Space);}
public Bry_bfr Add_byte_nl() {return Add_byte(Byte_ascii.Nl);}
public Bry_bfr Add_byte_dot() {return Add_byte(Byte_ascii.Dot);}
public Bry_bfr Add_byte_colon() {return Add_byte(Byte_ascii.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_u8_int(int val) {
if (bfr_len + 4 > bfr_max) Resize((bfr_max + 4) * 2);
int utf8_len = gplx.intl.Utf16_.Encode_int(val, bfr, bfr_len);
bfr_len += utf8_len;
return this;
}
public Bry_bfr Add_bool(boolean v) {return Add(v ? Const_bool_true : Const_bool_false);} public static final byte[] Const_bool_true = Bry_.new_a7("true"), Const_bool_false = Bry_.new_a7("false");
public Bry_bfr Add_int_bool(boolean v) {return Add_int_fixed(v ? 1 : 0, 1);}
public Bry_bfr Add_int_variable(int val) {
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++] = Byte_ascii.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_.MaxValue;
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++] = Byte_ascii.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_.MaxValue;
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(Byte_ascii.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(val);
return this;
}
public Bry_bfr Add_str(String v) {return Add_str_u8(v);}
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 Exc_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);}
}
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 Exc_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);}
}
public Bry_bfr Add_kv_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))).Add_byte_nl();
return this;
}
public Bry_bfr Add_float(float f) {Add_str(Float_.Xto_str(f)); return this;}
public Bry_bfr Add_double(double v) {Add_str(Double_.Xto_str(v)); return this;}
public Bry_bfr Add_dte(DateAdp val) {return Add_dte_segs(val.Year(), val.Month(),val.Day(), val.Hour(), val.Minute(), val.Second(), val.Frac());}
public Bry_bfr Add_dte_segs(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] = Byte_ascii.Space;
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] = Byte_ascii.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] = Byte_ascii.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] = Byte_ascii.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] = Byte_ascii.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] = Byte_ascii.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] = Byte_ascii.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] = Byte_ascii.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 Byte_ascii.Nl: bfr[bfr_len] = Byte_ascii.Backslash; bfr[bfr_len + 1] = Byte_ascii.Ltr_n; bfr_len += 2; break;
case Byte_ascii.Tab: bfr[bfr_len] = Byte_ascii.Backslash; bfr[bfr_len + 1] = Byte_ascii.Ltr_t; bfr_len += 2; break;
case Byte_ascii.Backslash: bfr[bfr_len] = Byte_ascii.Backslash; bfr[bfr_len + 1] = Byte_ascii.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, Bool_.N);}
public Bry_bfr Add_str_pad_space_end(String v, int pad_max) {return Add_str_pad_space(v, pad_max, Bool_.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(Byte_ascii.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((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(Bool_.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 ((Bry_fmtr_arg)o).XferAry(this, 0);
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((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(Bool_.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 ((Bry_fmtr_arg)o).XferAry(this, 0);
return this;
}
public Bry_bfr Add_yn(boolean v) {Add_byte(v ? Byte_ascii.Ltr_y : Byte_ascii.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_utl.XtoStrByAry(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] == Byte_ascii.Nl;}
public boolean Match_end_ary(byte[] ary) {return Bry_.Match(bfr, bfr_len - ary.length, bfr_len, ary);}
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_by_pos (bfr , 0, add_pos, new_bfr, 0);
Bry_.Copy_by_pos (add_bry, add_bgn, add_end, new_bfr, add_pos);
Bry_.Copy_by_pos (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_by_pos(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 Concat_skip_empty(byte[] dlm, byte[]... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
byte[] itm = ary[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[] Xto_bry() {return bfr_len == 0 ? Bry_.Empty : Bry_.Mid(bfr, 0, bfr_len);}
public byte[] Xto_bry_and_reset(int v) {
byte[] rv = Xto_bry();
this.Clear().Reset_if_gt(v);
return rv;
}
public byte[] Xto_bry_and_clear_and_trim() {return Xto_bry_and_clear_and_trim(true, true, Bry_.Trim_ary_ws);}
public byte[] Xto_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);
this.Clear();
return rv;
}
public byte[] Xto_bry_and_clear() {
byte[] rv = Xto_bry();
this.Clear();
if (reset > 0) Reset_if_gt(reset);
return rv;
}
public String Xto_str() {return String_.new_u8(Xto_bry());}
public String Xto_str_by_pos(int bgn, int end) {return String_.new_u8(Xto_bry(), bgn, end);}
public String Xto_str_and_clear() {return String_.new_u8(Xto_bry_and_clear());}
public String Xto_str_and_clear_and_trim() {return String_.new_u8(Xto_bry_and_clear_and_trim());}
public int XtoIntAndClear(int or) {int rv = XtoInt(or); this.Clear(); return rv;}
public int XtoInt(int or) {
switch (bfr_len) {
case 0: return or;
case 1: {
byte b = bfr[0];
return Byte_ascii.Is_num(b) ? b - Byte_ascii.Num_0 : or;
}
default:
long rv = 0, mult = 1;
for (int i = bfr_len - 1; i > -1; i--) {
byte b = bfr[i];
if (!Byte_ascii.Is_num(b)) return or;
long dif = (b - Byte_ascii.Num_0 ) * mult;
long new_val = rv + dif;
if (new_val > Int_.MaxValue) 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();
}
@Override public int hashCode() {return Bry_obj_ref.CalcHashCode(bfr, 0, bfr_len);}
@Override public boolean equals(Object obj) {return obj == null ? false : Bry_.Match(bfr, 0, bfr_len, ((Bry_obj_ref)obj).Val());} // NOTE: strange, but null check needed; throws null error; PAGE:c:File:Eug<75>ne_Delacroix_-_La_libert<72>_guidant_le_peuple.jpg
public void Resize(int v) {
bfr_max = v;
bfr = Bry_.Resize(bfr, 0, v);
}
@gplx.Internal protected int Mkr_idx() {return mkr_idx;} private int mkr_idx = -1;
@gplx.Internal protected boolean Mkr_idx_is_null() {return mkr_idx == -1;}
@gplx.Internal protected int Bfr_max() {return bfr_max;} private int bfr_max;
@gplx.Internal protected 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;
}
public static Bry_bfr new_() {return new Bry_bfr(16);}
public static Bry_bfr new_(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
Bry_bfr(int bfr_max) {
this.bfr_max = bfr_max;
this.bfr = new byte[bfr_max];
}
}

@ -0,0 +1,38 @@
/*
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 Bry_bfr_ {
public static Bry_bfr[] Ary_empty = new Bry_bfr[0];
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;
}
}
}

@ -0,0 +1,158 @@
/*
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 Bry_bfr_mkr {
public static final byte Tid_b128 = 0, Tid_b512 = 1, Tid_k004 = 2, Tid_m001 = 3;
private Bry_bfr_mkr_mgr mkr_b128 = new Bry_bfr_mkr_mgr(Tid_b128, 128), mkr_b512 = new Bry_bfr_mkr_mgr(Tid_b512, 512), mkr_k004 = new Bry_bfr_mkr_mgr(Tid_k004, 4 * Io_mgr.Len_kb), mkr_m001 = new Bry_bfr_mkr_mgr(Tid_m001, 1 * Io_mgr.Len_mb);
public Bry_bfr Get_b128() {return mkr_b128.Get();}
public Bry_bfr Get_b512() {return mkr_b512.Get();}
public Bry_bfr Get_k004() {return mkr_k004.Get();}
public Bry_bfr Get_m001() {return mkr_m001.Get();}
public void Rls(Bry_bfr v) {
v.Mkr_rls();
// v.Mkr_mgr().Rls(v);
}
public void Reset_if_gt(int v) {
for (byte i = Tid_b128; i <= Tid_m001; i++)
mkr(i).Reset_if_gt(v);
}
public void Clear_fail_check() {
for (byte i = Tid_b128; i <= Tid_m001; i++)
mkr(i).Clear_fail_check();
}
public void Clear() {
for (byte i = Tid_b128; i <= Tid_m001; i++)
mkr(i).Clear();
}
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 Exc_.new_unhandled(tid);
}
}
}
class Bry_bfr_mkr_mgr {
private final Object thread_lock;
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
thread_lock = new Object();
synchronized (thread_lock) {
this.mgr_id = mgr_id;
this.reset = reset;
this.free = Int_.Ary_empty;
this.free_len = 0;
}
} private int reset;
public byte Mgr_id() {return mgr_id;} private byte mgr_id;
private Bry_bfr[] ary = Ary_empty; private int nxt_idx = 0, ary_max = 0;
private int[] free; private int free_len;
public void Reset_if_gt(int v) {
this.Clear(); // TODO: for now, just call clear
}
public void Clear_fail_check() {
synchronized (thread_lock) {
for (int i = 0; i < ary_max; i++) {
Bry_bfr itm = ary[i];
if (itm != null) {
if (!itm.Mkr_idx_is_null()) throw Exc_.new_("failed to clear bfr", "idx", Int_.Xto_str(i));
itm.Clear();
}
ary[i] = null;
}
ary = Ary_empty;
free = Int_.Ary_empty;
free_len = 0;
nxt_idx = ary_max = 0;
}
}
public void Clear() {
synchronized (thread_lock) {
for (int i = 0; i < ary_max; i++) {
Bry_bfr itm = ary[i];
if (itm != null) itm.Clear();
ary[i] = null;
}
ary = Ary_empty;
free = Int_.Ary_empty;
free_len = 0;
nxt_idx = ary_max = 0;
}
}
public Bry_bfr[] Ary() {return ary;}
public int Nxt_idx() {return nxt_idx;}
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 Exc_.new_exc(e, "core", "failed to get free index", "free_len", free_len, "free.length", free.length);}
try {rv = ary[rv_idx];}
catch (Exception e) {throw Exc_.new_exc(e, "core", "failed to get bfr", "rv_idx", rv_idx, "ary.length", ary.length);}
}
else {
if (nxt_idx == ary_max)
Expand();
rv_idx = nxt_idx++;
rv = ary[rv_idx];
if (rv == null) {
rv = Bry_bfr.reset_(reset);
ary[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
}
}
private void Expand() {
int new_max = ary_max == 0 ? 2 : ary_max * 2;
Bry_bfr[] new_ary = new Bry_bfr[new_max];
Array_.CopyTo(ary, 0, new_ary, 0, ary_max);
ary = new_ary;
ary_max = new_max;
int[] new_free = new int[ary_max];
Array_.CopyTo(free, 0, new_free, 0, free_len);
free = new_free;
}
// public void Rls(Bry_bfr v) {
// synchronized (thread_lock) {
// int idx = v.Mkr_itm();
// if (idx == -1) throw Err_mgr._.fmt_("gplx.Bry_bfr", "rls_failed", "rls called on bfr that was not created by factory");
// int new_ary_len = nxt_idx - 1;
// if (idx == new_ary_len)
// nxt_idx = new_ary_len;
// else
// free[free_len++] = idx;
// v.Mkr_(null, -1);
// }
// }
public void Rls(int idx) {
synchronized (thread_lock) {
if (idx == -1) throw Exc_.new_("rls called on bfr that was not created by factory");
int new_ary_len = nxt_idx - 1;
if (idx == new_ary_len)
nxt_idx = new_ary_len;
else
free[free_len++] = idx;
}
}
public static final Bry_bfr[] Ary_empty = new Bry_bfr[0];
}

@ -0,0 +1,74 @@
/*
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 Bry_bfr_mkr_tst {
Bry_bfr_mkr_fxt fxt = new Bry_bfr_mkr_fxt();
@Before public void setup() {fxt.Clear();}
@Test public void Get_1() {fxt.Clear().Get().Tst_idxs(0);}
@Test public void Get_2() {fxt.Clear().Get().Get().Tst_idxs(0, 1);}
@Test public void Get_3() {fxt.Clear().Get().Get().Get().Tst_idxs(0, 1, 2);}
@Test public void Rls() {
fxt.Clear().Get().Rls(0).Tst_idxs();
}
@Test public void Rls_skip_1() {
fxt.Clear().Get().Get().Rls(0).Tst_idxs(-1, 1);
fxt.Get().Tst_idxs(0, 1);
}
@Test public void Rls_skip_2_1() {
fxt.Clear().Get().Get().Get().Rls(1).Rls(0).Tst_idxs(-1, -1, 2);
fxt.Get().Tst_idxs(0, -1, 2);
fxt.Get().Tst_idxs(0, 1, 2);
fxt.Get().Tst_idxs(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).Tst_idxs();
}
public static final int Int_null = -2;
}
class Bry_bfr_mkr_fxt {
Bry_bfr_mkr_mgr mkr;
public Bry_bfr_mkr_fxt Clear() {
if (mkr == null) {
mkr = new Bry_bfr_mkr_mgr(Byte_.Zero, 32);
}
mkr.Clear();
return this;
}
public Bry_bfr_mkr_fxt Get() {
mkr.Get();
return this;
}
public Bry_bfr_mkr_fxt Rls(int i) {
Bry_bfr bfr = mkr.Ary()[i];
bfr.Mkr_rls();
return this;
}
public Bry_bfr_mkr_fxt Tst_idxs(int... expd) {
int actl_len = mkr.Nxt_idx();
int[] actl = new int[actl_len];
for (int i = 0; i < actl_len; i++) {
Bry_bfr bfr = mkr.Ary()[i];
int actl_val = Bry_bfr_mkr_tst.Int_null;
if (bfr != null) actl_val = bfr.Mkr_idx();
actl[i] = actl_val;
}
Tfds.Eq_ary(expd, actl);
return this;
}
}

@ -0,0 +1,227 @@
/*
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 Bry_bfr_tst {
private Bry_bfr bb = Bry_bfr.new_(16);
@Before public void setup() {bb.Clear();} private ByteAryBfr_fxt fxt = new ByteAryBfr_fxt();
@Test public void AddByte() {
bb = Bry_bfr.new_(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_(2);
tst_AddByte("abcd", "abcd", 12);
}
@Test public void Add_byte_repeat() { // NOTE: make sure auto-expands
bb = Bry_bfr.new_(2);
tst_Add_byte_repeat(Byte_ascii.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).Xto_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.Xto_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.Xto_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.Xto_bry())));
}
void Add_int_variable(int val) {
bb.Clear();
bb.Add_int_variable(val);
Tfds.Eq(val, Int_.parse_(String_.new_u8(bb.Xto_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).Xto_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).Xto_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.XtoIntAndClear(); break;
// case 7: m = ib.XtoIntAndClear(); break;
// case 10: d = ib.XtoIntAndClear(); break;
// case 13: h = ib.XtoIntAndClear(); break;
// case 16: n = ib.XtoIntAndClear(); break;
// case 19: s = ib.XtoIntAndClear(); break;
// default: ib.Add(b); break;
// }
// }
// long l = Pow38_to(y, m, d, h, n, s);
//// Base85_utl.XtoStrByAry(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.Xto_str_and_clear();
// Tfds.Eq(expd, actl);
// }
@Test public void Xto_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(raw);
Tfds.Eq(expd, String_.new_u8(bb.Xto_bry_and_clear_and_trim()));
}
@Test public void XtoInt() {
tst_XtoInt("123", 123);
tst_XtoInt("a", Int_.MinValue);
tst_XtoInt("9999999999", Int_.MinValue);
}
void tst_XtoInt(String raw, int expd) {
bb.Add_str(raw);
Tfds.Eq(expd, bb.XtoIntAndClear(Int_.MinValue));
}
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(raw);
Tfds.Eq(expd, bb.Add_bfr_trim_and_clear(tmp, false, true).Xto_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(raw);
Tfds.Eq(expd, bb.Add_bfr_trim_and_clear(tmp, true, true).Xto_str_and_clear());
}
@Test public void Add_int_pad_bgn() {
fxt.Test_Add_int_pad_bgn(Byte_ascii.Num_0, 3, 0, "000");
fxt.Test_Add_int_pad_bgn(Byte_ascii.Num_0, 3, 1, "001");
fxt.Test_Add_int_pad_bgn(Byte_ascii.Num_0, 3, 10, "010");
fxt.Test_Add_int_pad_bgn(Byte_ascii.Num_0, 3, 100, "100");
fxt.Test_Add_int_pad_bgn(Byte_ascii.Num_0, 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)
}
@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");
}
}
class ByteAryBfr_fxt {
private Bry_bfr bfr = Bry_bfr.reset_(16);
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).Xto_str_and_clear());}
public void Test_Add_bry_escape(String val, String expd) {
byte[] val_bry = Bry_.new_u8(val);
Tfds.Eq(expd, bfr.Add_bry_escape(Byte_ascii.Apos, Byte_.Ary(Byte_ascii.Apos, Byte_ascii.Apos), val_bry, 0, val_bry.length).Xto_str_and_clear());
}
public void Test_Insert_at(String init, int pos, String val, String expd) {Tfds.Eq(expd, bfr.Add_str(init).Insert_at(pos, Bry_.new_u8(val)).Xto_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(init).Insert_at(pos, Bry_.new_u8(val), val_bgn, val_end).Xto_str_and_clear());}
public void Test_Delete_rng(String init, int bgn, int end, String expd) {Tfds.Eq(expd, bfr.Add_str(init).Delete_rng(bgn, end).Xto_str_and_clear());}
public void Test_Delete_rng_to_bgn(String init, int pos, String expd) {Tfds.Eq(expd, bfr.Add_str(init).Delete_rng_to_bgn(pos).Xto_str_and_clear());}
public void Test_Delete_rng_to_end(String init, int pos, String expd) {Tfds.Eq(expd, bfr.Add_str(init).Delete_rng_to_end(pos).Xto_str_and_clear());}
}

@ -0,0 +1,296 @@
/*
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 Bry_finder {
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_finder.Not_found;
}
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_finder.Not_found;
}
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_finder.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_finder.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);}
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_finder.Not_found;
int dif, lkp_len = lkp.length, lkp_bgn, lkp_end, src_end_chk;
if (fwd) {
if (src_bgn > src_end) return Bry_finder.Not_found;
dif = 1; lkp_bgn = 0; lkp_end = lkp_len; src_end_chk = src_end - CompareAble_.OffsetCompare;
}
else {
if (src_bgn < src_end) return Bry_finder.Not_found;
dif = -1; lkp_bgn = lkp_len - 1; lkp_end = -1; src_end_chk = src.length - CompareAble_.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_finder.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_finder.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_finder.Not_found;
}
public static int Find_bwd_last_ws(byte[] src, int cur) {
if (cur < 1) return Bry_finder.Not_found;
--cur;
int rv = Bry_finder.Not_found;
for (int i = cur; i > -1; i--) {
byte b = src[i];
switch (b) {
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.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 Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr:
return i;
}
}
return Bry_finder.Not_found;
}
public static int Find_fwd_last_ws(byte[] src, int cur) {
int end = src.length;
if (cur >= end) return Bry_finder.Not_found;
int rv = Bry_finder.Not_found;
for (int i = cur; i < end; i++) {
byte b = src[i];
switch (b) {
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.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_finder.Not_found;
for (int i = cur; i >= end; i--) {
byte b = src[i];
switch (b) {
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr:
break;
default:
return i;
}
}
return Bry_finder.Not_found;
}
public static int Find_bwd_non_ws_or_end(byte[] src, int cur, int end) {
if (cur >= src.length) return Bry_finder.Not_found;
for (int i = cur; i >= end; i--) {
byte b = src[i];
switch (b) {
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr:
break;
default:
return i;
}
}
return end;
}
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_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_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_finder.Not_found;
switch (src[cur]) {
case Byte_ascii.Space: case Byte_ascii.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_finder.Not_found;
switch (src[cur]) {
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.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 Byte_ascii.Space: case Byte_ascii.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 Byte_ascii.Space: case Byte_ascii.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 Byte_ascii.Space: case Byte_ascii.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 Byte_ascii.Nl: case Byte_ascii.Cr:
case Byte_ascii.Space: case Byte_ascii.Tab: ++cur; break;
default: return cur;
}
} catch (Exception e) {throw Exc_.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 Byte_ascii.Ltr_A: case Byte_ascii.Ltr_B: case Byte_ascii.Ltr_C: case Byte_ascii.Ltr_D: case Byte_ascii.Ltr_E:
case Byte_ascii.Ltr_F: case Byte_ascii.Ltr_G: case Byte_ascii.Ltr_H: case Byte_ascii.Ltr_I: case Byte_ascii.Ltr_J:
case Byte_ascii.Ltr_K: case Byte_ascii.Ltr_L: case Byte_ascii.Ltr_M: case Byte_ascii.Ltr_N: case Byte_ascii.Ltr_O:
case Byte_ascii.Ltr_P: case Byte_ascii.Ltr_Q: case Byte_ascii.Ltr_R: case Byte_ascii.Ltr_S: case Byte_ascii.Ltr_T:
case Byte_ascii.Ltr_U: case Byte_ascii.Ltr_V: case Byte_ascii.Ltr_W: case Byte_ascii.Ltr_X: case Byte_ascii.Ltr_Y: case Byte_ascii.Ltr_Z:
case Byte_ascii.Ltr_a: case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_e:
case Byte_ascii.Ltr_f: case Byte_ascii.Ltr_g: case Byte_ascii.Ltr_h: case Byte_ascii.Ltr_i: case Byte_ascii.Ltr_j:
case Byte_ascii.Ltr_k: case Byte_ascii.Ltr_l: case Byte_ascii.Ltr_m: case Byte_ascii.Ltr_n: case Byte_ascii.Ltr_o:
case Byte_ascii.Ltr_p: case Byte_ascii.Ltr_q: case Byte_ascii.Ltr_r: case Byte_ascii.Ltr_s: case Byte_ascii.Ltr_t:
case Byte_ascii.Ltr_u: case Byte_ascii.Ltr_v: case Byte_ascii.Ltr_w: case Byte_ascii.Ltr_x: case Byte_ascii.Ltr_y: case Byte_ascii.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 (!Byte_ascii.Is_num(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 Byte_ascii.Space:
case Byte_ascii.Nl:
case Byte_ascii.Tab:
case Byte_ascii.Cr:
++cur;
break;
default:
return cur;
}
}
}
}

@ -0,0 +1,78 @@
/*
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.texts.*;
public class Bry_finder_tst {
private Bry_finder_fxt fxt = new Bry_finder_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_.NotFound); // 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);
}
}
class Bry_finder_fxt {
public void Test_Find_fwd(String src, String lkp, int bgn, int expd) {Tfds.Eq(expd, Bry_finder.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_finder.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_finder.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_finder.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_finder.Trim_fwd_space_tab(raw_bry, 0, raw_bry.length);
Tfds.Eq(expd, actl, raw_str);
}
}

@ -0,0 +1,267 @@
/*
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.core.primitives.*; import gplx.core.strings.*;
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._;
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])), Int_obj_val.new_(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, Bry_fmtr_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].XferAry(bfr, itm.ArgIdx);
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.Xto_bry_and_clear();}
public byte[] Bld_bry_many(Bry_bfr bfr, Object... args) {
Bld_bfr_ary(bfr, args);
return bfr.Xto_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.Xto_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.XtoStr();
} 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_(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;
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.XtoInt(0) - baseInt));
else {
byte[] key_fmt = lkp_bfr.Xto_bry();
Object idx_ref = keys.Get_by(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 Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
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 Exc_.new_("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
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 = Byte_ascii.Nl;
else if (nxt_byte == char_escape_tab) tmp_byte = Byte_ascii.Tab;
else {
if (fail_when_invalid_escapes) throw Exc_.new_("unknown escape code", "code", Char_.XbyInt(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 Exc_.new_("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.To_ary(Bry_fmtr_itm.class);
itms_len = itms.length;
return this;
}
}
int Compile_eval_cmd(byte[] fmt, int fmt_len, int eval_lhs_bgn, List_adp list) {
int eval_lhs_end = Bry_finder.Find_fwd(fmt, char_eval_end, eval_lhs_bgn + Int_.Const_dlm_len, fmt_len); if (eval_lhs_end == Bry_.NotFound) throw Exc_.new_("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 + Int_.Const_dlm_len);
int eval_rhs_bgn = Bry_finder.Find_fwd(fmt, eval_dlm , eval_lhs_end + Int_.Const_dlm_len, fmt_len); if (eval_rhs_bgn == Bry_.NotFound) throw Exc_.new_("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 + Int_.Const_dlm_len, eval_rhs_bgn);
byte[] eval_rslt = eval_mgr.Eval(eval_cmd);
int eval_rhs_end = eval_rhs_bgn + Int_.Const_dlm_len + 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 = Byte_ascii.Tilde, char_arg_bgn = Byte_ascii.Curly_bgn, char_arg_end = Byte_ascii.Curly_end, char_escape_nl = Byte_ascii.Ltr_n, char_escape_tab = Byte_ascii.Ltr_t, char_eval_bgn = Byte_ascii.Lt, char_eval_end = Byte_ascii.Gt;
public static final Bry_fmtr Null = new Bry_fmtr().Fmt_("");
public static Bry_fmtr 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(key);
tmp_bfr.Add_byte(Byte_ascii.Colon);
int args_len = args.length;
for (int i = 0; i < args_len; i++) { // add " 0='~{0}'"
tmp_bfr.Add_byte(Byte_ascii.Space);
tmp_bfr.Add_int_variable(i);
tmp_bfr.Add_byte(Byte_ascii.Eq);
tmp_bfr.Add_byte(Byte_ascii.Apos);
tmp_bfr.Add_byte(Byte_ascii.Tilde);
tmp_bfr.Add_byte(Byte_ascii.Curly_bgn);
tmp_bfr.Add_int_variable(i);
tmp_bfr.Add_byte(Byte_ascii.Curly_end);
tmp_bfr.Add_byte(Byte_ascii.Apos);
}
return tmp_bfr.Xto_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.Xto_bry_and_clear();
this.Fmt_(bry).Compile();
}
public static String Escape_tilde(String v) {return String_.Replace(v, "~", "~~");}
}

@ -0,0 +1,21 @@
/*
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 interface Bry_fmtr_arg {
void XferAry(Bry_bfr bfr, int idx);
}

@ -0,0 +1,33 @@
/*
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.brys.*;
public class Bry_fmtr_arg_ {
public static Bry_fmtr_arg_bry bry_(String v) {return new Bry_fmtr_arg_bry(Bry_.new_u8(v));}
public static Bry_fmtr_arg_bry bry_(byte[] v) {return new Bry_fmtr_arg_bry(v);}
public static Bry_fmtr_arg_byt byt_(byte v) {return new Bry_fmtr_arg_byt(v);}
public static Bry_fmtr_arg_int int_(int v) {return new Bry_fmtr_arg_int(v);}
public static Bry_fmtr_arg_bfr bfr_(Bry_bfr v) {return new Bry_fmtr_arg_bfr(v);}
public static Bry_fmtr_arg_bfr_preserve bfr_retain_(Bry_bfr v) {return new Bry_fmtr_arg_bfr_preserve(v);}
public static Bry_fmtr_arg fmtr_(Bry_fmtr v, Bry_fmtr_arg... arg_ary) {return new Bry_fmtr_arg_fmtr(v, arg_ary);}
public static Bry_fmtr_arg_fmtr_objs fmtr_null_() {return new Bry_fmtr_arg_fmtr_objs(null, null);}
public static final Bry_fmtr_arg Noop = new Bry_fmtr_arg__noop();
}
class Bry_fmtr_arg__noop implements Bry_fmtr_arg {
public void XferAry(Bry_bfr trg, int idx) {}
}

@ -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 Bry_fmtr_arg_fmtr_objs implements Bry_fmtr_arg {
public Bry_fmtr_arg_fmtr_objs Atrs_(Bry_fmtr fmtr, Object... objs) {this.fmtr = fmtr; this.objs = objs; return this;}
public void XferAry(Bry_bfr trg, int idx) {
fmtr.Bld_bfr_many(trg, objs);
}
public Bry_fmtr_arg_fmtr_objs(Bry_fmtr fmtr, Object[] objs) {this.fmtr = fmtr; this.objs = objs;} Bry_fmtr fmtr; Object[] objs;
}

@ -0,0 +1,22 @@
/*
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 interface Bry_fmtr_eval_mgr {
boolean Enabled(); void Enabled_(boolean v);
byte[] Eval(byte[] cmd);
}

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

Loading…
Cancel
Save