mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.7.2.1
This commit is contained in:
123
400_xowa/src/gplx/core/brys/Bit_.java
Normal file
123
400_xowa/src/gplx/core/brys/Bit_.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
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 Bit_ {
|
||||
public static String XtoBitStr(int val) {
|
||||
boolean[] bits = new boolean[8];
|
||||
int idx = 7;
|
||||
while (val > 0) {
|
||||
if ((val & 1) == 1) bits[idx] = true;
|
||||
idx--;
|
||||
val >>= 1;
|
||||
}
|
||||
byte[] rv = new byte[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
rv[i] = bits[i] ? Byte_ascii.Num_1 : Byte_ascii.Num_0;
|
||||
return String_.new_a7(rv);
|
||||
}
|
||||
public static int[] Bld_pow_ary(int... seg_ary) {
|
||||
int seg_ary_len = seg_ary.length;
|
||||
int pow = 0;
|
||||
int[] rv = new int[seg_ary_len];
|
||||
for (int i = seg_ary_len - 1; i > -1; i--) {
|
||||
rv[i] = Base2_ary[pow];
|
||||
pow += seg_ary[i];
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static int Xto_int(int[] pow_ary, int[] val_ary) {
|
||||
int pow_ary_last = pow_ary.length - 1;
|
||||
int val = 0;
|
||||
for (int i = pow_ary_last; i > -1; i--)
|
||||
val += pow_ary[i] * val_ary[i];
|
||||
return val;
|
||||
}
|
||||
public static int[] Xto_intAry(int[] pow_ary, int v) {
|
||||
int[] rv = new int[pow_ary.length];
|
||||
Xto_intAry(rv, pow_ary, v);
|
||||
return rv;
|
||||
}
|
||||
public static void Xto_intAry(int[] rv, int[] pow_ary, int v) {
|
||||
int pow_ary_len = pow_ary.length;
|
||||
int rv_len = rv.length;
|
||||
for (int i = 0; i < pow_ary_len; i++) {
|
||||
if (i >= rv_len) break;
|
||||
rv[i] = v / pow_ary[i];
|
||||
int factor = pow_ary[i] * rv[i];
|
||||
v = factor == 0 ? v : (v % factor); // NOTE: if 0, do not do modulus or else div by zero
|
||||
}
|
||||
}
|
||||
public static byte Xto_byte(byte[] pow_ary, byte... val_ary) {
|
||||
int pow_ary_last = pow_ary.length - 1;
|
||||
int val = 0;
|
||||
for (int i = pow_ary_last; i > -1; --i)
|
||||
val += pow_ary[i] * val_ary[i];
|
||||
return (byte)val;
|
||||
}
|
||||
public static void Xto_bry(byte[] rv, byte[] pow_ary, byte val) {
|
||||
int pow_ary_len = pow_ary.length;
|
||||
int rv_len = rv.length;
|
||||
for (int i = 0; i < pow_ary_len; i++) {
|
||||
if (i >= rv_len) break;
|
||||
rv[i] = (byte)(val / pow_ary[i]);
|
||||
int factor = pow_ary[i] * rv[i];
|
||||
val = (byte)(factor == 0 ? val : (val % factor)); // NOTE: if 0, do not do modulus or else div by zero
|
||||
}
|
||||
}
|
||||
public static int Shift_lhs(int val, int shift) {return val << shift;}
|
||||
public static int Shift_rhs(int val, int shift) {return val >> shift;}
|
||||
public static int Shift_lhs_to_int(int[] shift_ary, int... val_ary) {
|
||||
int val_len = val_ary.length; if (val_len > shift_ary.length) throw Exc_.new_("vals must be less than shifts", "vals", val_len, "shifts", shift_ary.length);
|
||||
int rv = 0;
|
||||
for (int i = 0; i < val_len; ++i) {
|
||||
int val = val_ary[i];
|
||||
int shift = shift_ary[i];
|
||||
rv += val << shift;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static void Shift_rhs_to_ary(int[] rv, int[] shift_ary, int val) {
|
||||
int shift_len = shift_ary.length;
|
||||
for (int i = shift_len - 1; i > - 1; --i) {
|
||||
int shift = shift_ary[i];
|
||||
int itm = val >> shift;
|
||||
rv[i] = itm;
|
||||
val -= (itm << shift);
|
||||
}
|
||||
}
|
||||
public static int Xto_int_date_short(int[] val_ary) {
|
||||
val_ary[0] -= 1900;
|
||||
return Xto_int(Pow_ary_date_short, val_ary);
|
||||
}
|
||||
public static void Xto_date_short_int_ary(int[] rv, int v) {
|
||||
Xto_intAry(rv, Pow_ary_date_short, v);
|
||||
rv[0] += 1900;
|
||||
}
|
||||
public static DateAdp Xto_date_short(int v) {
|
||||
int[] rv = new int[Pow_ary_date_short.length];
|
||||
Xto_date_short_int_ary(rv, v);
|
||||
return DateAdp_.seg_(rv);
|
||||
}
|
||||
private static final int[] Pow_ary_date_short = new int[] {1048576, 65536, 2048, 64, 1}; // yndhm -> 12,4,5,5,6
|
||||
private static final int[] Base2_ary = new int[]
|
||||
{ 1, 2, 4, 8, 16, 32, 64, 128
|
||||
, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
|
||||
, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608
|
||||
, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 0
|
||||
};
|
||||
}
|
||||
109
400_xowa/src/gplx/core/brys/Bit__tst.java
Normal file
109
400_xowa/src/gplx/core/brys/Bit__tst.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
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.*;
|
||||
import org.junit.*;
|
||||
public class Bit__tst {
|
||||
@Before public void init() {fxt.Clear();} private Bit__fxt fxt = new Bit__fxt();
|
||||
@Test public void XtoBitStr() {
|
||||
tst_XtoBitStr( 0, "00000000");
|
||||
tst_XtoBitStr( 1, "00000001");
|
||||
tst_XtoBitStr( 2, "00000010");
|
||||
tst_XtoBitStr( 3, "00000011");
|
||||
tst_XtoBitStr(255, "11111111");
|
||||
} void tst_XtoBitStr(int val, String expd) {Tfds.Eq(expd, Bit_.XtoBitStr(val));}
|
||||
@Test public void Bld_pow_ary() {
|
||||
tst_Bld_pow_ary(ary_(1, 1, 1, 1), ary_(8, 4, 2, 1));
|
||||
tst_Bld_pow_ary(ary_(3, 2) , ary_(4, 1));
|
||||
} void tst_Bld_pow_ary(int[] seg_ary, int[] expd) {Tfds.Eq_ary_str(expd, Bit_.Bld_pow_ary(seg_ary));}
|
||||
@Test public void Xto_int() {
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(1, 1, 1, 1), 15);
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(0, 0, 0, 0), 0);
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(1, 0, 0, 1), 9);
|
||||
tst_Xto_int(ary_(1, 1, 1, 1) , ary_(0, 1, 1, 0), 6);
|
||||
tst_Xto_int(ary_(3, 2) , ary_(7, 3) , 31);
|
||||
tst_Xto_int(ary_(3, 2, 1) , ary_(7, 3, 1) , 63);
|
||||
tst_Xto_int(ary_(11, 4, 5, 5, 6), ary_(2012, 6, 3, 23, 17), 2110135761);
|
||||
tst_Xto_int(ary_(11, 4, 5, 5, 6), ary_(2012, 6, 3, 23, 18), 2110135762);
|
||||
}
|
||||
private void tst_Xto_int(int[] seg_ary, int[] val_ary, int expd) {
|
||||
int[] pow_ary = Bit_.Bld_pow_ary(seg_ary);
|
||||
Tfds.Eq(expd, Bit_.Xto_int(pow_ary, val_ary));
|
||||
}
|
||||
@Test public void Xto_intAry() {
|
||||
tst_Xto_intAry(ary_(1, 1, 1, 1) , 15, ary_(1, 1, 1, 1));
|
||||
tst_Xto_intAry(ary_(3, 2) , 31, ary_(7, 3));
|
||||
tst_Xto_intAry(ary_(3, 2, 1) , 63, ary_(7, 3, 1));
|
||||
tst_Xto_intAry(ary_(12, 4, 5, 5, 6), 2110135761, ary_(2012, 6, 3, 23, 17));
|
||||
tst_Xto_intAry(ary_(12, 4, 5, 5, 6), 2110135762, ary_(2012, 6, 3, 23, 18));
|
||||
}
|
||||
private void tst_Xto_intAry(int[] seg_ary, int val, int[] expd) {
|
||||
int[] pow_ary = Bit_.Bld_pow_ary(seg_ary);
|
||||
Tfds.Eq_ary_str(expd, Bit_.Xto_intAry(pow_ary, val));
|
||||
}
|
||||
int[] ary_(int... v) {return v;}
|
||||
@Test public void Xto_int_date_short() {
|
||||
tst_Xto_int_date_short("20120604 2359", 117843451);
|
||||
tst_Xto_int_date_short("20120604 2358", 117843450);
|
||||
tst_Xto_int_date_short("20120605 0000", 117843968);
|
||||
}
|
||||
private void tst_Xto_int_date_short(String date_str, int expd) {
|
||||
DateAdp date = DateAdp_.parse_fmt(date_str, "yyyyMMdd HHmm");
|
||||
int date_int = Bit_.Xto_int_date_short(date.XtoSegAry());
|
||||
Tfds.Eq(expd, date_int);
|
||||
Tfds.Eq(date_str, Bit_.Xto_date_short(date_int).XtoStr_fmt("yyyyMMdd HHmm"));
|
||||
}
|
||||
@Test public void Shift_lhs() {// simple: shift 1 bit
|
||||
fxt.Test_shift_lhs(1, 1, 2);
|
||||
fxt.Test_shift_lhs(2, 1, 4);
|
||||
fxt.Test_shift_lhs(3, 1, 6);
|
||||
fxt.Test_shift_lhs(4, 1, 8);
|
||||
}
|
||||
@Test public void Shift_rhs() {
|
||||
fxt.Test_shift_rhs(2, 1, 1);
|
||||
fxt.Test_shift_rhs(4, 1, 2);
|
||||
fxt.Test_shift_rhs(6, 1, 3);
|
||||
fxt.Test_shift_rhs(8, 1, 4);
|
||||
}
|
||||
@Test public void Shift_lhs_to_int() {
|
||||
int[] shift_ary = Int_.Ary(0, 3, 5);
|
||||
fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(0, 0, 0), 0);
|
||||
fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(7, 0, 0), 7); // 1st 3 bits
|
||||
fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(0, 3, 0), 24); // 2nd 2 bits
|
||||
fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(0, 0, 1), 32); // 3rd 1 bit
|
||||
fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(7, 3, 1), 63); // many bits
|
||||
}
|
||||
@Test public void Shift_rhs_to_ary() {
|
||||
int[] shift_ary = Int_.Ary(0, 3, 5);
|
||||
fxt.Test_shift_rhs_to_ary(shift_ary, 0, Int_.Ary(0, 0, 0));
|
||||
fxt.Test_shift_rhs_to_ary(shift_ary, 7, Int_.Ary(7, 0, 0)); // 1st 3 bits
|
||||
fxt.Test_shift_rhs_to_ary(shift_ary, 24, Int_.Ary(0, 3, 0)); // 2nd 2 bits
|
||||
fxt.Test_shift_rhs_to_ary(shift_ary, 32, Int_.Ary(0, 0, 1)); // 3rd 1 bit
|
||||
fxt.Test_shift_rhs_to_ary(shift_ary, 63, Int_.Ary(7, 3, 1)); // many bits
|
||||
}
|
||||
}
|
||||
class Bit__fxt {
|
||||
public void Clear() {}
|
||||
public void Test_shift_lhs(int val, int shift, int expd) {Tfds.Eq(expd, Bit_.Shift_lhs(val, shift));}
|
||||
public void Test_shift_rhs(int val, int shift, int expd) {Tfds.Eq(expd, Bit_.Shift_rhs(val, shift));}
|
||||
public void Test_shift_lhs_to_int(int[] shift_ary, int[] val_ary, int expd) {Tfds.Eq(expd, Bit_.Shift_lhs_to_int(shift_ary, val_ary));}
|
||||
public void Test_shift_rhs_to_ary(int[] shift_ary, int val, int[] expd_ary) {
|
||||
int[] actl_ary = Int_.Ary(0, 0, 0);
|
||||
Bit_.Shift_rhs_to_ary(actl_ary, shift_ary, val);
|
||||
Tfds.Eq_ary(expd_ary, actl_ary);
|
||||
}
|
||||
}
|
||||
40
400_xowa/src/gplx/core/brys/Bry_bldr.java
Normal file
40
400_xowa/src/gplx/core/brys/Bry_bldr.java
Normal file
@@ -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.brys; import gplx.*; import gplx.core.*;
|
||||
public class Bry_bldr {
|
||||
public byte[] Val() {return val;} private byte[] val;
|
||||
public Bry_bldr New_256() {return New(256);}
|
||||
public Bry_bldr New(int len) {val = new byte[len]; return this;}
|
||||
public Bry_bldr Set_rng_ws(byte v) {return Set_many(v, Byte_ascii.Space, Byte_ascii.Tab, Byte_ascii.Nl, Byte_ascii.Cr);}
|
||||
public Bry_bldr Set_rng_xml_identifier(byte v) {return Set_rng_alpha_lc(v).Set_rng_alpha_uc(v).Set_rng_num(v).Set_many(v, Byte_ascii.Underline, Byte_ascii.Dash);}
|
||||
public Bry_bldr Set_rng_alpha(byte v) {return Set_rng_alpha_lc(v).Set_rng_alpha_uc(v);}
|
||||
public Bry_bldr Set_rng_alpha_lc(byte v) {return Set_rng(v, Byte_ascii.Ltr_a, Byte_ascii.Ltr_z);}
|
||||
public Bry_bldr Set_rng_alpha_uc(byte v) {return Set_rng(v, Byte_ascii.Ltr_A, Byte_ascii.Ltr_Z);}
|
||||
public Bry_bldr Set_rng_num(byte v) {return Set_rng(v, Byte_ascii.Num_0, Byte_ascii.Num_9);}
|
||||
public Bry_bldr Set_rng(byte v, int bgn, int end) {
|
||||
for (int i = bgn; i <= end; i++)
|
||||
val[i] = v;
|
||||
return this;
|
||||
}
|
||||
public Bry_bldr Set_many(byte v, int... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
val[ary[i]] = v;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
26
400_xowa/src/gplx/core/brys/Bry_comparer.java
Normal file
26
400_xowa/src/gplx/core/brys/Bry_comparer.java
Normal file
@@ -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.core.brys; import gplx.*; import gplx.core.*;
|
||||
import gplx.lists.*;
|
||||
public class Bry_comparer implements ComparerAble {
|
||||
public int compare(Object lhsObj, Object rhsObj) {
|
||||
byte[] lhs = (byte[])lhsObj, rhs = (byte[])rhsObj;
|
||||
return Bry_.Compare(lhs, 0, lhs.length, rhs, 0, rhs.length);
|
||||
}
|
||||
public static final Bry_comparer _ = new Bry_comparer(); Bry_comparer() {}
|
||||
}
|
||||
56
400_xowa/src/gplx/core/brys/Bry_rdr_tst.java
Normal file
56
400_xowa/src/gplx/core/brys/Bry_rdr_tst.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.brys; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class Bry_rdr_tst {
|
||||
@Before public void init() {fxt.Clear();} private Bry_rdr_fxt fxt = new Bry_rdr_fxt();
|
||||
@Test public void Int() {
|
||||
fxt.Init_src("12|3456|789");
|
||||
fxt.Test_read_int(12);
|
||||
fxt.Test_read_int(3456);
|
||||
fxt.Test_read_int(789);
|
||||
fxt.Test_read_int(Int_.MinValue);
|
||||
}
|
||||
@Test public void Int_negative() {
|
||||
fxt.Init_src("-1|-2");
|
||||
fxt.Test_read_int(-1);
|
||||
fxt.Test_read_int(-2);
|
||||
}
|
||||
@Test public void Bry() {
|
||||
fxt.Init_src("abc|d||ef");
|
||||
fxt.Test_read_bry("abc");
|
||||
fxt.Test_read_bry("d");
|
||||
fxt.Test_read_bry("");
|
||||
fxt.Test_read_bry("ef");
|
||||
fxt.Test_read_bry(null);
|
||||
}
|
||||
}
|
||||
class Bry_rdr_fxt {
|
||||
private Bry_rdr rdr;
|
||||
public void Clear() {rdr = new Bry_rdr();}
|
||||
public Bry_rdr_fxt Init_src(String v) {rdr.Init(Bry_.new_u8(v)); return this;}
|
||||
public Bry_rdr_fxt Init_pos(int v) {rdr.Pos_(v); return this;}
|
||||
public void Test_read_int(int expd_val) {
|
||||
Tfds.Eq(expd_val, rdr.Read_int_to_pipe());
|
||||
}
|
||||
public void Test_read_bry(String expd_str) {
|
||||
byte[] actl_bry = rdr.Read_bry_to_pipe();
|
||||
String actl_str = actl_bry == null ? null : String_.new_u8(actl_bry);
|
||||
Tfds.Eq(expd_str, actl_str);
|
||||
}
|
||||
}
|
||||
96
400_xowa/src/gplx/core/btries/Btrie_utf8_mgr_tst.java
Normal file
96
400_xowa/src/gplx/core/btries/Btrie_utf8_mgr_tst.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
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.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Btrie_utf8_mgr_tst {
|
||||
@Before public void init() {fxt.Clear();} private Btrie_utf8_mgr_fxt fxt = new Btrie_utf8_mgr_fxt();
|
||||
@Test public void Ascii() {
|
||||
fxt.Init_add(Bry_.new_a7("a") , "1");
|
||||
fxt.Init_add(Bry_.new_a7("abc") , "123");
|
||||
fxt.Test_match("a" , "1"); // single.exact
|
||||
fxt.Test_match("abc" , "123"); // many.exact
|
||||
fxt.Test_match("ab" , "1"); // single.more
|
||||
fxt.Test_match("abcde" , "123"); // many.more
|
||||
fxt.Test_match(" a" , null); // no_match
|
||||
fxt.Test_match("aBC" , "123"); // upper
|
||||
}
|
||||
@Test public void Uft8() {
|
||||
fxt.Init_add(Bry_.new_u8("aéi") , "1");
|
||||
fxt.Test_match("aéi" , "1"); // exact
|
||||
fxt.Test_match("aÉi" , "1"); // upper.utf8
|
||||
fxt.Test_match("AÉI" , "1"); // upper.all
|
||||
fxt.Test_match("AÉIo" , "1"); // trailing-char
|
||||
fxt.Test_match("aei" , null); // no_match
|
||||
}
|
||||
@Test public void Uft8_match_pos() {
|
||||
fxt.Init_add(Bry_.new_u8("aéi") , "1");
|
||||
fxt.Test_match_pos("aAÉI" , 1, "1"); // match at 1
|
||||
fxt.Test_match_pos("aAÉI" , 0, null); // no_match at 0
|
||||
}
|
||||
@Test public void Uft8_asymmetric() {
|
||||
fxt.Init_add(Bry_.new_u8("İ") , "1");
|
||||
fxt.Test_match("İ" , "1"); // exact=y; İ = Bry_.ints_(196,176)
|
||||
fxt.Test_match("i" , "1"); // lower=y; i = Bry_.ints_(105)
|
||||
fxt.Test_match("I" , null); // upper=n; I = Bry_.ints_( 73); see Btrie_utf8_itm and rv.asymmetric_bry
|
||||
|
||||
fxt.Clear();
|
||||
fxt.Init_add(Bry_.new_u8("i") , "1");
|
||||
fxt.Test_match("i" , "1"); // exact=y
|
||||
fxt.Test_match("I" , "1"); // upper=y
|
||||
fxt.Test_match("İ" , null); // utf_8=n; note that a trie with "i" doesn't match a src with "İ" even though "İ" lower-cases to "i"
|
||||
}
|
||||
@Test public void Utf8_asymmetric_multiple() { // PURPOSE: problems in original implementation of Hash_adp_bry and uneven source / target counts;
|
||||
fxt.Init_add(Bry_.new_u8("İİ") , "1");
|
||||
fxt.Test_match("İİ" , "1"); // exact
|
||||
fxt.Test_match("ii" , "1"); // lower
|
||||
fxt.Test_match("İi" , "1"); // mixed
|
||||
fxt.Test_match("iİ" , "1"); // mixed
|
||||
}
|
||||
@Test public void Utf8_asymmetric_upper() { // PURPOSE: "İ" and "I" should co-exist; see Btrie_utf8_itm and called_by_match
|
||||
fxt.Init_add(Bry_.new_u8("İ") , "1");
|
||||
fxt.Init_add(Bry_.new_u8("I") , "1");
|
||||
fxt.Test_match("İ" , "1"); // exact
|
||||
fxt.Test_match("I" , "1"); // exact
|
||||
fxt.Test_match("i" , "1"); // lower
|
||||
}
|
||||
@Test public void Utf8_asymmetric_symbols() { // PURPOSE: test Hash_adp_bry and multi-byte syms (chars that will never be cased)
|
||||
fxt.Init_add(Bry_.new_u8("a_b") , "1");
|
||||
fxt.Test_match("a_b" , "1"); // exact: len=3
|
||||
fxt.Test_match("a†b" , null); // diff : len=3
|
||||
fxt.Test_match("a±b" , null); // diff : len=2
|
||||
fxt.Test_match("a_b" , null); // diff : len=1
|
||||
}
|
||||
}
|
||||
class Btrie_utf8_mgr_fxt {
|
||||
private Btrie_utf8_mgr trie;
|
||||
public void Clear() {
|
||||
trie = Btrie_utf8_mgr.new_(Xol_case_mgr_.Utf8());
|
||||
}
|
||||
public void Init_add(byte[] key, Object val) {trie.Add_obj(key, val);}
|
||||
public void Test_match_pos(String src_str, int bgn_pos, String expd) {
|
||||
byte[] src = Bry_.new_u8(src_str);
|
||||
Object actl = trie.Match_bgn_w_byte(src[bgn_pos], src, bgn_pos, src.length);
|
||||
Tfds.Eq(expd, actl, src_str);
|
||||
}
|
||||
public void Test_match(String src_str, String expd) {
|
||||
byte[] src = Bry_.new_u8(src_str);
|
||||
Object actl = trie.Match_bgn_w_byte(src[0], src, 0, src.length);
|
||||
Tfds.Eq(expd, actl, src_str);
|
||||
}
|
||||
}
|
||||
54
400_xowa/src/gplx/core/enums/Gfo_enum_grp.java
Normal file
54
400_xowa/src/gplx/core/enums/Gfo_enum_grp.java
Normal file
@@ -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.core.enums; import gplx.*; import gplx.core.*;
|
||||
class Gfo_enum_grp {
|
||||
// private Ordered_hash itms = Ordered_hash_.new_();
|
||||
public Gfo_enum_grp(Guid_adp uid, String key, int id, String name, int sort, String xtn) {
|
||||
this.uid = uid; this.key = key; this.id = id; this.name = name; this.sort = sort; this.xtn = xtn;
|
||||
}
|
||||
public Guid_adp Uid() {return uid;} private Guid_adp uid;
|
||||
public String Key() {return key;} private String key;
|
||||
public int Id() {return id;} private int id;
|
||||
public String Name() {return name;} private String name;
|
||||
public int Sort() {return sort;} private int sort;
|
||||
public String Xtn() {return xtn;} private String xtn;
|
||||
}
|
||||
class Gfo_enum_itm {
|
||||
public Gfo_enum_itm(Guid_adp uid, String key, int id, String name, int sort, String xtn) {
|
||||
this.uid = uid; this.key = key; this.id = id; this.name = name; this.sort = sort; this.xtn = xtn;
|
||||
}
|
||||
public Guid_adp Uid() {return uid;} private Guid_adp uid;
|
||||
public String Key() {return key;} private String key;
|
||||
public int Id() {return id;} private int id;
|
||||
public String Name() {return name;} private String name;
|
||||
public int Sort() {return sort;} private int sort;
|
||||
public String Xtn() {return xtn;} private String xtn;
|
||||
}
|
||||
/*
|
||||
enum_grps
|
||||
grp_guid,grp_key,grp_int,grp_name,grp_sort,grp_xtn
|
||||
0-1-2-3,xowa.wiki,0,wiki,,
|
||||
|
||||
enum_itms
|
||||
grp_int,itm_guid,itm_key,itm_int,itm_name,itm_sort,itm_xtn
|
||||
1,0-1-2-3,0,en.wikipedia.org,0,enwiki,0,''
|
||||
|
||||
class Gfo_enum_mgr {
|
||||
// public Gui
|
||||
}
|
||||
*/
|
||||
48
400_xowa/src/gplx/core/flds/Gfo_fld_base.java
Normal file
48
400_xowa/src/gplx/core/flds/Gfo_fld_base.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.flds; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_fld_base {
|
||||
public byte Row_dlm() {return row_dlm;} public Gfo_fld_base Row_dlm_(byte v) {row_dlm = v; return this;} protected byte row_dlm = Byte_ascii.Nl;
|
||||
public byte Fld_dlm() {return fld_dlm;} public Gfo_fld_base Fld_dlm_(byte v) {fld_dlm = v; return this;} protected byte fld_dlm = Byte_ascii.Pipe;
|
||||
public byte Escape_dlm() {return escape_dlm;} public Gfo_fld_base Escape_dlm_(byte v) {escape_dlm = v; return this;} protected byte escape_dlm = Byte_ascii.Tilde;
|
||||
public byte Quote_dlm() {return quote_dlm;} public Gfo_fld_base Quote_dlm_(byte v) {quote_dlm = v; return this;} protected byte quote_dlm = Byte_ascii.Nil;
|
||||
public Gfo_fld_base Escape_reg(byte b) {return Escape_reg(b, b);}
|
||||
public byte[] Escape_decode() {return decode_regy;}
|
||||
public Gfo_fld_base Escape_reg(byte key, byte val) {encode_regy[key] = val; decode_regy[val] = key; return this;} protected byte[] decode_regy = new byte[256]; protected byte[] encode_regy = new byte[256];
|
||||
public Gfo_fld_base Escape_clear() {
|
||||
for (int i = 0; i < 256; i++)
|
||||
decode_regy[i] = Byte_ascii.Nil;
|
||||
for (int i = 0; i < 256; i++)
|
||||
encode_regy[i] = Byte_ascii.Nil;
|
||||
return this;
|
||||
}
|
||||
Gfo_fld_base Ini_common() {
|
||||
return Escape_reg(Byte_ascii.Nl, Byte_ascii.Ltr_n).Escape_reg(Byte_ascii.Tab, Byte_ascii.Ltr_t).Escape_reg(Byte_ascii.Cr, Byte_ascii.Ltr_r)
|
||||
.Escape_reg(Byte_ascii.Backfeed, Byte_ascii.Ltr_b); // .Escape_reg(Byte_ascii.Nil, Byte_ascii.Num_0)
|
||||
}
|
||||
protected Gfo_fld_base Ctor_xdat_base() {
|
||||
return Escape_clear().Ini_common()
|
||||
.Fld_dlm_(Byte_ascii.Pipe).Row_dlm_(Byte_ascii.Nl).Escape_dlm_(Byte_ascii.Tilde).Quote_dlm_(Byte_ascii.Nil)
|
||||
.Escape_reg(Byte_ascii.Pipe, Byte_ascii.Ltr_p).Escape_reg(Byte_ascii.Tilde);
|
||||
}
|
||||
protected Gfo_fld_base Ctor_sql_base() {
|
||||
return Escape_clear().Ini_common()
|
||||
.Fld_dlm_(Byte_ascii.Comma).Row_dlm_(Byte_ascii.Paren_end).Escape_dlm_(Byte_ascii.Backslash).Quote_dlm_(Byte_ascii.Apos)
|
||||
.Escape_reg(Byte_ascii.Backslash).Escape_reg(Byte_ascii.Quote).Escape_reg(Byte_ascii.Apos); // , Escape_eof = Bry_.new_u8("\\Z")
|
||||
}
|
||||
}
|
||||
124
400_xowa/src/gplx/core/flds/Gfo_fld_rdr.java
Normal file
124
400_xowa/src/gplx/core/flds/Gfo_fld_rdr.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.flds; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_fld_rdr extends Gfo_fld_base {
|
||||
private Bry_bfr bfr = Bry_bfr.new_(); private static final byte[] Bry_nil = Bry_.new_a7("\\0");
|
||||
public byte[] Data() {return data;} public Gfo_fld_rdr Data_(byte[] v) {data = v; data_len = v.length; pos = 0; return this;} private byte[] data; int data_len;
|
||||
public int Pos() {return pos;} public Gfo_fld_rdr Pos_(int v) {pos = v; return this;} private int pos;
|
||||
public int Fld_bgn() {return fld_bgn;} public Gfo_fld_rdr Fld_bgn_(int v) {fld_bgn = v; return this;} private int fld_bgn;
|
||||
public int Fld_end() {return fld_end;} public Gfo_fld_rdr Fld_end_(int v) {fld_end = v; return this;} private int fld_end;
|
||||
public int Fld_idx() {return fld_idx;} private int fld_idx;
|
||||
public int Row_idx() {return row_idx;} private int row_idx;
|
||||
public void Ini(byte[] data, int pos) {this.data = data; this.data_len = data.length; this.pos = pos;}
|
||||
|
||||
public String Read_str_simple() {Move_next_simple(); return String_.new_u8(data, fld_bgn, fld_end);}
|
||||
public byte[] Read_bry_simple() {Move_next_simple(); return Bry_.Mid(data, fld_bgn, fld_end);} // was Mid_by_len???; 20120915
|
||||
public int Read_int_base85_lenN(int len) {fld_bgn = pos; fld_end = pos + len - 1 ; pos = pos + len + 1 ; return Base85_utl.XtoIntByAry(data, fld_bgn, fld_end);}
|
||||
public int Read_int_base85_len5() {fld_bgn = pos; fld_end = pos + 4 ; pos = pos + 6 ; return Base85_utl.XtoIntByAry(data, fld_bgn, fld_end);}
|
||||
public int Read_int() {Move_next_simple(); return Bry_.Xto_int_or(data, fld_bgn, fld_end, -1);}
|
||||
public byte Read_int_as_byte() {Move_next_simple(); return (byte)Bry_.Xto_int_or(data, fld_bgn, fld_end, -1);}
|
||||
public byte Read_byte() {Move_next_simple(); return data[fld_bgn];}
|
||||
public double Read_double() {Move_next_simple(); return Bry_.XtoDoubleByPos(data, fld_bgn, fld_end);}
|
||||
public DateAdp Read_dte() {// NOTE: fmt = yyyyMMdd HHmmss.fff
|
||||
int y = 0, M = 0, d = 0, H = 0, m = 0, s = 0, f = 0;
|
||||
if (pos < data_len && data[pos] == row_dlm) {++pos; ++row_idx; fld_idx = 0;} fld_bgn = pos;
|
||||
y += (data[fld_bgn + 0] - Byte_ascii.Num_0) * 1000;
|
||||
y += (data[fld_bgn + 1] - Byte_ascii.Num_0) * 100;
|
||||
y += (data[fld_bgn + 2] - Byte_ascii.Num_0) * 10;
|
||||
y += (data[fld_bgn + 3] - Byte_ascii.Num_0);
|
||||
M += (data[fld_bgn + 4] - Byte_ascii.Num_0) * 10;
|
||||
M += (data[fld_bgn + 5] - Byte_ascii.Num_0);
|
||||
d += (data[fld_bgn + 6] - Byte_ascii.Num_0) * 10;
|
||||
d += (data[fld_bgn + 7] - Byte_ascii.Num_0);
|
||||
H += (data[fld_bgn + 9] - Byte_ascii.Num_0) * 10;
|
||||
H += (data[fld_bgn + 10] - Byte_ascii.Num_0);
|
||||
m += (data[fld_bgn + 11] - Byte_ascii.Num_0) * 10;
|
||||
m += (data[fld_bgn + 12] - Byte_ascii.Num_0);
|
||||
s += (data[fld_bgn + 13] - Byte_ascii.Num_0) * 10;
|
||||
s += (data[fld_bgn + 14] - Byte_ascii.Num_0);
|
||||
f += (data[fld_bgn + 16] - Byte_ascii.Num_0) * 100;
|
||||
f += (data[fld_bgn + 17] - Byte_ascii.Num_0) * 10;
|
||||
f += (data[fld_bgn + 18] - Byte_ascii.Num_0);
|
||||
if (data[fld_bgn + 19] != fld_dlm) throw Exc_.new_("csv date is invalid", "txt", String_.new_u8_by_len(data, fld_bgn, 20));
|
||||
fld_end = pos + 20;
|
||||
pos = fld_end + 1; ++fld_idx;
|
||||
return DateAdp_.new_(y, M, d, H, m, s, f);
|
||||
}
|
||||
public void Move_next_simple() {
|
||||
if (pos < data_len) {
|
||||
byte b_cur = data[pos];
|
||||
if (b_cur == row_dlm) {
|
||||
fld_bgn = fld_end = pos;
|
||||
++pos; ++row_idx;
|
||||
fld_idx = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fld_bgn = pos;
|
||||
if (fld_bgn == data_len) {fld_end = data_len; return;}
|
||||
for (int i = fld_bgn; i < data_len; i++) {
|
||||
byte b = data[i];
|
||||
if (b == fld_dlm || b == row_dlm) {
|
||||
fld_end = i; pos = i + 1; ++fld_idx; // position after dlm
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw Exc_.new_("fld_dlm failed", "fld_dlm", (char)fld_dlm, "bgn", fld_bgn);
|
||||
}
|
||||
public String Read_str_escape() {Move_next_escaped(bfr); return String_.new_u8(bfr.Xto_bry_and_clear());}
|
||||
public byte[] Read_bry_escape() {Move_next_escaped(bfr); return bfr.Xto_bry_and_clear();}
|
||||
public void Move_1() {++pos;}
|
||||
public void Move_next_escaped() {Move_next_escaped(bfr); bfr.Clear();}
|
||||
public int Move_next_simple_fld() {
|
||||
Move_next_simple();
|
||||
return fld_end;
|
||||
}
|
||||
public int Move_next_escaped(Bry_bfr trg) {
|
||||
//if (pos < data_len && data[pos] == row_dlm) {++pos; ++row_idx; fld_idx = 0;} // REMOVE:20120919: this will fail for empty fields at end of line; EX: "a|\n"; intent was probably to auto-advance to new row, but this intent should be explicit
|
||||
fld_bgn = pos;
|
||||
boolean quote_on = false;
|
||||
for (int i = fld_bgn; i < data_len; i++) {
|
||||
byte b = data[i];
|
||||
if ((b == fld_dlm || b == row_dlm) && !quote_on) {
|
||||
fld_end = i; pos = i + 1; ++fld_idx; // position after dlm
|
||||
return pos;
|
||||
}
|
||||
else if (b == escape_dlm) {
|
||||
++i;
|
||||
// if (i == data_len) throw Err_.new_("escape char at end of String");
|
||||
b = data[i];
|
||||
byte escape_val = decode_regy[b];
|
||||
if (escape_val == Byte_ascii.Nil) {trg.Add_byte(escape_dlm).Add_byte(b);} //throw Err_.new_fmt_("unknown escape key: key={0}", data[i]);
|
||||
else trg.Add_byte(escape_val);
|
||||
}
|
||||
else if (b == Byte_ascii.Nil) {
|
||||
trg.Add(Bry_nil);
|
||||
}
|
||||
else if (b == quote_dlm) {
|
||||
quote_on = !quote_on;
|
||||
}
|
||||
else
|
||||
trg.Add_byte(b);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public Gfo_fld_rdr Ctor_xdat() {return (Gfo_fld_rdr)super.Ctor_xdat_base();}
|
||||
public Gfo_fld_rdr Ctor_sql() {return (Gfo_fld_rdr)super.Ctor_sql_base();}
|
||||
public static Gfo_fld_rdr xowa_() {return new Gfo_fld_rdr().Ctor_xdat();}
|
||||
public static Gfo_fld_rdr sql_() {return new Gfo_fld_rdr().Ctor_sql();}
|
||||
}
|
||||
56
400_xowa/src/gplx/core/flds/Gfo_fld_rdr_tst.java
Normal file
56
400_xowa/src/gplx/core/flds/Gfo_fld_rdr_tst.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.flds; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
import gplx.ios.*;
|
||||
public class Gfo_fld_rdr_tst {
|
||||
Gfo_fld_rdr_fxt fxt = new Gfo_fld_rdr_fxt();
|
||||
@Test public void Read_int() {fxt.ini_xdat().Raw_("123|") .tst_Read_int(123);}
|
||||
@Test public void Read_double() {fxt.ini_xdat().Raw_("1.23|") .tst_Read_double(1.23);}
|
||||
@Test public void Read_str_simple() {fxt.ini_xdat().Raw_("ab|") .tst_Read_str_simple("ab");}
|
||||
@Test public void Read_str_escape_pipe() {fxt.ini_xdat().Raw_("a~pb|") .tst_Read_str_escape("a|b");}
|
||||
@Test public void Read_str_escape_tilde() {fxt.ini_xdat().Raw_("a~~b|") .tst_Read_str_escape("a~b");}
|
||||
@Test public void Read_str_escape_nl() {fxt.ini_xdat().Raw_("a~nb|") .tst_Read_str_escape("a\nb");}
|
||||
@Test public void Read_str_escape_tab() {fxt.ini_xdat().Raw_("a~tb|") .tst_Read_str_escape("a\tb");}
|
||||
@Test public void Write_str_escape_pipe() {fxt.ini_xdat().tst_Write_str_escape("a|b", "a~pb|");}
|
||||
@Test public void Read_str_quoted_comma() {fxt.ini_sql ().Raw_("'a,b',") .tst_Read_str_escape("a,b");}
|
||||
@Test public void Read_str_quoted_apos() {fxt.ini_sql ().Raw_("'a\\'b',") .tst_Read_str_escape("a'b");}
|
||||
@Test public void Read_multiple() {
|
||||
fxt.ini_xdat().Raw_("ab|1|.9|\n")
|
||||
.tst_Read_str_escape("ab").tst_Read_int(1).tst_Read_double(.9)
|
||||
;
|
||||
}
|
||||
@Test public void Read_dlm_nl() {fxt.ini_xdat().Raw_("123\n") .tst_Read_int(123);}
|
||||
}
|
||||
class Gfo_fld_rdr_fxt {
|
||||
Gfo_fld_rdr rdr = new Gfo_fld_rdr(); Gfo_fld_wtr wtr = Gfo_fld_wtr.xowa_();
|
||||
public Gfo_fld_rdr_fxt Raw_(String v) {rdr.Data_(Bry_.new_u8(v)); return this;}
|
||||
public Gfo_fld_rdr_fxt ini_xdat() {rdr.Ctor_xdat(); return this;}
|
||||
public Gfo_fld_rdr_fxt ini_sql() {rdr.Ctor_sql(); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_int(int expd) {Tfds.Eq(expd, rdr.Read_int()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_double(double expd) {Tfds.Eq(expd, rdr.Read_double()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_str_simple(String expd) {Tfds.Eq(expd, rdr.Read_str_simple()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Read_str_escape(String expd) {Tfds.Eq(expd, rdr.Read_str_escape()); return this;}
|
||||
public Gfo_fld_rdr_fxt tst_Write_str_escape(String val, String expd) {
|
||||
byte[] bry = Bry_.new_u8(val);
|
||||
wtr.Bfr_(bfr);
|
||||
wtr.Write_bry_escape_fld(bry);
|
||||
Tfds.Eq(expd, bfr.Xto_str());
|
||||
return this;
|
||||
} private Bry_bfr bfr = Bry_bfr.new_();
|
||||
}
|
||||
59
400_xowa/src/gplx/core/flds/Gfo_fld_wtr.java
Normal file
59
400_xowa/src/gplx/core/flds/Gfo_fld_wtr.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.flds; import gplx.*; import gplx.core.*;
|
||||
import gplx.ios.*;
|
||||
public class Gfo_fld_wtr extends Gfo_fld_base {
|
||||
public Bry_bfr Bfr() {return bfr;} public Gfo_fld_wtr Bfr_(Bry_bfr v) {bfr = v; return this;} Bry_bfr bfr;
|
||||
public Gfo_fld_wtr() {this.bfr = Bry_bfr.new_();}
|
||||
public Gfo_fld_wtr Write_int_base85_len5_fld(int v) {bfr.Add_base85(v, Base85_utl.Len_int); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_base85_lenN_fld(int v, int len) {bfr.Add_base85(v, len); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_variable_fld(int v) {bfr.Add_int_variable(v); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_fixed_fld(int v, int len) {bfr.Add_int_fixed(v, len); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_double_fld(double v) {bfr.Add_double(v); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_byte_fld(byte v) {bfr.Add_byte(v); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_fld(byte[] val) {Write_bry_escape(val, 0, val.length); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_fld(byte[] val, int bgn, int end) {Write_bry_escape(val, bgn, end); bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_dlm_row() { bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_dlm_fld() { bfr.Add_byte(fld_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_base85_lenN_row(int v, int len) {bfr.Add_base85(v, len); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_int_base85_len5_row(int v) {bfr.Add_base85(v, Base85_utl.Len_int); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_row(byte[] val) {Write_bry_escape(val, 0, val.length); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_bry_escape_row(byte[] val, int bgn, int end) {Write_bry_escape(val, bgn, end); bfr.Add_byte(row_dlm); return this;}
|
||||
public Gfo_fld_wtr Write_double_row(double v) {bfr.Add_double(v); bfr.Add_byte(row_dlm); return this;}
|
||||
Gfo_fld_wtr Write_bry_escape(byte[] val, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = val[i];
|
||||
byte escape_val = encode_regy[b & 0xFF]; // PATCH.JAVA:need to convert to unsigned byte
|
||||
if (escape_val == Byte_ascii.Nil) bfr.Add_byte(b);
|
||||
else {bfr.Add_byte(escape_dlm); bfr.Add_byte(escape_val);}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Gfo_fld_wtr Rls() {bfr.Rls(); return this;}
|
||||
|
||||
public Io_url_gen Fil_gen() {return fil_gen;} public Gfo_fld_wtr Fil_gen_(Io_url_gen v) {fil_gen = v; return this;} Io_url_gen fil_gen;
|
||||
public int Bfr_max() {return bfr_max;} public Gfo_fld_wtr Bfr_max_(int v) {bfr_max = v; return this;} private int bfr_max = Io_mgr.Len_mb;
|
||||
public boolean Flush_needed(int v) {return bfr.Len() + v > bfr_max;}
|
||||
public void Flush() {
|
||||
if (Fil_gen().Cur_url() == null) fil_gen.Nxt_url();
|
||||
Io_mgr.I.AppendFilBfr(fil_gen.Cur_url(), bfr);
|
||||
}
|
||||
public void Flush_nxt() {Flush(); fil_gen.Nxt_url();}
|
||||
public Gfo_fld_wtr Ctor_xdat() {return (Gfo_fld_wtr)super.Ctor_xdat_base();}
|
||||
public static Gfo_fld_wtr xowa_() {return new Gfo_fld_wtr().Ctor_xdat();}
|
||||
}
|
||||
24
400_xowa/src/gplx/core/html/parsers/Gfo_html_node.java
Normal file
24
400_xowa/src/gplx/core/html/parsers/Gfo_html_node.java
Normal file
@@ -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.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*;
|
||||
class Gfo_html_node {
|
||||
public Gfo_html_node(byte[] src, int bgn, int end) {this.src = src; this.bgn = bgn; this.end = end;}
|
||||
public byte[] Src() {return src;} private final byte[] src;
|
||||
public int Bgn() {return bgn;} private final int bgn;
|
||||
public int End() {return end;} private final int end;
|
||||
}
|
||||
68
400_xowa/src/gplx/core/html/parsers/Gfo_html_parser.java
Normal file
68
400_xowa/src/gplx/core/html/parsers/Gfo_html_parser.java
Normal file
@@ -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.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*;
|
||||
import gplx.core.btries.*; import gplx.core.primitives.*;
|
||||
import gplx.xowa.*;
|
||||
class Gfo_html_parser {
|
||||
private final Gfo_msg_log msg_log = Gfo_msg_log.Test();
|
||||
private final Xop_xatr_parser xatr_parser = new Xop_xatr_parser();
|
||||
public void Parse(Gfo_html_wkr handler, byte[] src, int bgn, int end) {
|
||||
// int src_len = src.length;
|
||||
// int prv_pos = 0;
|
||||
// int css_find_bgn_len = Css_find_bgn.length;
|
||||
// byte[] protocol_prefix_bry = Bry_.new_u8(protocol_prefix);
|
||||
// while (true) {
|
||||
// int url_bgn = Bry_finder.Find_fwd(src, Css_find_bgn, prv_pos); if (url_bgn == Bry_.NotFound) break; // nothing left; stop
|
||||
// url_bgn += css_find_bgn_len;
|
||||
// int url_end = Bry_finder.Find_fwd(src, Byte_ascii.Quote, url_bgn, src_len); if (url_end == Bry_.NotFound) {usr_dlg.Warn_many("", "main_page.css_parse", "could not find css; pos='~{0}' text='~{1}'", url_bgn, String_.new_u8_by_len(src, url_bgn, url_bgn + 32)); break;}
|
||||
// byte[] css_url_bry = Bry_.Mid(src, url_bgn, url_end);
|
||||
// css_url_bry = Bry_.Replace(css_url_bry, Css_amp_find, Css_amp_repl); // & -> &
|
||||
// css_url_bry = url_encoder.Decode(css_url_bry); // %2C -> %7C -> |
|
||||
// css_url_bry = Bry_.Add(protocol_prefix_bry, css_url_bry);
|
||||
// rv.Add(String_.new_u8(css_url_bry));
|
||||
// prv_pos = url_end;
|
||||
// }
|
||||
// return rv.XtoStrAry();
|
||||
int src_len = src.length; int pos = 0;
|
||||
while (pos < src_len) {
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Angle_bgn:
|
||||
pos = Parse_node(handler, src, end, pos, pos + 1);
|
||||
break;
|
||||
default:
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private int Parse_node(Gfo_html_wkr handler, byte[] src, int end, int tkn_bgn, int tkn_end) {
|
||||
int name_bgn = tkn_end;
|
||||
int name_end = Bry_finder.Find_fwd_until_ws(src, name_bgn, end);
|
||||
if (name_end == Bry_finder.Not_found) return end; // EOS; EX: "<abcEOS"
|
||||
if (name_bgn == name_end) return tkn_end; // ws; EX: "< "
|
||||
Object o = handler.Get_or_null(src, name_bgn, name_end);
|
||||
if (o == null) return name_end; // unknown name: EX: "<unknown >"
|
||||
int node_end = Bry_finder.Find_fwd(src, Byte_ascii.Angle_end, name_end, end);
|
||||
if (node_end == Bry_finder.Not_found) return end; // EOS; EX: "<name lots_of_text_but_no_gt EOS"
|
||||
Xop_xatr_itm[] xatr_ary = xatr_parser.Parse(msg_log, src, name_end, node_end);
|
||||
Gfo_html_tkn tkn = (Gfo_html_tkn)o;
|
||||
tkn.Process(src, Xop_xatr_hash.new_ary(src, xatr_ary));
|
||||
return node_end;
|
||||
}
|
||||
}
|
||||
22
400_xowa/src/gplx/core/html/parsers/Gfo_html_wkr.java
Normal file
22
400_xowa/src/gplx/core/html/parsers/Gfo_html_wkr.java
Normal file
@@ -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.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*;
|
||||
interface Gfo_html_wkr {
|
||||
Gfo_html_tkn Get_or_null(byte[] src, int bgn, int end);
|
||||
void Process(Gfo_html_node node);
|
||||
}
|
||||
33
400_xowa/src/gplx/core/html/parsers/Xob_html_tkn.java
Normal file
33
400_xowa/src/gplx/core/html/parsers/Xob_html_tkn.java
Normal file
@@ -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.core.html.parsers; import gplx.*; import gplx.core.*; import gplx.core.html.*;
|
||||
import gplx.xowa.*;
|
||||
interface Gfo_html_tkn {
|
||||
int Tid();
|
||||
byte[] Key();
|
||||
void Process(byte[] src, Xop_xatr_hash hash);
|
||||
}
|
||||
class Gfo_html_tkn_ {
|
||||
public static final int Tid_link = 1;
|
||||
public static final byte[] Key_link = Bry_.new_a7("link");
|
||||
}
|
||||
class Gfo_html_tkn__link implements Gfo_html_tkn {
|
||||
public int Tid() {return Gfo_html_tkn_.Tid_link;}
|
||||
public byte[] Key() {return Gfo_html_tkn_.Key_link;}
|
||||
@gplx.Virtual public void Process(byte[] src, Xop_xatr_hash hash) {}
|
||||
}
|
||||
23
400_xowa/src/gplx/core/ints/Int_ary_bldr.java
Normal file
23
400_xowa/src/gplx/core/ints/Int_ary_bldr.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.ints; import gplx.*; import gplx.core.*;
|
||||
public class Int_ary_bldr {
|
||||
public Int_ary_bldr(int len) {ary = new int[len];}
|
||||
public Int_ary_bldr Set(int idx, int val) {ary[idx] = val; return this;}
|
||||
public int[] Xto_int_ary() {return ary;} private int[] ary;
|
||||
}
|
||||
52
400_xowa/src/gplx/core/lists/Binary_search_.java
Normal file
52
400_xowa/src/gplx/core/lists/Binary_search_.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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.lists; import gplx.*; import gplx.core.*;
|
||||
public class Binary_search_ {
|
||||
public static int Search(CompareAble[] ary, int ary_len, CompareAble val) {
|
||||
if (ary_len == 1) return 0;
|
||||
int interval = ary_len / 2;
|
||||
int pos = interval - List_adp_.Base1;
|
||||
int pos_last = ary_len - 1;
|
||||
int pos_prv = -1;
|
||||
int loop_count = 0;
|
||||
while (loop_count++ < 32) { // 32 bit integer
|
||||
CompareAble lo = ary[pos];
|
||||
CompareAble hi = pos + 1 == ary_len ? null : ary[pos + 1];
|
||||
int adj = 0;
|
||||
int lo_comp = val.compareTo(lo);
|
||||
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
|
||||
adj = -1;
|
||||
else {
|
||||
if (hi == null) return pos; // hi is null when at last slot in ary
|
||||
int hi_comp = val.compareTo(hi);
|
||||
if (hi_comp == CompareAble_.More) // val is > hi; search slots above
|
||||
adj = 1;
|
||||
else
|
||||
return pos; // val is > lo and < hi; return slot
|
||||
}
|
||||
interval /= 2;
|
||||
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
|
||||
pos += (interval * adj);
|
||||
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
|
||||
if (pos < 0) pos = 0;
|
||||
else if (pos > pos_last) pos = pos_last;
|
||||
pos_prv = pos;
|
||||
}
|
||||
return Int_.MinValue; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
|
||||
}
|
||||
}
|
||||
47
400_xowa/src/gplx/core/lists/Binary_search__tst.java
Normal file
47
400_xowa/src/gplx/core/lists/Binary_search__tst.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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.lists; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.primitives.*;
|
||||
public class Binary_search__tst {
|
||||
private Binary_search__fxt fxt = new Binary_search__fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Init_ary("", "e", "j", "o", "t", "y");
|
||||
fxt.Test_binary_search("a", 0);
|
||||
fxt.Test_binary_search("f", 1);
|
||||
fxt.Test_binary_search("k", 2);
|
||||
fxt.Test_binary_search("p", 3);
|
||||
fxt.Test_binary_search("u", 4);
|
||||
fxt.Test_binary_search("z", 5);
|
||||
}
|
||||
@Test public void One() {
|
||||
fxt.Init_ary("");
|
||||
fxt.Test_binary_search("a", 0);
|
||||
}
|
||||
}
|
||||
class Binary_search__fxt {
|
||||
public void Init_ary(String... v) {
|
||||
int ary_len = v.length;
|
||||
ary = new String_obj_val[ary_len];
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i] = String_obj_val.new_(v[i]);
|
||||
} private String_obj_val[] ary;
|
||||
public void Test_binary_search(String val, int expd) {
|
||||
int actl = Binary_search_.Search(ary, ary.length, String_obj_val.new_(val));
|
||||
Tfds.Eq(expd, actl, val);
|
||||
}
|
||||
}
|
||||
24
400_xowa/src/gplx/core/net/Http_client_rdr.java
Normal file
24
400_xowa/src/gplx/core/net/Http_client_rdr.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
public interface Http_client_rdr {
|
||||
void Stream_(Object o);
|
||||
String Read_line();
|
||||
byte[] Read_line_as_bry();
|
||||
void Rls();
|
||||
}
|
||||
35
400_xowa/src/gplx/core/net/Http_client_rdr_.java
Normal file
35
400_xowa/src/gplx/core/net/Http_client_rdr_.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_client_rdr_ {
|
||||
public static Http_client_rdr new_stream() {return new Http_client_rdr__stream();}
|
||||
public static Http_client_rdr new_mem() {return new Http_client_rdr__mem();}
|
||||
}
|
||||
class Http_client_rdr__mem implements Http_client_rdr {
|
||||
private String[] ary; private int ary_len; private int idx;
|
||||
public void Stream_(Object o) {
|
||||
this.ary = (String[])o;
|
||||
this.ary_len = ary.length;
|
||||
this.idx = 0;
|
||||
}
|
||||
public String Read_line() {
|
||||
return idx == ary_len ? null : ary[idx++];
|
||||
}
|
||||
public byte[] Read_line_as_bry() {return Bry_.new_u8(Read_line());}
|
||||
public void Rls() {}
|
||||
}
|
||||
34
400_xowa/src/gplx/core/net/Http_client_rdr__stream.java
Normal file
34
400_xowa/src/gplx/core/net/Http_client_rdr__stream.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
import java.io.*;
|
||||
class Http_client_rdr__stream implements Http_client_rdr {
|
||||
private BufferedReader br;
|
||||
public void Stream_(Object o) {
|
||||
this.br = new BufferedReader(new InputStreamReader((InputStream)o, java.nio.charset.Charset.forName("UTF-8")));
|
||||
}
|
||||
public String Read_line() {
|
||||
try {return br.readLine();}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Read_line failed");}
|
||||
}
|
||||
public byte[] Read_line_as_bry() {return Bry_.new_u8(Read_line());}
|
||||
public void Rls() {
|
||||
try {br.close();}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Rls failed");}
|
||||
}
|
||||
}
|
||||
27
400_xowa/src/gplx/core/net/Http_client_wtr.java
Normal file
27
400_xowa/src/gplx/core/net/Http_client_wtr.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
import gplx.ios.*;
|
||||
public interface Http_client_wtr {
|
||||
void Stream_(Object o);
|
||||
void Write_bry(byte[] bry);
|
||||
void Write_str(String s);
|
||||
void Write_mid(byte[] bry, int bgn, int end);
|
||||
void Write_stream(Io_stream_rdr stream_rdr);
|
||||
void Rls();
|
||||
}
|
||||
21
400_xowa/src/gplx/core/net/Http_client_wtr_.java
Normal file
21
400_xowa/src/gplx/core/net/Http_client_wtr_.java
Normal file
@@ -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.core.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_client_wtr_ {
|
||||
public static Http_client_wtr new_stream() {return new Http_client_wtr__stream();}
|
||||
}
|
||||
53
400_xowa/src/gplx/core/net/Http_client_wtr__stream.java
Normal file
53
400_xowa/src/gplx/core/net/Http_client_wtr__stream.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
import gplx.ios.*;
|
||||
import java.io.*;
|
||||
class Http_client_wtr__stream implements Http_client_wtr {
|
||||
private final byte[] tmp_stream_bry = new byte[1024];
|
||||
private DataOutputStream stream;
|
||||
public void Stream_(Object o) {
|
||||
this.stream = new DataOutputStream((OutputStream)o);
|
||||
}
|
||||
public void Write_bry(byte[] bry) {
|
||||
try {stream.write(bry);}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Write_bry failed");}
|
||||
}
|
||||
public void Write_str(String s) {
|
||||
try {stream.writeBytes(s);}
|
||||
catch (Exception e) {throw Exc_.new_exc(e, "net", "Write_str failed");}
|
||||
}
|
||||
public void Write_mid(byte[] bry, int bgn, int end) {
|
||||
try {stream.write(bry, bgn, end - bgn);}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Write_mid failed");}
|
||||
}
|
||||
public void Write_stream(Io_stream_rdr stream_rdr) {
|
||||
synchronized (tmp_stream_bry) {
|
||||
int read = 0;
|
||||
while (true) {
|
||||
read = stream_rdr.Read(tmp_stream_bry, 0, 1024);
|
||||
if (read == -1) break;
|
||||
Write_mid(tmp_stream_bry, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Rls() {
|
||||
try {stream.close();}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Rls failed");}
|
||||
}
|
||||
}
|
||||
27
400_xowa/src/gplx/core/net/Http_post_data_hash.java
Normal file
27
400_xowa/src/gplx/core/net/Http_post_data_hash.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_post_data_hash {
|
||||
private final Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
public int Len() {return hash.Count();}
|
||||
public Http_post_data_itm Get_at(int i) {return (Http_post_data_itm)hash.Get_at(i);}
|
||||
public Http_post_data_itm Get_by(byte[] k) {return (Http_post_data_itm)hash.Get_by(k);}
|
||||
public void Add(byte[] key, byte[] val) {
|
||||
hash.Add(key, new Http_post_data_itm(key, val));
|
||||
}
|
||||
}
|
||||
23
400_xowa/src/gplx/core/net/Http_post_data_itm.java
Normal file
23
400_xowa/src/gplx/core/net/Http_post_data_itm.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_post_data_itm {
|
||||
public Http_post_data_itm(byte[] key, byte[] val) {this.key = key; this.val = val;}
|
||||
public byte[] Key() {return key;} private final byte[] key;
|
||||
public byte[] Val() {return val;} private final byte[] val;
|
||||
}
|
||||
81
400_xowa/src/gplx/core/net/Http_request_itm.java
Normal file
81
400_xowa/src/gplx/core/net/Http_request_itm.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
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.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_request_itm {
|
||||
public Http_request_itm(int type, byte[] url, byte[] protocol, byte[] host, byte[] user_agent
|
||||
, byte[] accept, byte[] accept_language, byte[] accept_encoding, boolean dnt, byte[] x_requested_with, byte[] cookie, byte[] referer
|
||||
, int content_length, byte[] content_type, byte[] content_type_boundary
|
||||
, byte[] connection, byte[] pragma, byte[] cache_control
|
||||
, Http_post_data_hash post_data_hash
|
||||
) {
|
||||
this.type = type; this.url = url; this.protocol = protocol; this.host = host; this.user_agent = user_agent;
|
||||
this.accept = accept; this.accept_language = accept_language; this.accept_encoding = accept_encoding; this.dnt = dnt; this.x_requested_with = x_requested_with; this.cookie = cookie; this.referer = referer;
|
||||
this.content_length = content_length; this.content_type = content_type; this.content_type_boundary = content_type_boundary;
|
||||
this.connection = connection; this.pragma = pragma; this.cache_control = cache_control;
|
||||
this.post_data_hash = post_data_hash;
|
||||
}
|
||||
public int Type() {return type;} private final int type;
|
||||
public byte[] Url() {return url;} private final byte[] url;
|
||||
public byte[] Protocol() {return protocol;} private final byte[] protocol;
|
||||
public byte[] Host() {return host;} private final byte[] host;
|
||||
public byte[] User_agent() {return user_agent;} private final byte[] user_agent;
|
||||
public byte[] Accept() {return accept;} private final byte[] accept;
|
||||
public byte[] Accept_language() {return accept_language;} private final byte[] accept_language;
|
||||
public byte[] Accept_encoding() {return accept_encoding;} private final byte[] accept_encoding;
|
||||
public boolean Dnt() {return dnt;} private final boolean dnt;
|
||||
public byte[] X_requested_with() {return x_requested_with;} private byte[] x_requested_with;
|
||||
public byte[] Cookie() {return cookie;} private final byte[] cookie;
|
||||
public byte[] Referer() {return referer;} private final byte[] referer;
|
||||
public int Content_length() {return content_length;} private final int content_length;
|
||||
public byte[] Content_type() {return content_type;} private final byte[] content_type;
|
||||
public byte[] Content_type_boundary() {return content_type_boundary;} private final byte[] content_type_boundary;
|
||||
public byte[] Connection() {return connection;} private final byte[] connection;
|
||||
public byte[] Pragma() {return pragma;} private final byte[] pragma;
|
||||
public byte[] Cache_control() {return cache_control;} private final byte[] cache_control;
|
||||
public Http_post_data_hash Post_data_hash() {return post_data_hash;} private final Http_post_data_hash post_data_hash;
|
||||
public String To_str(Bry_bfr bfr) {
|
||||
bfr .Add_kv_line("type" , type == Type_get ? "GET" : "POST")
|
||||
.Add_kv_line("url" , url)
|
||||
.Add_kv_line("protocol" , protocol)
|
||||
.Add_kv_line("host" , host)
|
||||
.Add_kv_line("user_agent" , user_agent)
|
||||
.Add_kv_line("accept" , accept)
|
||||
.Add_kv_line("accept_encoding" , accept_encoding)
|
||||
.Add_kv_line("dnt" , dnt)
|
||||
.Add_kv_line("x_requested_with" , x_requested_with)
|
||||
.Add_kv_line("cookie" , cookie)
|
||||
.Add_kv_line("referer" , referer)
|
||||
.Add_kv_line("content_length" , content_length)
|
||||
.Add_kv_line("content_type" , content_type)
|
||||
.Add_kv_line("content_type_boundary" , content_type_boundary)
|
||||
.Add_kv_line("connection" , connection)
|
||||
.Add_kv_line("pragma" , pragma)
|
||||
.Add_kv_line("cache_control" , cache_control)
|
||||
;
|
||||
if (post_data_hash != null) {
|
||||
int len = post_data_hash.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Http_post_data_itm itm = post_data_hash.Get_at(i);
|
||||
bfr.Add_byte_repeat(Byte_ascii.Space, 2);
|
||||
bfr.Add_kv_line(String_.new_u8(itm.Key()), itm.Val());
|
||||
}
|
||||
}
|
||||
return bfr.Xto_str_and_clear();
|
||||
}
|
||||
public static final int Type_get = 1, Type_post = 2;
|
||||
}
|
||||
168
400_xowa/src/gplx/core/net/Http_request_parser.java
Normal file
168
400_xowa/src/gplx/core/net/Http_request_parser.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
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.net; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
public class Http_request_parser {
|
||||
private boolean dnt;
|
||||
private int type, content_length;
|
||||
private byte[] url, protocol, host, user_agent, accept, accept_language, accept_encoding, x_requested_with, cookie, referer, content_type, content_type_boundary, connection, pragma, cache_control;
|
||||
private Http_post_data_hash post_data_hash;
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr.new_(255);
|
||||
private final Http_server_wtr server_wtr; private final boolean log;
|
||||
public Http_request_parser(Http_server_wtr server_wtr, boolean log) {this.server_wtr = server_wtr; this.log = log;}
|
||||
public void Clear() {
|
||||
this.dnt = false;
|
||||
this.type = this.content_length = 0;
|
||||
this.url = this.protocol = this.host = this.user_agent = this.accept = this.accept_language = this.accept_encoding = this.x_requested_with = this.cookie
|
||||
= this.referer = this.content_type = this.content_type_boundary = this.connection = this.pragma = this.cache_control = null;
|
||||
this.post_data_hash = null;
|
||||
}
|
||||
public Http_request_itm Parse(Http_client_rdr rdr) {
|
||||
this.Clear();
|
||||
boolean reading_post_data = false; boolean post_nl_seen = false;
|
||||
while (true) {
|
||||
String line_str = rdr.Read_line(); if (line_str == null) break; // needed for TEST
|
||||
if (log) server_wtr.Write_str_w_nl(line_str);
|
||||
byte[] line = Bry_.new_u8(line_str);
|
||||
int line_len = line.length;
|
||||
if (line_len == 0) {
|
||||
switch (type) {
|
||||
case Http_request_itm.Type_get: break;
|
||||
case Http_request_itm.Type_post:
|
||||
if (reading_post_data || post_nl_seen) throw Exc_.new_("http.request.parser;invalid new line during post", "request", To_str());
|
||||
post_nl_seen = true; // only allow one \n per POST
|
||||
continue; // ignore line and get next
|
||||
default: throw Exc_.new_unimplemented();
|
||||
}
|
||||
break; // only GET will reach this line; GET requests always end with blank line; stop;
|
||||
}
|
||||
if (content_type_boundary != null && Bry_.Has_at_bgn(line, content_type_boundary)) {
|
||||
while (true) {
|
||||
if (Bry_.Has_at_end(line, Tkn_content_type_boundary_end)) break; // last form_data pair will end with "--"; stop
|
||||
line = Parse_content_type_boundary(rdr);
|
||||
}
|
||||
break; // assume form_data ends POST request
|
||||
}
|
||||
Object o = trie.Match_bgn(line, 0, line_len);
|
||||
if (o == null) {
|
||||
server_wtr.Write_str_w_nl(String_.Format("http.request.parser; unknown line; line={0} request={1}", line_str, To_str()));
|
||||
continue;
|
||||
}
|
||||
int val_bgn = Bry_finder.Find_fwd_while_ws(line, trie.Match_pos(), line_len); // skip ws after key; EX: "Host: "
|
||||
int tid = ((Int_obj_val)o).Val();
|
||||
switch (tid) {
|
||||
case Tid_get:
|
||||
case Tid_post: Parse_type(tid, val_bgn, line, line_len); break;
|
||||
case Tid_host: this.host = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_user_agent: this.user_agent = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_accept: this.accept = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_accept_language: this.accept_language = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_accept_encoding: this.accept_encoding = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_dnt: this.dnt = line[val_bgn] == Byte_ascii.Num_1; break;
|
||||
case Tid_x_requested_with: this.x_requested_with = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_cookie: this.cookie = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_referer: this.referer = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_content_length: this.content_length = Bry_.Xto_int_or(line, val_bgn, line_len, -1); break;
|
||||
case Tid_content_type: Parse_content_type(val_bgn, line, line_len); break;
|
||||
case Tid_connection: this.connection = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_pragma: this.pragma = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_cache_control: this.cache_control = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
default: throw Exc_.new_unhandled(tid);
|
||||
}
|
||||
}
|
||||
return Make_request_itm();
|
||||
}
|
||||
private void Parse_type(int tid, int val_bgn, byte[] line, int line_len) { // EX: "POST /xowa-cmd:exec_as_json HTTP/1.1"
|
||||
int url_end = Bry_finder.Find_bwd(line, Byte_ascii.Space, line_len); if (url_end == Bry_finder.Not_found) throw Exc_.new_("invalid protocol", "line", line, "request", To_str());
|
||||
switch (tid) {
|
||||
case Tid_get : this.type = Http_request_itm.Type_get; break;
|
||||
case Tid_post : this.type = Http_request_itm.Type_post; break;
|
||||
default : throw Exc_.new_unimplemented();
|
||||
}
|
||||
this.url = Bry_.Mid(line, val_bgn, url_end);
|
||||
this.protocol = Bry_.Mid(line, url_end + 1, line_len);
|
||||
}
|
||||
private void Parse_content_type(int val_bgn, byte[] line, int line_len) { // EX: Content-Type: multipart/form-data; boundary=---------------------------72432484930026
|
||||
int boundary_bgn = Bry_finder.Find_fwd(line, Tkn_boundary, val_bgn, line_len); if (boundary_bgn == Bry_finder.Not_found) throw Exc_.new_("invalid content_type", "line", line, "request", To_str());
|
||||
int content_type_end = Bry_finder.Find_bwd(line, Byte_ascii.Semic, boundary_bgn);
|
||||
this.content_type = Bry_.Mid(line, val_bgn, content_type_end);
|
||||
this.content_type_boundary = Bry_.Add(Tkn_content_type_boundary_end, Bry_.Mid(line, boundary_bgn += Tkn_boundary.length, line_len));
|
||||
}
|
||||
private Http_request_itm Make_request_itm() {
|
||||
return new Http_request_itm(type, url, protocol, host, user_agent, accept, accept_language, accept_encoding, dnt, x_requested_with, cookie, referer, content_length, content_type, content_type_boundary, connection, pragma, cache_control, post_data_hash);
|
||||
}
|
||||
private byte[] Parse_content_type_boundary(Http_client_rdr rdr) {
|
||||
if (post_data_hash == null) post_data_hash = new Http_post_data_hash();
|
||||
byte[] line = Bry_.new_u8(rdr.Read_line()); // cur line is already known to be content_type_boundary; skip it
|
||||
byte[] key = Parse_post_data_name(line);
|
||||
String line_str = rdr.Read_line(); // blank-line
|
||||
if (String_.Len_gt_0(line_str)) {throw Exc_.new_("http.request.parser; blank_line should follow content_type_boundary", "request", To_str());}
|
||||
while (true) {
|
||||
line = Bry_.new_u8(rdr.Read_line());
|
||||
if (Bry_.Has_at_bgn(line, content_type_boundary)) break;
|
||||
tmp_bfr.Add(line);
|
||||
}
|
||||
byte[] val = tmp_bfr.Xto_bry_and_clear();
|
||||
post_data_hash.Add(key, val);
|
||||
return line;
|
||||
}
|
||||
private byte[] Parse_post_data_name(byte[] line) { // EX: Content-Disposition: form-data; name="data"
|
||||
int line_len = line.length;
|
||||
int pos = Assert_tkn(line, 0, line_len, Tkn_content_disposition);
|
||||
pos = Assert_tkn(line, pos, line_len, Tkn_form_data);
|
||||
pos = Assert_tkn(line, pos, line_len, Tkn_name);
|
||||
int name_end = line_len;
|
||||
if (line[pos] == Byte_ascii.Quote) {
|
||||
if (line[name_end - 1] != Byte_ascii.Quote) throw Exc_.new_("http.request.parser; invalid form at end", "line", line, "request", To_str());
|
||||
++pos;
|
||||
--name_end;
|
||||
}
|
||||
return Bry_.Mid(line, pos, name_end);
|
||||
}
|
||||
private int Assert_tkn(byte[] src, int src_pos, int src_len, byte[] tkn) {
|
||||
int tkn_len = tkn.length;
|
||||
if (!Bry_.Match(src, src_pos, src_pos + tkn_len, tkn)) throw Exc_.new_("http.request.parser; invalid form_data line", "tkn", tkn, "line", src, "request", To_str());
|
||||
int rv = src_pos += tkn_len;
|
||||
return Bry_finder.Find_fwd_while_ws(src, rv, src_len);
|
||||
}
|
||||
private String To_str() {return Make_request_itm().To_str(tmp_bfr);}
|
||||
private static final int Tid_get = 1, Tid_post = 2, Tid_host = 3, Tid_user_agent = 4, Tid_accept = 5, Tid_accept_language = 6, Tid_accept_encoding = 7, Tid_dnt = 8
|
||||
, Tid_x_requested_with = 9, Tid_cookie = 10, Tid_referer = 11, Tid_content_length = 12, Tid_content_type = 13, Tid_connection = 14, Tid_pragma = 15, Tid_cache_control = 16;
|
||||
private static final Btrie_slim_mgr trie = Btrie_slim_mgr.ci_ascii_()
|
||||
.Add_str_int("GET" , Tid_get)
|
||||
.Add_str_int("POST" , Tid_post)
|
||||
.Add_str_int("Host:" , Tid_host)
|
||||
.Add_str_int("User-Agent:" , Tid_user_agent)
|
||||
.Add_str_int("Accept:" , Tid_accept)
|
||||
.Add_str_int("Accept-Language:" , Tid_accept_language)
|
||||
.Add_str_int("Accept-Encoding:" , Tid_accept_encoding)
|
||||
.Add_str_int("DNT:" , Tid_dnt)
|
||||
.Add_str_int("X-Requested-With:" , Tid_x_requested_with)
|
||||
.Add_str_int("Cookie:" , Tid_cookie)
|
||||
.Add_str_int("Referer:" , Tid_referer)
|
||||
.Add_str_int("Content-length:" , Tid_content_length)
|
||||
.Add_str_int("Content-Type:" , Tid_content_type)
|
||||
.Add_str_int("Connection:" , Tid_connection)
|
||||
.Add_str_int("Pragma:" , Tid_pragma)
|
||||
.Add_str_int("Cache-Control:" , Tid_cache_control)
|
||||
;
|
||||
private static final byte[] Tkn_boundary = Bry_.new_a7("boundary="), Tkn_content_type_boundary_end = Bry_.new_a7("--")
|
||||
, Tkn_content_disposition = Bry_.new_a7("Content-Disposition:"), Tkn_form_data = Bry_.new_a7("form-data;")
|
||||
, Tkn_name = Bry_.new_a7("name=")
|
||||
;
|
||||
}
|
||||
82
400_xowa/src/gplx/core/net/Http_request_parser_tst.java
Normal file
82
400_xowa/src/gplx/core/net/Http_request_parser_tst.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
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.net; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class Http_request_parser_tst {
|
||||
@Before public void init() {fxt.Clear();} private final Http_request_parser_fxt fxt = new Http_request_parser_fxt();
|
||||
@Test public void Type_post() {
|
||||
fxt.Test_type_post("POST /url HTTP/1.1", Http_request_itm.Type_post, "/url", "HTTP/1.1");
|
||||
}
|
||||
@Test public void Type_content_type() {
|
||||
fxt.Test_content_type("Content-Type: multipart/form-data; boundary=---------------------------72432484930026", "multipart/form-data", "-----------------------------72432484930026");
|
||||
}
|
||||
@Test public void Type_form_data() {
|
||||
fxt.Test_form_data(String_.Ary
|
||||
( "POST /url HTTP/1.1"
|
||||
, "Content-Type: multipart/form-data; boundary=---------------------------12345678901234"
|
||||
, ""
|
||||
, "-----------------------------12345678901234"
|
||||
, "Content-Disposition: form-data; name=\"key0\""
|
||||
, ""
|
||||
, "val0"
|
||||
, "-----------------------------12345678901234"
|
||||
, "Content-Disposition: form-data; name=\"key1\""
|
||||
, ""
|
||||
, "val1"
|
||||
, "-----------------------------12345678901234--"
|
||||
)
|
||||
, fxt.Make_post_data_itm("key0", "val0")
|
||||
, fxt.Make_post_data_itm("key1", "val1")
|
||||
);
|
||||
}
|
||||
}
|
||||
class Http_request_parser_fxt {
|
||||
private final Http_request_parser parser;
|
||||
private final Http_client_rdr client_rdr = Http_client_rdr_.new_mem();
|
||||
public Http_request_parser_fxt() {
|
||||
this.parser = new Http_request_parser(Http_server_wtr_.Noop, false);
|
||||
}
|
||||
public void Clear() {
|
||||
parser.Clear();
|
||||
}
|
||||
public Http_post_data_itm Make_post_data_itm(String key, String val) {return new Http_post_data_itm(Bry_.new_u8(key), Bry_.new_u8(val));}
|
||||
public void Test_type_post(String line, int expd_type, String expd_url, String expd_protocol) {
|
||||
client_rdr.Stream_(String_.Ary(line));
|
||||
Http_request_itm req = parser.Parse(client_rdr);
|
||||
Tfds.Eq(expd_type , req.Type());
|
||||
Tfds.Eq(expd_url , String_.new_u8(req.Url()));
|
||||
Tfds.Eq(expd_protocol , String_.new_u8(req.Protocol()));
|
||||
}
|
||||
public void Test_content_type(String line, String expd_content_type, String expd_content_boundary) {
|
||||
client_rdr.Stream_(String_.Ary(line));
|
||||
Http_request_itm req = parser.Parse(client_rdr);
|
||||
Tfds.Eq(expd_content_type , String_.new_u8(req.Content_type()));
|
||||
Tfds.Eq(expd_content_boundary , String_.new_u8(req.Content_type_boundary()));
|
||||
}
|
||||
public void Test_form_data(String[] ary, Http_post_data_itm... expd) {
|
||||
client_rdr.Stream_(ary);
|
||||
Http_request_itm req = parser.Parse(client_rdr);
|
||||
Http_post_data_hash hash = req.Post_data_hash();
|
||||
int len = hash.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Http_post_data_itm itm = hash.Get_at(i);
|
||||
Tfds.Eq_bry(itm.Key(), expd[i].Key());
|
||||
Tfds.Eq_bry(itm.Val(), expd[i].Val());
|
||||
}
|
||||
}
|
||||
}
|
||||
24
400_xowa/src/gplx/core/net/Http_server_wtr.java
Normal file
24
400_xowa/src/gplx/core/net/Http_server_wtr.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
public interface Http_server_wtr {
|
||||
void Write_str_w_nl(String s);
|
||||
}
|
||||
class Http_server_wtr__noop implements Http_server_wtr {
|
||||
public void Write_str_w_nl(String s) {}
|
||||
}
|
||||
22
400_xowa/src/gplx/core/net/Http_server_wtr_.java
Normal file
22
400_xowa/src/gplx/core/net/Http_server_wtr_.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_server_wtr_ {
|
||||
public static Http_server_wtr new_console() {return new Http_server_wtr__console();}
|
||||
public static final Http_server_wtr Noop = new Http_server_wtr__noop();
|
||||
}
|
||||
21
400_xowa/src/gplx/core/net/Http_server_wtr__console.java
Normal file
21
400_xowa/src/gplx/core/net/Http_server_wtr__console.java
Normal file
@@ -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.core.net; import gplx.*; import gplx.core.*;
|
||||
class Http_server_wtr__console implements Http_server_wtr {
|
||||
public void Write_str_w_nl(String s) {ConsoleAdp._.WriteLine(s);}
|
||||
}
|
||||
23
400_xowa/src/gplx/core/net/Socket_adp.java
Normal file
23
400_xowa/src/gplx/core/net/Socket_adp.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
public interface Socket_adp {
|
||||
Object Get_input_stream();
|
||||
Object Get_output_stream();
|
||||
void Rls();
|
||||
}
|
||||
36
400_xowa/src/gplx/core/net/Socket_adp__base.java
Normal file
36
400_xowa/src/gplx/core/net/Socket_adp__base.java
Normal file
@@ -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.net; import gplx.*; import gplx.core.*;
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
public class Socket_adp__base implements Socket_adp {
|
||||
private final Socket socket;
|
||||
public Socket_adp__base(Socket socket) {this.socket = socket;}
|
||||
public Object Get_input_stream() {
|
||||
try {return socket.getInputStream();}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Get_input_stream failed");}
|
||||
}
|
||||
public Object Get_output_stream() {
|
||||
try {return socket.getOutputStream();}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Get_output_stream failed");}
|
||||
}
|
||||
public void Rls() {
|
||||
try {socket.close();}
|
||||
catch (IOException e) {throw Exc_.new_exc(e, "net", "Rls failed");}
|
||||
}
|
||||
}
|
||||
50
400_xowa/src/gplx/core/regxs/Gfo_pattern.java
Normal file
50
400_xowa/src/gplx/core/regxs/Gfo_pattern.java
Normal file
@@ -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.regxs; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_pattern {
|
||||
private final Gfo_pattern_itm[] itms; private final int itms_len;
|
||||
private final Gfo_pattern_ctx ctx = new Gfo_pattern_ctx();
|
||||
public Gfo_pattern(byte[] raw) {
|
||||
this.raw = raw;
|
||||
itms = Gfo_pattern_itm_.Compile(raw);
|
||||
itms_len = itms.length;
|
||||
}
|
||||
public byte[] Raw() {return raw;} private byte[] raw;
|
||||
public boolean Match(byte[] val) {
|
||||
int val_len = val.length;
|
||||
int val_pos = 0;
|
||||
ctx.Init(itms_len);
|
||||
for (int i = 0; i < itms_len; ++i) {
|
||||
Gfo_pattern_itm itm = itms[i];
|
||||
ctx.Itm_idx_(i);
|
||||
val_pos = itm.Match(ctx, val, val_len, val_pos);
|
||||
if (!ctx.Rslt_pass()) return false;
|
||||
}
|
||||
return ctx.Rslt_pass() && val_pos == val_len;
|
||||
}
|
||||
public static Gfo_pattern[] Parse_to_ary(byte[] raw) {
|
||||
byte[][] patterns = Bry_.Split(raw, Byte_ascii.Semic, true);
|
||||
int patterns_len = patterns.length;
|
||||
Gfo_pattern[] rv = new Gfo_pattern[patterns_len];
|
||||
for (int i = 0; i < patterns_len; ++i) {
|
||||
byte[] pattern = patterns[i];
|
||||
rv[i] = new Gfo_pattern(pattern);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
31
400_xowa/src/gplx/core/regxs/Gfo_pattern_ctx.java
Normal file
31
400_xowa/src/gplx/core/regxs/Gfo_pattern_ctx.java
Normal file
@@ -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.regxs; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_pattern_ctx {
|
||||
public boolean Rslt_pass() {return rslt;} private boolean rslt;
|
||||
public void Rslt_fail_() {rslt = false;}
|
||||
public boolean Prv_was_wild() {return prv_was_wild;} public void Prv_was_wild_(boolean v) {prv_was_wild = v;} private boolean prv_was_wild;
|
||||
private int itm_len;
|
||||
public int Itm_idx() {return itm_idx;} public void Itm_idx_(int v) {itm_idx = v;} private int itm_idx;
|
||||
public boolean Itm_idx_is_last() {return itm_idx == itm_len - 1;}
|
||||
public void Init(int itm_len) {
|
||||
this.rslt = true;
|
||||
this.itm_len = itm_len;
|
||||
this.prv_was_wild = false;
|
||||
}
|
||||
}
|
||||
64
400_xowa/src/gplx/core/regxs/Gfo_pattern_itm.java
Normal file
64
400_xowa/src/gplx/core/regxs/Gfo_pattern_itm.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.regxs; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.strings.*;
|
||||
public interface Gfo_pattern_itm {
|
||||
byte Tid();
|
||||
void Compile(byte[] src, int bgn, int end);
|
||||
int Match(Gfo_pattern_ctx ctx, byte[] src, int src_len, int pos);
|
||||
void Xto_str(String_bldr sb);
|
||||
}
|
||||
class Gfo_pattern_itm_text implements Gfo_pattern_itm {
|
||||
public Gfo_pattern_itm_text() {}
|
||||
public byte Tid() {return Gfo_pattern_itm_.Tid_text;}
|
||||
public byte[] Text() {return text;} private byte[] text; private int text_len;
|
||||
public void Xto_str(String_bldr sb) {sb.Add(this.Tid()).Add("|" + String_.new_u8(text));}
|
||||
public void Compile(byte[] src, int bgn, int end) {
|
||||
this.text = Bry_.Mid(src, bgn, end);
|
||||
this.text_len = end - bgn;
|
||||
}
|
||||
public int Match(Gfo_pattern_ctx ctx, byte[] src, int src_len, int pos) {
|
||||
boolean pass = false;
|
||||
int text_end = pos + text_len;
|
||||
if (text_end > src_len) text_end = src_len;
|
||||
if (ctx.Prv_was_wild()) {
|
||||
int text_bgn = Bry_finder.Find_fwd(src, text, pos);
|
||||
pass = text_bgn != Bry_finder.Not_found;
|
||||
if (pass)
|
||||
pos = text_bgn + text_len;
|
||||
}
|
||||
else {
|
||||
pass = Bry_.Match(src, pos, text_end, text);
|
||||
if (pass)
|
||||
pos = text_end;
|
||||
}
|
||||
if (!pass) ctx.Rslt_fail_();
|
||||
ctx.Prv_was_wild_(false);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
class Gfo_pattern_itm_wild implements Gfo_pattern_itm {
|
||||
public byte Tid() {return Gfo_pattern_itm_.Tid_wild;}
|
||||
public void Compile(byte[] src, int bgn, int end) {}
|
||||
public int Match(Gfo_pattern_ctx ctx, byte[] src, int src_len, int pos) {
|
||||
ctx.Prv_was_wild_(true);
|
||||
return ctx.Itm_idx_is_last() ? src_len : pos;
|
||||
}
|
||||
public void Xto_str(String_bldr sb) {sb.Add(this.Tid()).Add("|*");}
|
||||
public static final Gfo_pattern_itm_wild _ = new Gfo_pattern_itm_wild(); Gfo_pattern_itm_wild() {}
|
||||
}
|
||||
51
400_xowa/src/gplx/core/regxs/Gfo_pattern_itm_.java
Normal file
51
400_xowa/src/gplx/core/regxs/Gfo_pattern_itm_.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
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.regxs; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_pattern_itm_ {
|
||||
public static final byte Tid_text = 0, Tid_wild = 1;
|
||||
public static Gfo_pattern_itm[] Compile(byte[] raw) {
|
||||
List_adp rv = List_adp_.new_();
|
||||
int raw_len = raw.length;
|
||||
int itm_bgn = -1;
|
||||
Gfo_pattern_itm itm = null;
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
boolean last = pos == raw_len;
|
||||
byte b = last ? Byte_ascii.Nil : raw[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Nil:
|
||||
if (itm != null) {itm.Compile(raw, itm_bgn, pos); itm = null; itm_bgn = -1;}
|
||||
break;
|
||||
case Byte_ascii.Star:
|
||||
if (itm != null) {itm.Compile(raw, itm_bgn, pos); itm = null; itm_bgn = -1;}
|
||||
rv.Add(Gfo_pattern_itm_wild._);
|
||||
break;
|
||||
default:
|
||||
if (itm_bgn == -1) {
|
||||
itm_bgn = pos;
|
||||
itm = new Gfo_pattern_itm_text();
|
||||
rv.Add(itm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
if (last) break;
|
||||
}
|
||||
return (Gfo_pattern_itm[])rv.To_ary_and_clear(Gfo_pattern_itm.class);
|
||||
}
|
||||
}
|
||||
93
400_xowa/src/gplx/core/regxs/Gfo_pattern_tst.java
Normal file
93
400_xowa/src/gplx/core/regxs/Gfo_pattern_tst.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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.regxs; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.strings.*;
|
||||
public class Gfo_pattern_tst {
|
||||
@Before public void init() {fxt.Clear();} private Gfo_pattern_itm_fxt fxt = new Gfo_pattern_itm_fxt();
|
||||
@Test public void Compile() {
|
||||
fxt.Test_Compile("a" , fxt.itm_text_("a"));
|
||||
fxt.Test_Compile("*" , fxt.itm_wild_());
|
||||
fxt.Test_Compile("a*" , fxt.itm_text_("a"), fxt.itm_wild_());
|
||||
fxt.Test_Compile("*a" , fxt.itm_wild_(), fxt.itm_text_("a"));
|
||||
fxt.Test_Compile("*ab*" , fxt.itm_wild_(), fxt.itm_text_("ab"), fxt.itm_wild_());
|
||||
fxt.Test_Compile("" );
|
||||
}
|
||||
@Test public void Match() {
|
||||
Gfo_pattern pattern = fxt.pattern_("abc");
|
||||
fxt.Test_Match_y(pattern, "abc");
|
||||
fxt.Test_Match_n(pattern, "ab", "a", "bc", "Abc", "");
|
||||
}
|
||||
@Test public void Match_all() {
|
||||
Gfo_pattern pattern = fxt.pattern_("*");
|
||||
fxt.Test_Match_y(pattern, "a", "abc", "");
|
||||
}
|
||||
@Test public void Match_bgn() {
|
||||
Gfo_pattern pattern = fxt.pattern_("abc*");
|
||||
fxt.Test_Match_y(pattern, "abc", "abcdef");
|
||||
fxt.Test_Match_n(pattern, "abd", "aabc", "");
|
||||
}
|
||||
@Test public void Match_end() {
|
||||
Gfo_pattern pattern = fxt.pattern_("*abc");
|
||||
fxt.Test_Match_y(pattern, "abc", "xyzabc");
|
||||
fxt.Test_Match_n(pattern, "abcd", "");
|
||||
}
|
||||
@Test public void Match_mid() {
|
||||
Gfo_pattern pattern = fxt.pattern_("a*c*e");
|
||||
fxt.Test_Match_y(pattern, "ace", "abcde");
|
||||
fxt.Test_Match_n(pattern, "abc", "");
|
||||
}
|
||||
@Test public void Bug_ctx() { // PURPOSE.fix: cb was true b/c ctx was not reset correctly
|
||||
Gfo_pattern pattern = fxt.pattern_("b*");
|
||||
fxt.Test_Match_y(pattern, "bc");
|
||||
fxt.Test_Match_n(pattern, "cb");
|
||||
}
|
||||
}
|
||||
class Gfo_pattern_itm_fxt {
|
||||
public void Clear() {}
|
||||
public Gfo_pattern pattern_(String raw) {return new Gfo_pattern(Bry_.new_u8(raw));}
|
||||
public void Test_Match_y(Gfo_pattern pattern, String... itms) {Test_Match(pattern, itms, Bool_.Y);}
|
||||
public void Test_Match_n(Gfo_pattern pattern, String... itms) {Test_Match(pattern, itms, Bool_.N);}
|
||||
private void Test_Match(Gfo_pattern pattern, String[] itms, boolean expd) {
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
String itm = itms[i];
|
||||
Tfds.Eq(expd, pattern.Match(Bry_.new_u8(itm)), "pattern={0} itm={1} expd={2}", String_.new_u8(pattern.Raw()), itm, expd);
|
||||
}
|
||||
}
|
||||
public Gfo_pattern_itm_wild itm_wild_() {return Gfo_pattern_itm_wild._;}
|
||||
public Gfo_pattern_itm_text itm_text_(String raw) {
|
||||
Gfo_pattern_itm_text rv = new Gfo_pattern_itm_text();
|
||||
byte[] bry = Bry_.new_u8(raw);
|
||||
rv.Compile(bry, 0, bry.length);
|
||||
return rv;
|
||||
}
|
||||
public void Test_Compile(String raw, Gfo_pattern_itm... expd) {
|
||||
Gfo_pattern_itm[] actl = Gfo_pattern_itm_.Compile(Bry_.new_u8(raw));
|
||||
Tfds.Eq(Ary_xto_str(expd), Ary_xto_str(actl));
|
||||
}
|
||||
private static String Ary_xto_str(Gfo_pattern_itm[] ary) {
|
||||
int len = ary.length;
|
||||
String_bldr sb = String_bldr_.new_();
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i != 0) sb.Add_char_nl();
|
||||
Gfo_pattern_itm itm = ary[i];
|
||||
itm.Xto_str(sb);
|
||||
}
|
||||
return sb.Xto_str_and_clear();
|
||||
}
|
||||
}
|
||||
42
400_xowa/src/gplx/core/threads/Gfo_async_cmd_itm.java
Normal file
42
400_xowa/src/gplx/core/threads/Gfo_async_cmd_itm.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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 Gfo_async_cmd_itm implements GfoInvkAble {
|
||||
private GfoInvkAble invk; private String invk_key; private GfoMsg msg = GfoMsg_.new_cast_("");
|
||||
public Gfo_async_cmd_itm Init(GfoInvkAble invk, String invk_key, Object... args) {
|
||||
this.invk = invk; this.invk_key = invk_key;
|
||||
msg.Args_reset();
|
||||
msg.Clear();
|
||||
int len = args.length;
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
String key = (String)args[i];
|
||||
Object val = args[i + 1];
|
||||
msg.Add(key, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public void Exec() {
|
||||
GfoInvkAble_.InvkCmd_msg(invk, invk_key, msg);
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_exec)) Exec();
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_exec = "exec";
|
||||
public static final Gfo_async_cmd_itm[] Ary_empty = new Gfo_async_cmd_itm[0];
|
||||
}
|
||||
34
400_xowa/src/gplx/core/threads/Gfo_async_cmd_mkr.java
Normal file
34
400_xowa/src/gplx/core/threads/Gfo_async_cmd_mkr.java
Normal file
@@ -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.threads; import gplx.*; import gplx.core.*;
|
||||
class Gfo_async_cmd_mkr {
|
||||
// private Gfo_async_cmd_itm[] free = Gfo_async_cmd_itm.Ary_empty, used = Gfo_async_cmd_itm.Ary_empty;
|
||||
// private int free_bgn = 0, free_end = 0, ary_len = 0;
|
||||
// public void Resize(int v) {
|
||||
// free = (Gfo_async_cmd_itm[])Array_.Resize(free, v);
|
||||
// used = (Gfo_async_cmd_itm[])Array_.Resize(used, v);
|
||||
// ary_len = v;
|
||||
// }
|
||||
public Gfo_async_cmd_itm Get(GfoInvkAble invk, String invk_key, Object... args) {
|
||||
Gfo_async_cmd_itm rv = new Gfo_async_cmd_itm();
|
||||
rv.Init(invk, invk_key, args);
|
||||
return rv;
|
||||
}
|
||||
public void Rls(Gfo_async_cmd_itm cmd) {
|
||||
}
|
||||
}
|
||||
58
400_xowa/src/gplx/core/threads/Gfo_async_mgr.java
Normal file
58
400_xowa/src/gplx/core/threads/Gfo_async_mgr.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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 gplx.core.primitives.*;
|
||||
public class Gfo_async_mgr implements GfoInvkAble {
|
||||
private List_adp queue = List_adp_.new_();
|
||||
private Bool_obj_ref running = Bool_obj_ref.n_();
|
||||
private Gfo_async_cmd_mkr cmd_mkr = new Gfo_async_cmd_mkr();
|
||||
public void Queue(GfoInvkAble invk, String invk_key, Object... args) {
|
||||
Gfo_async_cmd_itm cmd = cmd_mkr.Get(invk, invk_key, args);
|
||||
synchronized (queue) {
|
||||
queue.Add(cmd);
|
||||
}
|
||||
synchronized (running) {
|
||||
if (running.Val_n()) {
|
||||
running.Val_y_();
|
||||
gplx.core.threads.Thread_adp_.invk_(Invk_run, this, Invk_run).Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Run() {
|
||||
Gfo_async_cmd_itm cmd = null;
|
||||
try {
|
||||
while (true) {
|
||||
synchronized (queue) {
|
||||
if (queue.Count() == 0) break;
|
||||
cmd = (Gfo_async_cmd_itm)List_adp_.Pop(queue);
|
||||
cmd.Exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
synchronized (running) {
|
||||
running.Val_n_();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_run)) Run();
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_run = "run";
|
||||
}
|
||||
30
400_xowa/src/gplx/core/threads/Gfo_thread_cmd.java
Normal file
30
400_xowa/src/gplx/core/threads/Gfo_thread_cmd.java
Normal file
@@ -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.threads; import gplx.*; import gplx.core.*;
|
||||
public interface Gfo_thread_cmd extends GfoInvkAble {
|
||||
void Cmd_ctor();
|
||||
String Async_key();
|
||||
int Async_sleep_interval();
|
||||
boolean Async_prog_enabled();
|
||||
void Async_prog_run(int async_sleep_sum);
|
||||
byte Async_init();
|
||||
boolean Async_term();
|
||||
void Async_run();
|
||||
boolean Async_running();
|
||||
Gfo_thread_cmd Async_next_cmd(); void Async_next_cmd_(Gfo_thread_cmd next);
|
||||
}
|
||||
22
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_.java
Normal file
22
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_.java
Normal file
@@ -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.threads; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_thread_cmd_ {
|
||||
public static final int Async_sleep_interval_1_second = 1000;
|
||||
public static final byte Init_ok = 0, Init_cancel_step = 1, Init_cancel_all = 2;
|
||||
}
|
||||
41
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_base.java
Normal file
41
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_base.java
Normal file
@@ -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.threads; import gplx.*; import gplx.core.*;
|
||||
import gplx.gfui.*;
|
||||
public class Gfo_thread_cmd_base implements Gfo_thread_cmd {
|
||||
@gplx.Virtual public String Async_key() {return "undefined";}
|
||||
public void Cmd_ctor() {}
|
||||
public Gfo_thread_cmd_base Ctor(Gfo_usr_dlg usr_dlg, Gfui_kit kit) {this.usr_dlg = usr_dlg; this.kit = kit; return this;} protected Gfo_usr_dlg usr_dlg; protected Gfui_kit kit;
|
||||
public GfoInvkAble Owner() {return owner;} public Gfo_thread_cmd_base Owner_(GfoInvkAble v) {owner = v; return this;} GfoInvkAble owner;
|
||||
public Bry_fmtr_eval_mgr Url_eval_mgr() {return url_eval_mgr;} public Gfo_thread_cmd_base Url_eval_mgr_(Bry_fmtr_eval_mgr v) {url_eval_mgr = v; return this;} Bry_fmtr_eval_mgr url_eval_mgr;
|
||||
public Gfo_thread_cmd Async_next_cmd() {return next_cmd;} public void Async_next_cmd_(Gfo_thread_cmd v) {next_cmd = v;} Gfo_thread_cmd next_cmd;
|
||||
@gplx.Virtual public int Async_sleep_interval() {return Gfo_thread_cmd_.Async_sleep_interval_1_second;}
|
||||
@gplx.Virtual public boolean Async_prog_enabled() {return false;}
|
||||
@gplx.Virtual public byte Async_init() {return Gfo_thread_cmd_.Init_ok;}
|
||||
@gplx.Virtual public boolean Async_term() {return true;}
|
||||
@gplx.Virtual public void Async_prog_run(int async_sleep_sum) {}
|
||||
@gplx.Virtual public void Async_bgn() {}
|
||||
@gplx.Virtual public boolean Async_running() {return false;}
|
||||
@gplx.Virtual public void Async_run() {}
|
||||
@gplx.Virtual public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_owner)) return owner;
|
||||
else if (ctx.Match(k, Invk_async_bgn)) Async_bgn();
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_owner = "owner", Invk_async_bgn = "async_bgn";
|
||||
}
|
||||
73
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_download.java
Normal file
73
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_download.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
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 gplx.gfui.*;
|
||||
public class Gfo_thread_cmd_download implements Gfo_thread_cmd {
|
||||
public Gfo_thread_cmd Ctor(Gfo_usr_dlg usr_dlg, Gfui_kit kit) {this.usr_dlg = usr_dlg; this.kit = kit; xrg.Prog_dlg_(usr_dlg); return this;}
|
||||
public Gfo_thread_cmd_download Init(String prog_fmt_hdr, String src, Io_url trg) {
|
||||
this.src = src; this.trg = trg;
|
||||
xrg.Prog_fmt_hdr_(prog_fmt_hdr).Init(src, trg);
|
||||
return this;
|
||||
} String src; protected Gfui_kit kit; Gfo_usr_dlg usr_dlg; Io_url trg;
|
||||
public GfoInvkAble Owner() {return owner;} public Gfo_thread_cmd_download Owner_(GfoInvkAble v) {owner = v; return this;} GfoInvkAble owner;
|
||||
public Bry_fmtr_eval_mgr Url_eval_mgr() {return url_eval_mgr;} public Gfo_thread_cmd_download Url_eval_mgr_(Bry_fmtr_eval_mgr v) {url_eval_mgr = v; return this;} Bry_fmtr_eval_mgr url_eval_mgr;
|
||||
public void Cmd_ctor() {}
|
||||
public Gfo_thread_cmd Async_next_cmd() {return next_cmd;} public void Async_next_cmd_(Gfo_thread_cmd v) {next_cmd = v;} Gfo_thread_cmd next_cmd;
|
||||
@gplx.Virtual public String Async_key() {return KEY;}
|
||||
public int Async_sleep_interval() {return Gfo_thread_cmd_.Async_sleep_interval_1_second;}
|
||||
public boolean Async_prog_enabled() {return false;}
|
||||
@gplx.Virtual public byte Async_init() {
|
||||
if (Io_mgr.I.ExistsFil(trg)) {
|
||||
int rslt = kit.Ask_yes_no_cancel(GRP_KEY, "target_exists", "Target file already exists: '~{0}'.\nDo you want to delete it?", trg.Raw());
|
||||
switch (rslt) {
|
||||
case Gfui_dlg_msg_.Btn_yes: Io_mgr.I.DeleteFil(trg); break;
|
||||
case Gfui_dlg_msg_.Btn_no: return Gfo_thread_cmd_.Init_cancel_step;
|
||||
case Gfui_dlg_msg_.Btn_cancel: return Gfo_thread_cmd_.Init_cancel_all;
|
||||
default: throw Exc_.new_unhandled(rslt);
|
||||
}
|
||||
}
|
||||
usr_dlg.Prog_many(GRP_KEY, "download.bgn", "contacting web server: '~{0}'", src); // update progress; some servers (like WMF dump servers) are slow to respond
|
||||
return Gfo_thread_cmd_.Init_ok;
|
||||
}
|
||||
public boolean Async_term() {
|
||||
usr_dlg.Prog_many(GRP_KEY, "clear", "");
|
||||
return download_pass;
|
||||
}
|
||||
public void Async_prog_run(int async_sleep_sum) {}
|
||||
public boolean Async_running() {return xrg.Prog_running();}
|
||||
public void Async_run() {Thread_adp_.invk_(gplx.xowa.apps.Xoa_thread_.Key_bldr_download, this, Invk_async_bgn).Start();}
|
||||
private void Download() {
|
||||
download_pass = true;
|
||||
if (!xrg.Exec()) {
|
||||
xrg.Prog_running_(false);
|
||||
download_pass = false;
|
||||
kit.Ask_ok(GRP_KEY, "download.fail", "download failed. Please select 'read from file' if you've already downloaded a dump: url=~{0} error=~{1}", src, xrg.Rslt_err_str());
|
||||
}
|
||||
} boolean download_pass = true;
|
||||
protected gplx.ios.IoEngine_xrg_downloadFil xrg = Io_mgr.I.DownloadFil_args("", Io_url_.Empty);
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_async_bgn)) Download();
|
||||
else if (ctx.Match(k, Invk_owner)) return owner;
|
||||
else if (ctx.Match(k, Invk_src_)) src = m.ReadStr("v");
|
||||
else if (ctx.Match(k, Invk_trg_)) trg = Bry_fmtr_eval_mgr_.Eval_url(url_eval_mgr, m.ReadBry("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_async_bgn = "async_bgn", Invk_owner = "owner", Invk_src_ = "src_", Invk_trg_ = "trg_";
|
||||
static final String GRP_KEY = "gfo.thread.file.download";
|
||||
public static final String KEY = "file.download";
|
||||
}
|
||||
61
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_replace.java
Normal file
61
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_replace.java
Normal file
@@ -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.threads; import gplx.*; import gplx.core.*;
|
||||
import gplx.gfui.*;
|
||||
public class Gfo_thread_cmd_replace implements Gfo_thread_cmd {
|
||||
public Gfo_thread_cmd Init(Gfo_usr_dlg usr_dlg, Gfui_kit kit, Io_url fil) {
|
||||
this.usr_dlg = usr_dlg; this.kit = kit; this.fil = fil;
|
||||
return this;
|
||||
} Gfui_kit kit; Gfo_usr_dlg usr_dlg; Io_url fil;
|
||||
public GfoInvkAble Owner() {return owner;} public Gfo_thread_cmd_replace Owner_(GfoInvkAble v) {owner = v; return this;} GfoInvkAble owner;
|
||||
public Bry_fmtr_eval_mgr Url_eval_mgr() {return url_eval_mgr;} public Gfo_thread_cmd_replace Url_eval_mgr_(Bry_fmtr_eval_mgr v) {url_eval_mgr = v; return this;} Bry_fmtr_eval_mgr url_eval_mgr;
|
||||
public String Async_key() {return KEY;}
|
||||
public void Cmd_ctor() {}
|
||||
public Gfo_thread_cmd Async_next_cmd() {return next_cmd;} public void Async_next_cmd_(Gfo_thread_cmd v) {next_cmd = v;} Gfo_thread_cmd next_cmd;
|
||||
public int Async_sleep_interval() {return Gfo_thread_cmd_.Async_sleep_interval_1_second;}
|
||||
public boolean Async_prog_enabled() {return false;}
|
||||
@gplx.Virtual public byte Async_init() {
|
||||
if (!Io_mgr.I.ExistsFil(fil)) {kit.Ask_ok(GRP_KEY, "file_missing", "File does not exist: '~{0}'", fil.Raw()); return Gfo_thread_cmd_.Init_cancel_step;}
|
||||
return Gfo_thread_cmd_.Init_ok;
|
||||
}
|
||||
public boolean Async_term() {return true;}
|
||||
public void Async_prog_run(int async_sleep_sum) {}
|
||||
public boolean Async_running() {return false;}
|
||||
@gplx.Virtual public void Async_run() {Exec_find_replace();} // NOTE: do not run async; if multiple commands for same file then they will not always work
|
||||
public void Exec_find_replace() {
|
||||
String raw = Io_mgr.I.LoadFilStr(fil);
|
||||
int pairs_len = pairs.Count();
|
||||
for (int i = 0; i < pairs_len; i++) {
|
||||
KeyVal kv = (KeyVal)pairs.Get_at(i);
|
||||
raw = String_.Replace(raw, kv.Key(), kv.Val_to_str_or_null());
|
||||
}
|
||||
Io_mgr.I.SaveFilStr(fil, raw);
|
||||
usr_dlg.Prog_many(GRP_KEY, "done", "replace completed: ~{0} ~{1}", fil.Raw(), pairs_len);
|
||||
}
|
||||
public List_adp pairs = List_adp_.new_();
|
||||
@gplx.Virtual public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_async_bgn)) Exec_find_replace();
|
||||
else if (ctx.Match(k, Invk_owner)) return owner;
|
||||
else if (ctx.Match(k, Invk_fil_)) fil = Bry_fmtr_eval_mgr_.Eval_url(url_eval_mgr, m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_add)) pairs.Add(KeyVal_.new_(m.ReadStr("find"), m.ReadStr("replace")));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_async_bgn = "async_bgn", Invk_owner = "owner", Invk_fil_ = "fil_", Invk_add = "add";
|
||||
static final String GRP_KEY = "gfo.thread.file.download";
|
||||
public static final String KEY = "text.replace";
|
||||
}
|
||||
115
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_unzip.java
Normal file
115
400_xowa/src/gplx/core/threads/Gfo_thread_cmd_unzip.java
Normal file
@@ -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.threads; import gplx.*; import gplx.core.*;
|
||||
import gplx.gfui.*; import gplx.xowa.bldrs.cmds.utils.*;
|
||||
public class Gfo_thread_cmd_unzip implements Gfo_thread_cmd {
|
||||
public Gfo_thread_cmd_unzip Init(Gfo_usr_dlg usr_dlg, Gfui_kit kit, ProcessAdp bzip2_process, ProcessAdp zip_process, ProcessAdp gz_process, Io_url src, Io_url trg) {
|
||||
this.src = src; this.trg = trg; this.kit = kit; this.usr_dlg = usr_dlg;
|
||||
unzip_wkr = new Xob_unzip_wkr().Init(bzip2_process, zip_process, gz_process).Process_run_mode_(ProcessAdp.Run_mode_async);
|
||||
return this;
|
||||
} private Io_url src, trg; private Gfui_kit kit; private Gfo_usr_dlg usr_dlg; private Xob_unzip_wkr unzip_wkr;
|
||||
public GfoInvkAble Owner() {return owner;} public Gfo_thread_cmd_unzip Owner_(GfoInvkAble v) {owner = v; return this;} GfoInvkAble owner;
|
||||
public void Cmd_ctor() {}
|
||||
@gplx.Virtual public String Async_key() {return KEY;}
|
||||
public Gfo_thread_cmd Async_next_cmd() {return next_cmd;} public void Async_next_cmd_(Gfo_thread_cmd v) {next_cmd = v;} Gfo_thread_cmd next_cmd;
|
||||
public Bry_fmtr_eval_mgr Url_eval_mgr() {return url_eval_mgr;} public Gfo_thread_cmd_unzip Url_eval_mgr_(Bry_fmtr_eval_mgr v) {url_eval_mgr = v; return this;} Bry_fmtr_eval_mgr url_eval_mgr;
|
||||
public int Async_sleep_interval() {return Gfo_thread_cmd_.Async_sleep_interval_1_second;}
|
||||
public boolean Async_prog_enabled() {return true;}
|
||||
public void Async_prog_run(int async_sleep_sum) {
|
||||
String size_str = " please wait...";
|
||||
if (trg.Type_fil()) size_str = gplx.ios.Io_size_.To_str(Io_mgr.I.QueryFil(trg).Size());
|
||||
usr_dlg.Prog_many(GRP_KEY, "unzip", "unzipping: ~{0}", size_str);
|
||||
}
|
||||
@gplx.Virtual public byte Async_init() {
|
||||
if (!Io_mgr.I.ExistsFil(src)) {
|
||||
kit.Ask_ok(GRP_KEY, "source_missing", "Source file does not exist: '~{0}'", src.Raw());
|
||||
return Gfo_thread_cmd_.Init_cancel_step;
|
||||
}
|
||||
trg_is_dir = trg.Type_dir();
|
||||
if (delete_trg_if_exists
|
||||
&& (( trg_is_dir && Io_mgr.I.ExistsDir(trg))
|
||||
|| (!trg_is_dir && Io_mgr.I.ExistsFil(trg)))
|
||||
) {
|
||||
int rslt = kit.Ask_yes_no_cancel(GRP_KEY, "target_exists", "Target file already exists: '~{0}'.\nDo you want to delete it?", trg.Raw());
|
||||
switch (rslt) {
|
||||
case Gfui_dlg_msg_.Btn_yes: if (trg_is_dir) Io_mgr.I.DeleteDirDeep(trg); else Io_mgr.I.DeleteFil(trg); break;
|
||||
case Gfui_dlg_msg_.Btn_no: return Gfo_thread_cmd_.Init_cancel_step;
|
||||
case Gfui_dlg_msg_.Btn_cancel: return Gfo_thread_cmd_.Init_cancel_all;
|
||||
}
|
||||
}
|
||||
return Gfo_thread_cmd_.Init_ok;
|
||||
}
|
||||
public boolean Async_running() {return unzip_wkr.Process_exit_code() == ProcessAdp.Exit_init;}
|
||||
public void Async_run() {
|
||||
usr_dlg.Prog_many(GRP_KEY, "bgn", "unzipping");
|
||||
unzip_wkr.Decompress(src, trg);
|
||||
}
|
||||
public boolean Async_term() {
|
||||
if (rename_dir) {
|
||||
Io_url[] dirs = Io_mgr.I.QueryDir_args(trg.OwnerDir()).DirOnly_().Recur_(false).ExecAsUrlAry();
|
||||
int dirs_len = dirs.length;
|
||||
Io_url zip_dir = Io_url_.Empty;
|
||||
for (int i = 0; i < dirs_len; i++) {
|
||||
Io_url dir = dirs[i];
|
||||
if (String_.Has_at_bgn(String_.Lower(dir.NameOnly()), String_.Lower(trg.NameOnly()))) { // HACK: check that directory starts with archive name; DATE:2013-12-22
|
||||
zip_dir = dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (zip_dir == Io_url_.Empty) {
|
||||
kit.Ask_ok(GRP_KEY, "rename.fail", "unable to find directory: trg=~{0}", trg.Raw());
|
||||
return false;
|
||||
}
|
||||
if (!String_.Eq(String_.Lower(zip_dir.Raw()), String_.Lower(trg.Raw()))) // HACK: inkscape is itself
|
||||
Io_mgr.I.MoveDirDeep(zip_dir, trg);
|
||||
}
|
||||
switch (term_cmd_for_src) {
|
||||
case Term_cmd_for_src_noop: break;
|
||||
case Term_cmd_for_src_delete: Io_mgr.I.DeleteFil(src); break;
|
||||
case Term_cmd_for_src_move:
|
||||
if (term_cmd_for_src_url == Io_url_.Empty) throw Exc_.new_("move specified, but no url");
|
||||
Io_mgr.I.MoveFil_args(src, term_cmd_for_src_url, true).Exec();
|
||||
break;
|
||||
default: throw Exc_.new_unhandled(term_cmd_for_src);
|
||||
}
|
||||
usr_dlg.Prog_many(GRP_KEY, "done", "");
|
||||
return true;
|
||||
}
|
||||
public static final byte Term_cmd_for_src_noop = 0, Term_cmd_for_src_delete = 1, Term_cmd_for_src_move = 2;
|
||||
boolean rename_dir = false, trg_is_dir = false, delete_trg_if_exists = true;
|
||||
public byte Term_cmd_for_src() {return term_cmd_for_src;} public void Term_cmd_for_src_(byte v) {term_cmd_for_src = v;} private byte term_cmd_for_src = Term_cmd_for_src_delete;
|
||||
public Io_url Term_cmd_for_src_url() {return term_cmd_for_src_url;} public void Term_cmd_for_src_url_(Io_url v) {this.term_cmd_for_src_url = v;} Io_url term_cmd_for_src_url = Io_url_.Empty;
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_owner)) return owner;
|
||||
else if (ctx.Match(k, Invk_src_)) src = Bry_fmtr_eval_mgr_.Eval_url(url_eval_mgr, m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_trg_)) trg = Bry_fmtr_eval_mgr_.Eval_url(url_eval_mgr, m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_rename_dir_)) rename_dir = m.ReadYn("v");
|
||||
else if (ctx.Match(k, Invk_delete_trg_if_exists_)) delete_trg_if_exists = m.ReadYn("v");
|
||||
else if (ctx.Match(k, Invk_term_cmd_for_src_)) term_cmd_for_src = Term_cmd_for_src_parse_(m.ReadStr("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_owner = "owner", Invk_src_ = "src_", Invk_trg_ = "trg_", Invk_rename_dir_ = "rename_dir_", Invk_delete_trg_if_exists_ = "delete_trg_if_exists_", Invk_term_cmd_for_src_ = "term_cmd_for_src_";
|
||||
private static byte Term_cmd_for_src_parse_(String s) {
|
||||
if (String_.Eq(s, "noop")) return Term_cmd_for_src_noop;
|
||||
else if (String_.Eq(s, "delete")) return Term_cmd_for_src_delete;
|
||||
else if (String_.Eq(s, "move")) return Term_cmd_for_src_move;
|
||||
else throw Exc_.new_unhandled(s);
|
||||
}
|
||||
static final String GRP_KEY = "xowa.thread.file.unzip";
|
||||
public static final String KEY = "file.unzip";
|
||||
}
|
||||
62
400_xowa/src/gplx/core/threads/Gfo_thread_pool.java
Normal file
62
400_xowa/src/gplx/core/threads/Gfo_thread_pool.java
Normal file
@@ -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.core.threads; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_thread_pool implements GfoInvkAble {
|
||||
private Object thread_lock = new Object();
|
||||
private List_adp queue = List_adp_.new_();
|
||||
private GfoMsg run_msg = GfoMsg_.new_cast_(Invk_run_wkr);
|
||||
private boolean running = false;
|
||||
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public Gfo_thread_pool Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v; return this;} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Noop;
|
||||
public void Clear() {synchronized (thread_lock) {queue.Clear(); running = false;}}
|
||||
public Gfo_thread_pool Add_at_end(Gfo_thread_wkr wkr) {
|
||||
synchronized (thread_lock) {queue.Add(wkr);}
|
||||
return this;
|
||||
}
|
||||
public void Resume() {
|
||||
synchronized (thread_lock) {
|
||||
running = false;
|
||||
}
|
||||
this.Run();
|
||||
}
|
||||
public void Run() {
|
||||
Gfo_thread_wkr wkr = null;
|
||||
synchronized (thread_lock) {
|
||||
if (running) return; // already running; discard run request and rely on running-wkr to call Run when done
|
||||
int len = queue.Count(); if (len == 0) return; // nothing in list; occurs when last item calls Run when done
|
||||
running = true;
|
||||
wkr = (Gfo_thread_wkr)List_adp_.Pop_first(queue);
|
||||
}
|
||||
Thread_adp_.Run_invk_msg(wkr.Name(), this, run_msg.Clear().Add("v", wkr));
|
||||
}
|
||||
private void Run_wkr(Gfo_thread_wkr wkr) {
|
||||
try {wkr.Exec();}
|
||||
catch (Exception e) {
|
||||
usr_dlg.Warn_many("", "", "uncaught exception while running thread; name=~{0} err=~{1}", wkr.Name(), Err_.Message_gplx_brief(e));
|
||||
}
|
||||
finally {
|
||||
if (wkr.Resume())
|
||||
this.Resume();
|
||||
}
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_run_wkr)) Run_wkr((Gfo_thread_wkr)m.ReadObj("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
private static final String Invk_run_wkr = "run_wkr";
|
||||
}
|
||||
23
400_xowa/src/gplx/core/threads/Gfo_thread_wkr.java
Normal file
23
400_xowa/src/gplx/core/threads/Gfo_thread_wkr.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.threads; import gplx.*; import gplx.core.*;
|
||||
public interface Gfo_thread_wkr {
|
||||
String Name();
|
||||
void Exec();
|
||||
boolean Resume();
|
||||
}
|
||||
151
400_xowa/src/gplx/core/xmls/Gfo_xml_wtr.java
Normal file
151
400_xowa/src/gplx/core/xmls/Gfo_xml_wtr.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
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.xmls; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_xml_wtr {
|
||||
private final Bry_bfr bfr = Bry_bfr.reset_(255), txt_bfr = Bry_bfr.reset_(32);
|
||||
private byte quote_byte = Byte_ascii.Apos;
|
||||
private byte[] quote_escape = Bry_quote_1_escape;
|
||||
private List_adp nde_stack = List_adp_.new_();
|
||||
private Gfo_xml_nde nde_cur = null;
|
||||
private int indent = 0;
|
||||
public void Quote_(boolean apos) {
|
||||
if (apos) {
|
||||
this.quote_byte = Byte_ascii.Apos;
|
||||
this.quote_escape = Bry_quote_1_escape;
|
||||
}
|
||||
else {
|
||||
this.quote_byte = Byte_ascii.Quote;
|
||||
this.quote_escape = Bry_quote_2_escape;
|
||||
}
|
||||
}
|
||||
public Gfo_xml_wtr Nde_lhs_bgn_grp(String v) {return Nde_lhs_bgn(Bool_.Y, v);}
|
||||
public Gfo_xml_wtr Nde_lhs_bgn_itm(String v) {return Nde_lhs_bgn(Bool_.N, v);}
|
||||
private Gfo_xml_wtr Nde_lhs_bgn(boolean grp, String v) {
|
||||
nde_cur = new Gfo_xml_nde(grp, v);
|
||||
nde_stack.Add(nde_cur);
|
||||
bfr.Add_byte_repeat(Byte_ascii.Space, indent);
|
||||
bfr.Add_byte(Byte_ascii.Angle_bgn).Add_str_u8(v);
|
||||
indent += 2;
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Nde_lhs_end() {
|
||||
bfr.Add_byte(Byte_ascii.Angle_end);
|
||||
if (nde_cur.Grp()) bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Nde_lhs(String v) {return Nde_lhs(Bool_.Y, v);}
|
||||
private Gfo_xml_wtr Nde_lhs(boolean grp, String v) {
|
||||
this.Nde_lhs_bgn(grp, v);
|
||||
this.Nde_lhs_end();
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Nde_rhs() {
|
||||
Gfo_xml_nde nde = (Gfo_xml_nde)List_adp_.Pop(nde_stack);
|
||||
indent -= 2;
|
||||
if (nde.Grp()) bfr.Add_byte_repeat(Byte_ascii.Space, indent);
|
||||
bfr.Add(Bry_nde_rhs_bgn).Add_str_u8(nde.Name()).Add_byte(Byte_ascii.Angle_end); // EX: </node>
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Nde_txt_str(String name, String text) {
|
||||
this.Nde_lhs(Bool_.N, name);
|
||||
this.Txt_str_u8(text);
|
||||
this.Nde_rhs();
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Nde_txt_bry(String name, byte[] text) {
|
||||
this.Nde_lhs(Bool_.N, name);
|
||||
this.Txt_bry(text);
|
||||
this.Nde_rhs();
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Nde_txt_int(String name, int text) {
|
||||
this.Nde_lhs(Bool_.N, name);
|
||||
this.Txt_bry(Int_.Xto_bry(text));
|
||||
this.Nde_rhs();
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Atr_bgn(String key) {
|
||||
bfr.Add_byte_space().Add_str_u8(key).Add_byte(Byte_ascii.Eq).Add_byte(quote_byte);
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Atr_val_str_a7(String v) {bfr.Add_str_a7(v); return this;}
|
||||
public Gfo_xml_wtr Atr_val_str_u8(String v) {bfr.Add_str_u8 (v); return this;}
|
||||
public Gfo_xml_wtr Atr_val_bry (byte[] v) {bfr.Add(v); return this;}
|
||||
public Gfo_xml_wtr Atr_val_int (int v) {bfr.Add_int_variable(v); return this;}
|
||||
public Gfo_xml_wtr Atr_end() {
|
||||
bfr.Add_byte(quote_byte);
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Atr_kv_int(String key, int val) {return Atr_kv_bry(key, Int_.Xto_bry(val));}
|
||||
public Gfo_xml_wtr Atr_kv_str_a7(String key, String val) {return Atr_kv_bry(key, Bry_.new_a7(val));}
|
||||
public Gfo_xml_wtr Atr_kv_str_u8(String key, String val) {return Atr_kv_bry(key, Bry_.new_u8(val));}
|
||||
public Gfo_xml_wtr Atr_kv_bry(String key, byte[] val) {
|
||||
bfr.Add_byte_space().Add_str_u8(key);
|
||||
bfr.Add_byte(Byte_ascii.Eq);
|
||||
Atr_val_quote(val);
|
||||
return this;
|
||||
}
|
||||
private Gfo_xml_wtr Atr_val_quote(byte[] val_bry) {
|
||||
bfr.Add_byte(quote_byte);
|
||||
bfr.Add_bry_escape(quote_byte, quote_escape, val_bry, 0, val_bry.length);
|
||||
bfr.Add_byte(quote_byte);
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Txt_bry(byte[] txt) {
|
||||
int len = txt.length;
|
||||
boolean dirty = false;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
byte[] escape = null;
|
||||
byte b = txt[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Lt: escape = Bry_escape_lt; break;
|
||||
case Byte_ascii.Gt: escape = Bry_escape_gt; break;
|
||||
case Byte_ascii.Amp: escape = Bry_escape_amp; break;
|
||||
default: break;
|
||||
}
|
||||
if (escape != null && !dirty) {
|
||||
bfr.Add_mid(txt, 0, i);
|
||||
dirty = true;
|
||||
}
|
||||
if (dirty) {
|
||||
if (escape == null) bfr.Add_byte(b);
|
||||
else bfr.Add(escape);
|
||||
}
|
||||
}
|
||||
if (dirty) bfr.Add_bfr_and_clear(txt_bfr);
|
||||
else bfr.Add(txt);
|
||||
return this;
|
||||
}
|
||||
public Gfo_xml_wtr Txt_str_u8(String txt) {return Txt_bry(Bry_.new_u8(txt));}
|
||||
public String Bld_str() {return bfr.Xto_str_and_clear();}
|
||||
private static final byte[]
|
||||
Bry_nde_rhs_bgn = Bry_.new_a7("</")
|
||||
// , Bry_nde_inline = Bry_.new_a7("/>")
|
||||
, Bry_quote_1_escape = Bry_.new_a7("'")
|
||||
, Bry_quote_2_escape = Bry_.new_a7(""")
|
||||
, Bry_escape_lt = Bry_.new_a7("<")
|
||||
, Bry_escape_gt = Bry_.new_a7(">")
|
||||
, Bry_escape_amp = Bry_.new_a7("&")
|
||||
;
|
||||
}
|
||||
class Gfo_xml_nde {
|
||||
public Gfo_xml_nde(boolean grp, String name) {this.grp = grp; this.name = name;}
|
||||
public boolean Grp() {return grp;} private final boolean grp;
|
||||
public String Name() {return name;} private final String name;
|
||||
}
|
||||
81
400_xowa/src/gplx/core/xmls/Gfo_xml_wtr_tst.java
Normal file
81
400_xowa/src/gplx/core/xmls/Gfo_xml_wtr_tst.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
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.xmls; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class Gfo_xml_wtr_tst {
|
||||
private final Gfo_xml_wtr_fxt fxt = new Gfo_xml_wtr_fxt();
|
||||
@Before public void init() {}
|
||||
@Test public void Root() {
|
||||
fxt.Wtr().Nde_lhs("a").Nde_rhs();
|
||||
fxt.Test_bld("<a>", "</a>");
|
||||
}
|
||||
@Test public void Nest() {
|
||||
fxt.Wtr()
|
||||
.Nde_lhs("a")
|
||||
. Nde_lhs("a_a")
|
||||
. Nde_lhs("a_a_a")
|
||||
. Nde_rhs()
|
||||
. Nde_rhs()
|
||||
.Nde_rhs()
|
||||
;
|
||||
fxt.Test_bld
|
||||
( "<a>"
|
||||
, " <a_a>"
|
||||
, " <a_a_a>"
|
||||
, " </a_a_a>"
|
||||
, " </a_a>"
|
||||
, "</a>"
|
||||
);
|
||||
}
|
||||
@Test public void Atrs() {
|
||||
fxt.Wtr()
|
||||
.Nde_lhs_bgn_itm("a")
|
||||
.Atr_kv_str_a7("b", "b1")
|
||||
.Nde_lhs_end()
|
||||
.Nde_rhs()
|
||||
;
|
||||
fxt.Test_bld("<a b='b1'></a>");
|
||||
}
|
||||
@Test public void Atrs_escape() {
|
||||
fxt.Wtr()
|
||||
.Nde_lhs_bgn_itm("a")
|
||||
.Atr_kv_str_a7("b", "'\"<>&")
|
||||
.Nde_lhs_end()
|
||||
.Nde_rhs()
|
||||
;
|
||||
fxt.Test_bld("<a b=''\"<>&'></a>");
|
||||
}
|
||||
@Test public void Nde_txt() {
|
||||
fxt.Wtr()
|
||||
.Nde_txt_str("a", "a123")
|
||||
;
|
||||
fxt.Test_bld("<a>a123</a>");
|
||||
}
|
||||
@Test public void Nde_txt_escape() {
|
||||
fxt.Wtr()
|
||||
.Nde_txt_str("a", "'\"<>&x")
|
||||
;
|
||||
fxt.Test_bld("<a>'\"<>&x</a>");
|
||||
}
|
||||
}
|
||||
class Gfo_xml_wtr_fxt {
|
||||
public Gfo_xml_wtr Wtr() {return wtr;} private final Gfo_xml_wtr wtr = new Gfo_xml_wtr();
|
||||
public void Test_bld(String... lines) {
|
||||
Tfds.Eq_str_lines(String_.Concat_lines_nl_skip_last(lines), wtr.Bld_str());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user