mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
Embeddable: Fix if_exists
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/100_core"/>
|
||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/140_dbs"/>
|
||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/150_gfui"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/luaj_xowa.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/jtidy_xowa.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/icu4j-4_8.jar"/>
|
||||
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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 ToBitStr(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 Get_flag(int i) {return Int_flag_bldr_.Base2_ary[i];}
|
||||
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 Err_.new_wo_type("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
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_.ToBitStr(val));}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
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.xowa.htmls.core.hzips.*;
|
||||
public class Bit_heap_rdr {
|
||||
private final byte[] hzip_int_bry = new byte[5];
|
||||
public int Cur_val() {return cur_val;} private int cur_val;
|
||||
public int Cur_bits() {return cur_bits;} private int cur_bits;
|
||||
public int Cur_pos() {return cur_pos;} private int cur_pos;
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public void Load(byte[] src, int src_bgn, int src_end) {
|
||||
this.src = src; this.cur_pos = src_bgn; this.src_end = src_end;
|
||||
this.cur_val = 0; this.cur_bits = 0;
|
||||
}
|
||||
public boolean Get_bool() {
|
||||
Get_bgn(cur_bits);
|
||||
int old_val = cur_val;
|
||||
this.cur_val = cur_val >> 1;
|
||||
int comp_val = cur_val << 1;
|
||||
boolean rv = (old_val - comp_val) == 1;
|
||||
Get_end(1);
|
||||
return rv;
|
||||
}
|
||||
public byte Get_byte(int bits) {
|
||||
int old_bits = bits;
|
||||
int new_bits = cur_bits + bits;
|
||||
boolean again = false;
|
||||
if (new_bits > 7 && cur_bits > 0) {
|
||||
old_bits = 8 - cur_bits;
|
||||
again = true;
|
||||
new_bits -= 8;
|
||||
}
|
||||
int rv = Get_byte_private(old_bits, cur_bits);
|
||||
if (again) {
|
||||
Get_end(old_bits);
|
||||
int new_val = Get_byte_private(new_bits, 0);
|
||||
rv += new_val << old_bits;
|
||||
}
|
||||
Get_end(new_bits);
|
||||
return (byte)rv;
|
||||
}
|
||||
public int Get_int_hzip(int reqd_len) {
|
||||
int full_len = reqd_len; int bgn_idx = 0;
|
||||
byte b0 = Get_byte(8);
|
||||
switch (b0) {
|
||||
case Xoh_hzip_int.prefix__b256__2: full_len = 2; bgn_idx = 1; break;
|
||||
case Xoh_hzip_int.prefix__b256__3: full_len = 3; bgn_idx = 1; break;
|
||||
case Xoh_hzip_int.prefix__b256__4: full_len = 4; bgn_idx = 1; break;
|
||||
case Xoh_hzip_int.prefix__b256__5: full_len = 5; bgn_idx = 1; break;
|
||||
}
|
||||
hzip_int_bry[0] = b0;
|
||||
for (int i = 1; i < full_len; ++i)
|
||||
hzip_int_bry[i] = Get_byte(8);
|
||||
return Xoh_hzip_int.To_int_by_bry(hzip_int_bry, bgn_idx, full_len, Byte_.Zero, 256);
|
||||
}
|
||||
private byte Get_byte_private(int bits, int chk_bits) {
|
||||
Get_bgn(chk_bits);
|
||||
int old_val = cur_val;
|
||||
this.cur_val = cur_val >> bits;
|
||||
int comp_val = cur_val << bits;
|
||||
byte rv = (byte)(old_val - comp_val);
|
||||
return rv;
|
||||
}
|
||||
private void Get_bgn(int chk_bits) {
|
||||
if (chk_bits == 0) cur_val = src[cur_pos] & 0xFF; // PATCH.JAVA:need to convert to unsigned byte
|
||||
}
|
||||
private void Get_end(int bits) {
|
||||
int new_bits = cur_bits + bits;
|
||||
if (new_bits == 8) {
|
||||
cur_bits = 0;
|
||||
cur_pos += 1;
|
||||
}
|
||||
else
|
||||
cur_bits = new_bits;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
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_heap_rdr_tst {
|
||||
private final Bit_heap_rdr_fxt fxt = new Bit_heap_rdr_fxt();
|
||||
@Test public void Get_bool() {
|
||||
fxt.Load(255);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur(127, 1, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 63, 2, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 31, 3, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 15, 4, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 7, 5, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 3, 6, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 1, 7, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 0, 0, 1);
|
||||
fxt.Load(0);
|
||||
fxt.Test__get_bool(Bool_.N).Test__cur( 0, 1, 0);
|
||||
fxt.Load(6);
|
||||
fxt.Test__get_bool(Bool_.N).Test__cur( 3, 1, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 1, 2, 0);
|
||||
fxt.Test__get_bool(Bool_.Y).Test__cur( 0, 3, 0);
|
||||
}
|
||||
@Test public void Get_byte() {
|
||||
fxt.Load(255).Test__get_byte(2, 3).Test__cur(63, 2, 0);
|
||||
fxt.Load(255, 3);
|
||||
fxt.Test__get_byte(7, 127);
|
||||
fxt.Test__get_byte(3, 7);
|
||||
fxt.Load(10);
|
||||
fxt.Test__get_bool(false);
|
||||
fxt.Test__get_byte(3, 5);
|
||||
}
|
||||
@Test public void Get_int_hzip() {
|
||||
fxt.Load(100).Test__get_int_hzip(1, 100).Test__cur(0, 0, 1);
|
||||
fxt.Load(253, 1, 44).Test__get_int_hzip(1, 300).Test__cur(0, 0, 3);
|
||||
fxt.Load(0, 100).Test__get_int_hzip(2, 100).Test__cur(0, 0, 2);
|
||||
fxt.Load(250, 3, 88, 0).Test__get_bool(Bool_.N).Test__get_int_hzip(1, 300).Test__cur(0, 1, 3);
|
||||
}
|
||||
}
|
||||
class Bit_heap_rdr_fxt {
|
||||
private final Bit_heap_rdr heap = new Bit_heap_rdr();
|
||||
public Bit_heap_rdr_fxt Load(int... src) {
|
||||
byte[] bry = Bry_.New_by_ints(src);
|
||||
heap.Load(bry, 0, bry.length);
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_rdr_fxt Test__get_bool(boolean expd) {
|
||||
Tfds.Eq_bool(expd, heap.Get_bool());
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_rdr_fxt Test__get_byte(int bits, int expd) {
|
||||
Tfds.Eq_byte((byte)expd, heap.Get_byte(bits));
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_rdr_fxt Test__get_int_hzip(int reqd, int expd) {
|
||||
Tfds.Eq_int(expd, heap.Get_int_hzip(reqd));
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_rdr_fxt Test__cur(int cur_val, int cur_bits, int cur_pos) {
|
||||
Tfds.Eq_int(cur_val, heap.Cur_val(), "val");
|
||||
Tfds.Eq_int(cur_bits, heap.Cur_bits(), "bits");
|
||||
Tfds.Eq_int(cur_pos, heap.Cur_pos(), "pos");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
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_heap_wtr {
|
||||
private final gplx.xowa.htmls.core.hzips.Xoh_hzip_int hzip_int = new gplx.xowa.htmls.core.hzips.Xoh_hzip_int().Mode_is_b256_(true);
|
||||
private final Bry_bfr hzip_int_bfr = Bry_bfr_.Reset(5);
|
||||
public int Cur() {return cur;} private int cur;
|
||||
public int Cur_bits() {return cur_bits;} private int cur_bits;
|
||||
public Bry_bfr Heap() {return heap;} private final Bry_bfr heap = Bry_bfr_.New();
|
||||
public void Clear() {heap.Clear(); cur = 0; cur_bits = 0;}
|
||||
public void Add_bool(boolean v) {
|
||||
if (v)
|
||||
cur += Pow_ary[cur_bits];
|
||||
if (cur_bits == 7) {
|
||||
heap.Add_byte((byte)cur);
|
||||
cur = 0;
|
||||
cur_bits = 0;
|
||||
}
|
||||
else
|
||||
++cur_bits;
|
||||
}
|
||||
public void Add_byte(byte val_byte) {
|
||||
int val_int = val_byte & 0xFF; // PATCH.JAVA:need to convert to unsigned byte
|
||||
if (cur_bits == 0)
|
||||
heap.Add_byte(val_byte);
|
||||
else {
|
||||
heap.Add_byte((byte)(cur + (val_int << cur_bits)));
|
||||
this.cur = val_int >> cur_bits;
|
||||
}
|
||||
}
|
||||
public void Add_byte(int val_bits, int val) {
|
||||
int total_bits = cur_bits + val_bits;
|
||||
int new_val = cur + (val << cur_bits);
|
||||
if (total_bits < 8) {
|
||||
this.cur_bits = total_bits;
|
||||
this.cur = new_val;
|
||||
}
|
||||
else {
|
||||
heap.Add_byte((byte)new_val);
|
||||
this.cur = val >> (8 - cur_bits);
|
||||
this.cur_bits = total_bits - 8;
|
||||
}
|
||||
}
|
||||
public void Add_int_hzip(int reqd_len, int val) {
|
||||
hzip_int.Encode(reqd_len, hzip_int_bfr, val);
|
||||
int len = hzip_int_bfr.Len();
|
||||
byte[] hzip_bry = hzip_int_bfr.Bfr();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
byte b = hzip_bry[i];
|
||||
Add_byte(8, b & 0xFF); // PATCH.JAVA:need to convert to unsigned byte
|
||||
}
|
||||
hzip_int_bfr.Clear();
|
||||
}
|
||||
public void Save(Bry_bfr bfr) {}
|
||||
public static final int[] Pow_ary = new int[] {1, 2, 4, 8, 16, 32, 64, 128, 256};
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
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_heap_wtr_tst {
|
||||
private final Bit_heap_wtr_fxt fxt = new Bit_heap_wtr_fxt();
|
||||
@Test public void Add_bool() {
|
||||
fxt.Clear().Add_bool(Bool_.Y).Test__vals(1, 1);
|
||||
fxt.Clear().Add_bool(Bool_.N).Test__vals(1, 0);
|
||||
fxt.Clear().Add_bool(Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y).Test__vals(4, 15);
|
||||
fxt.Clear().Add_bool(Bool_.Y, Bool_.N, Bool_.N, Bool_.Y).Test__vals(4, 9);
|
||||
fxt.Clear().Add_bool(8, Bool_.Y).Test__vals(0, 0, 255);
|
||||
}
|
||||
@Test public void Add_byte() {
|
||||
fxt.Clear().Add_byte(255).Test__vals(0, 0, 255);
|
||||
}
|
||||
@Test public void Add_bool_byte() {
|
||||
fxt.Clear().Add_bool(Bool_.N).Add_byte(255).Test__vals(1, 127, 254);
|
||||
fxt.Clear().Add_bool(Bool_.Y).Add_byte(255).Test__vals(1, 127, 255);
|
||||
fxt.Clear().Add_bool(Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y).Add_byte(255).Test__vals(4, 15, 255);
|
||||
}
|
||||
@Test public void Add_byte_digits() {
|
||||
fxt.Clear().Add_byte(4, 15).Test__vals(4, 15);
|
||||
fxt.Clear().Add_byte(7, 127).Add_byte(2, 3).Test__vals(1, 1, 255);
|
||||
fxt.Clear().Add_byte(3, 7).Add_byte(3, 7).Test__vals(6, 63);
|
||||
fxt.Clear().Add_byte(6, 63).Add_byte(3, 7).Test__vals(1, 1, 255);
|
||||
fxt.Clear().Add_byte(3, 6).Add_byte(3, 6).Test__vals(6, 54);
|
||||
}
|
||||
@Test public void Add_int_hzip() {
|
||||
fxt.Clear().Add_int_hzip(1, 100).Test__vals(0, 0, 100);
|
||||
fxt.Clear().Add_int_hzip(1, 300).Test__vals(0, 0, 253, 1, 44);
|
||||
fxt.Clear().Add_int_hzip(2, 100).Test__vals(0, 0, 0, 100);
|
||||
fxt.Clear().Add_bool(Bool_.N).Add_int_hzip(1, 300).Test__vals(1, 0, 250, 3, 88);
|
||||
}
|
||||
}
|
||||
class Bit_heap_wtr_fxt {
|
||||
private final Bit_heap_wtr heap = new Bit_heap_wtr();
|
||||
public Bit_heap_wtr_fxt Clear() {heap.Clear(); return this;}
|
||||
public Bit_heap_wtr_fxt Add_bool(int len, boolean v) {
|
||||
boolean[] ary = new boolean[len];
|
||||
for (int i = 0; i < len; ++i)
|
||||
ary[i] = v;
|
||||
Add_bool(ary);
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_wtr_fxt Add_bool(boolean... v) {
|
||||
int len = v.length;
|
||||
for (int i = 0; i < len; ++i)
|
||||
heap.Add_bool(v[i]);
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_wtr_fxt Add_byte(int... v) {
|
||||
int len = v.length;
|
||||
for (int i = 0; i < len; ++i)
|
||||
heap.Add_byte((byte)v[i]);
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_wtr_fxt Add_byte(int bits, int val) {
|
||||
heap.Add_byte(bits, (byte)val);
|
||||
return this;
|
||||
}
|
||||
public Bit_heap_wtr_fxt Add_int_hzip(int reqd, int val) {
|
||||
heap.Add_int_hzip(reqd, val);
|
||||
return this;
|
||||
}
|
||||
public void Test__vals(int expd_cur_bits, int expd_cur, int... expd_ary) {
|
||||
Tfds.Eq_int (expd_cur_bits , heap.Cur_bits() , "cur_bits");
|
||||
Tfds.Eq_int (expd_cur , heap.Cur() , "cur");
|
||||
Tfds.Eq_ary (Bry_.New_by_ints(expd_ary) , heap.Heap().To_bry() , "heap");
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
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.core.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 Instance = new Bry_comparer(); Bry_comparer() {} // TS.static
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
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_diff_ {
|
||||
public static byte[][] Diff_1st_line(byte[] lhs, byte[] rhs) {return Diff_1st(lhs, 0, lhs.length, rhs, 0, rhs.length, Byte_ascii.Nl_bry, Byte_ascii.Angle_bgn_bry, 255);}
|
||||
public static byte[][] Diff_1st(byte[] lhs, int lhs_bgn, int lhs_end, byte[] rhs, int rhs_bgn, int rhs_end, byte[] stop, byte[] show, int diff_max) {
|
||||
int lhs_len = lhs_end - lhs_bgn;
|
||||
int rhs_len = rhs_end - rhs_bgn;
|
||||
int len = lhs_len < rhs_len ? lhs_len : rhs_len;
|
||||
int lhs_idx = -1, rhs_idx = -1;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
byte lhs_byte = lhs[i + lhs_bgn];
|
||||
byte rhs_byte = rhs[i + rhs_bgn];
|
||||
if (lhs_byte != rhs_byte) {lhs_idx = rhs_idx = i; break;} // diff; stop iterating
|
||||
}
|
||||
if (lhs_idx == -1 && rhs_idx == -1) {
|
||||
switch (Int_.Compare(lhs_len, rhs_len)) {
|
||||
case CompareAble_.Same: return null;
|
||||
case CompareAble_.Less: lhs_idx = rhs_idx = lhs_len; break;
|
||||
case CompareAble_.More: lhs_idx = rhs_idx = rhs_len; break;
|
||||
}
|
||||
}
|
||||
byte[] lhs_diff = Get_1st(stop, show, lhs, lhs_idx, lhs_len, diff_max);
|
||||
byte[] rhs_diff = Get_1st(stop, show, rhs, rhs_idx, rhs_len, diff_max);
|
||||
return new byte[][] {lhs_diff, rhs_diff};
|
||||
}
|
||||
private static byte[] Get_1st(byte[] stop, byte[] show, byte[] src, int bgn, int end, int diff_max) {
|
||||
if (bgn == end) return Bry__eos;
|
||||
int prv_show = Bry_find_.Find_bwd(src, show, bgn , 0); if (prv_show == Bry_find_.Not_found) prv_show = 0;
|
||||
int prv_stop = Bry_find_.Find_bwd(src, stop, bgn , 0); prv_stop = (prv_stop == Bry_find_.Not_found) ? 0 : prv_stop + 1;
|
||||
int prv = prv_show > prv_stop ? prv_show : prv_stop;
|
||||
int nxt = Bry_find_.Find_fwd(src, stop, bgn , end); if (nxt == Bry_find_.Not_found) nxt = end;
|
||||
if (nxt - prv > 255) nxt = prv + diff_max;
|
||||
return Bry_.Mid(src, prv, nxt);
|
||||
}
|
||||
private static final byte[] Bry__eos = Bry_.new_a7("<<EOS>>");
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
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_diff_tst {
|
||||
@Before public void init() {} private final Bry_diff_fxt fxt = new Bry_diff_fxt();
|
||||
@Test public void Diff_1st() {
|
||||
fxt.Test__diff_1st("a|b|c" , "a|b|c" , null , null);
|
||||
fxt.Test__diff_1st("a|b|c" , "a|b1|c" , "b" , "b1");
|
||||
fxt.Test__diff_1st("a|b|" , "a|b|c" , "<<EOS>>" , "c");
|
||||
fxt.Test__diff_1st("a|b|c" , "a|b|" , "c" , "<<EOS>>");
|
||||
}
|
||||
@Test public void Diff_1st_show() {
|
||||
fxt.Test__diff_1st("a|b<c>d|e" , "a|b<c>e|e" , "<c>d", "<c>e");
|
||||
}
|
||||
}
|
||||
class Bry_diff_fxt {
|
||||
public void Test__diff_1st(String lhs, String rhs, String expd_lhs, String expd_rhs) {
|
||||
byte[] lhs_src = Bry_.new_u8(lhs);
|
||||
byte[] rhs_src = Bry_.new_u8(rhs);
|
||||
byte[][] actl = Bry_diff_.Diff_1st(lhs_src, 0, lhs_src.length, rhs_src, 0, rhs_src.length, Byte_ascii.Pipe_bry, Byte_ascii.Angle_bgn_bry, 255);
|
||||
if (expd_lhs == null && expd_rhs == null)
|
||||
Tfds.Eq_true(actl == null, "actl not null");
|
||||
else {
|
||||
Tfds.Eq_bry(Bry_.new_u8(expd_lhs), actl[0]);
|
||||
Tfds.Eq_bry(Bry_.new_u8(expd_rhs), actl[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
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 Int_flag_bldr {
|
||||
private int[] pow_ary;
|
||||
public int[] Val_ary() {return val_ary;} private int[] val_ary;
|
||||
public Int_flag_bldr Pow_ary_bld_(int... ary) {
|
||||
this.pow_ary = Int_flag_bldr_.Bld_pow_ary(ary);
|
||||
this.val_ary = new int[pow_ary.length];
|
||||
return this;
|
||||
}
|
||||
public boolean Set_as_bool(int idx, boolean val) {val_ary[idx] = val ? 1 : 0; return val;}
|
||||
public byte Set_as_byte(int idx, byte val) {val_ary[idx] = val; return val;}
|
||||
public int Set_as_int(int idx, int val) {val_ary[idx] = val; return val;}
|
||||
public Int_flag_bldr Set(int idx, boolean val) {Set_as_bool(idx, val); return this;}
|
||||
public Int_flag_bldr Set(int idx, byte val) {Set_as_byte(idx, val); return this;}
|
||||
public Int_flag_bldr Set(int idx, int val) {Set_as_int(idx, val); return this;}
|
||||
public int Get_as_int(int idx) {return val_ary[idx];}
|
||||
public byte Get_as_byte(int idx) {return (byte)val_ary[idx];}
|
||||
public boolean Get_as_bool(int idx) {return val_ary[idx] == 1;}
|
||||
public int Encode() {return Int_flag_bldr_.To_int(pow_ary, val_ary);}
|
||||
public void Decode(int v) {Int_flag_bldr_.To_int_ary(val_ary, pow_ary, v);}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
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 Int_flag_bldr_ {
|
||||
public static int[] Bld_pow_ary(int... ary) {
|
||||
int len = ary.length;
|
||||
int[] rv = new int[len];
|
||||
int pow = 0;
|
||||
for (int i = len - 1; i > -1; --i) {
|
||||
rv[i] = Int_flag_bldr_.Base2_ary[pow];
|
||||
pow += ary[i];
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static int To_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[] To_int_ary(int[] pow_ary, int v) {
|
||||
int[] rv = new int[pow_ary.length];
|
||||
To_int_ary(rv, pow_ary, v);
|
||||
return rv;
|
||||
}
|
||||
public static void To_int_ary(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 To_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 To_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 To_int_date_short(int[] val_ary) {
|
||||
val_ary[0] -= 1900;
|
||||
return Int_flag_bldr_.To_int(Pow_ary_date_short, val_ary);
|
||||
}
|
||||
public static void To_date_short_int_ary(int[] rv, int v) {
|
||||
Int_flag_bldr_.To_int_ary(rv, Pow_ary_date_short, v);
|
||||
rv[0] += 1900;
|
||||
}
|
||||
public static DateAdp To_date_short(int v) {
|
||||
int[] rv = new int[Pow_ary_date_short.length];
|
||||
To_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
|
||||
public 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
|
||||
};
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
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 Int_flag_bldr__tst {
|
||||
private final Int_flag_bldr__fxt fxt = new Int_flag_bldr__fxt();
|
||||
@Test public void Bld_pow_ary() {
|
||||
fxt.Test__bld_pow_ary(fxt.Make__ary(1, 1, 1, 1), fxt.Make__ary(8, 4, 2, 1));
|
||||
fxt.Test__bld_pow_ary(fxt.Make__ary(3, 2) , fxt.Make__ary(4, 1));
|
||||
}
|
||||
@Test public void To_int__1_1_1() {
|
||||
int[] seg_ary = fxt.Make__ary(1, 1, 1);
|
||||
fxt.Test__to_int(seg_ary , fxt.Make__ary(0, 0, 0), 0);
|
||||
fxt.Test__to_int(seg_ary , fxt.Make__ary(1, 1, 1), 7);
|
||||
fxt.Test__to_int(seg_ary , fxt.Make__ary(1, 0, 0), 4);
|
||||
fxt.Test__to_int(seg_ary , fxt.Make__ary(1, 1, 0), 6);
|
||||
fxt.Test__to_int(seg_ary , fxt.Make__ary(0, 1, 1), 3);
|
||||
}
|
||||
@Test public void To_int__2_3() {
|
||||
fxt.Test__to_int(fxt.Make__ary(2, 3) , fxt.Make__ary(3, 7) , 31);
|
||||
fxt.Test__to_int(fxt.Make__ary(1, 2, 3) , fxt.Make__ary(1, 3, 7) , 63);
|
||||
}
|
||||
@Test public void To_int__11_4_5_5_6() {
|
||||
fxt.Test__to_int(fxt.Make__ary(11, 4, 5, 5, 6), fxt.Make__ary(2012, 6, 3, 23, 17), 2110135761);
|
||||
fxt.Test__to_int(fxt.Make__ary(11, 4, 5, 5, 6), fxt.Make__ary(2012, 6, 3, 23, 18), 2110135762);
|
||||
}
|
||||
@Test public void To_int_ary() {
|
||||
fxt.Test__to_int_ary(fxt.Make__ary(1, 1, 1, 1) , 15, fxt.Make__ary(1, 1, 1, 1));
|
||||
fxt.Test__to_int_ary(fxt.Make__ary(3, 2) , 31, fxt.Make__ary(7, 3));
|
||||
fxt.Test__to_int_ary(fxt.Make__ary(3, 2, 1) , 63, fxt.Make__ary(7, 3, 1));
|
||||
fxt.Test__to_int_ary(fxt.Make__ary(12, 4, 5, 5, 6), 2110135761, fxt.Make__ary(2012, 6, 3, 23, 17));
|
||||
fxt.Test__to_int_ary(fxt.Make__ary(12, 4, 5, 5, 6), 2110135762, fxt.Make__ary(2012, 6, 3, 23, 18));
|
||||
}
|
||||
@Test public void To_int_date_short() {
|
||||
fxt.Test__to_int_date_short("20120604 2359", 117843451);
|
||||
fxt.Test__to_int_date_short("20120604 2358", 117843450);
|
||||
fxt.Test__to_int_date_short("20120605 0000", 117843968);
|
||||
}
|
||||
}
|
||||
class Int_flag_bldr__fxt {
|
||||
public int[] Make__ary(int... v) {return v;}
|
||||
public void Test__bld_pow_ary(int[] seg_ary, int[] expd) {Tfds.Eq_ary_str(expd, Int_flag_bldr_.Bld_pow_ary(seg_ary));}
|
||||
public void Test__to_int(int[] seg_ary, int[] val_ary, int expd) {
|
||||
int[] pow_ary = Int_flag_bldr_.Bld_pow_ary(seg_ary);
|
||||
Tfds.Eq(expd, Int_flag_bldr_.To_int(pow_ary, val_ary));
|
||||
int[] actl_val_ary = Int_flag_bldr_.To_int_ary(pow_ary, expd);
|
||||
Tfds.Eq_ary(val_ary, actl_val_ary);
|
||||
}
|
||||
public void Test__to_int_ary(int[] seg_ary, int val, int[] expd) {
|
||||
int[] pow_ary = Int_flag_bldr_.Bld_pow_ary(seg_ary);
|
||||
Tfds.Eq_ary_str(expd, Int_flag_bldr_.To_int_ary(pow_ary, val));
|
||||
}
|
||||
public void Test__to_int_date_short(String date_str, int expd) {
|
||||
DateAdp date = DateAdp_.parse_fmt(date_str, "yyyyMMdd HHmm");
|
||||
int date_int = Int_flag_bldr_.To_int_date_short(date.XtoSegAry());
|
||||
Tfds.Eq(expd, date_int);
|
||||
Tfds.Eq(date_str, Int_flag_bldr_.To_date_short(date_int).XtoStr_fmt("yyyyMMdd HHmm"));
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
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 interface Mid_able {
|
||||
byte[] Mid__src();
|
||||
int Mid__bgn();
|
||||
int Mid__end();
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
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.evals; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
|
||||
public class Bry_eval_mgr {
|
||||
private final Hash_adp_bry hash = Hash_adp_bry.cs();
|
||||
private final byte sym_escape, sym_key_end, sym_grp_bgn, sym_grp_end;
|
||||
public Bry_eval_mgr(byte sym_escape, byte sym_key_end, byte sym_grp_bgn, byte sym_grp_end) {
|
||||
this.sym_escape = sym_escape;
|
||||
this.sym_key_end = sym_key_end;
|
||||
this.sym_grp_bgn = sym_grp_bgn;
|
||||
this.sym_grp_end = sym_grp_end;
|
||||
}
|
||||
public Bry_eval_mgr Add_many(Bry_eval_wkr... ary) {
|
||||
for (Bry_eval_wkr itm : ary)
|
||||
hash.Add(Bry_.new_u8(itm.Key()), itm);
|
||||
return this;
|
||||
}
|
||||
public byte[] Eval(byte[] src) {
|
||||
Bry_eval_rslt rv = Eval_txt(0, src, 0, src.length);
|
||||
return rv == null ? src : rv.Bry();
|
||||
}
|
||||
private Bry_eval_rslt Eval_txt(int depth, byte[] src, int src_bgn, int src_end) {
|
||||
Bry_bfr cur_bfr = null;
|
||||
int cur_pos = src_bgn;
|
||||
while (true) {
|
||||
if (cur_pos == src_end) break;
|
||||
byte cur_byte = src[cur_pos];
|
||||
// cur_byte is ~
|
||||
if (cur_byte == sym_escape) {
|
||||
// create cur_bfr
|
||||
if (cur_bfr == null) {cur_bfr = Bry_bfr_.New(); cur_bfr.Add_mid(src, src_bgn, cur_pos);}
|
||||
|
||||
// eval nxt_byte
|
||||
int nxt_pos = cur_pos + 1;
|
||||
if (nxt_pos == src_end) throw Err_.new_wo_type("bry_eval:escape at eos", "src", src);
|
||||
byte nxt_byte = src[nxt_pos];
|
||||
if (nxt_byte == sym_grp_bgn) { // ~{key|} -> eval;
|
||||
Bry_eval_rslt sub = Eval_txt(depth + 1, src, nxt_pos + 1, src_end); // get "}"
|
||||
cur_bfr.Add(Eval_grp(sub.Bry()));
|
||||
cur_pos = sub.Pos();
|
||||
continue;
|
||||
}
|
||||
else if (nxt_byte == sym_escape) {
|
||||
cur_bfr.Add_byte(nxt_byte);
|
||||
cur_pos = nxt_pos + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (depth > 0 && cur_byte == sym_grp_end) {
|
||||
return cur_bfr == null
|
||||
? new Bry_eval_rslt(Bry_.Mid(src, src_bgn, cur_pos), cur_pos + 1)
|
||||
: new Bry_eval_rslt(cur_bfr.To_bry_and_clear(), cur_pos + 1);
|
||||
}
|
||||
if (cur_bfr != null) cur_bfr.Add_byte(cur_byte);
|
||||
++cur_pos;
|
||||
}
|
||||
return cur_bfr == null ? null : new Bry_eval_rslt(cur_bfr.To_bry_and_clear(), src_end);
|
||||
}
|
||||
private byte[] Eval_grp(byte[] src) {
|
||||
// search for "|" or "}"
|
||||
boolean args_is_empty = true;
|
||||
int src_end = src.length;
|
||||
int key_bgn = 0, key_end = src_end;
|
||||
for (int i = key_bgn; i < src_end; ++i) {
|
||||
int key_end_byte = src[i];
|
||||
if (key_end_byte == sym_key_end) {
|
||||
key_end = i;
|
||||
args_is_empty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get wkr
|
||||
Bry_eval_wkr wkr = (Bry_eval_wkr)hash.Get_by_mid(src, key_bgn, key_end);
|
||||
if (wkr == null) throw Err_.new_wo_type("bry_eval:key not found", "src", src);
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
if (args_is_empty) {
|
||||
wkr.Resolve(bfr, src, -1, -1);
|
||||
}
|
||||
else {
|
||||
wkr.Resolve(bfr, src, key_end + 1, src_end);
|
||||
}
|
||||
return bfr.To_bry_and_clear();
|
||||
}
|
||||
public static Bry_eval_mgr Dflt() {return new Bry_eval_mgr(Byte_ascii.Tilde, Byte_ascii.Pipe, Byte_ascii.Curly_bgn, Byte_ascii.Curly_end);}
|
||||
}
|
||||
class Bry_eval_rslt {
|
||||
public Bry_eval_rslt(byte[] bry, int pos) {
|
||||
this.bry = bry; this.pos = pos;
|
||||
}
|
||||
public byte[] Bry() {return bry;} private final byte[] bry;
|
||||
public int Pos() {return pos;} private final int pos;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
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.evals; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
public class Bry_eval_mgr__tst {
|
||||
private final Bry_eval_mgr__fxt fxt = new Bry_eval_mgr__fxt();
|
||||
@Test public void Text() {fxt.Test__eval("abc" , "abc");}
|
||||
@Test public void Args_0() {fxt.Test__eval("abc~{test}xyz" , "abctestxyz");}
|
||||
@Test public void Args_n() {fxt.Test__eval("abc~{concat|d|e|f}xyz" , "abcdefxyz");}
|
||||
@Test public void Recur_1() {fxt.Test__eval("abc~{~{test}}xyz" , "abctestxyz");}
|
||||
@Test public void Recur_2() {fxt.Test__eval("abc~{t~{concat|e|s}t}xyz" , "abctestxyz");}
|
||||
@Test public void Grp_end() {fxt.Test__eval("a}b" , "a}b");}
|
||||
@Test public void Escape() {fxt.Test__eval("a~~b" , "a~b");}
|
||||
// @Test public void Eos() {fxt.Test__eval("a~" , "a~");}
|
||||
}
|
||||
class Bry_eval_mgr__fxt {
|
||||
private final Bry_eval_mgr mgr = Bry_eval_mgr.Dflt().Add_many(new Bry_eval_wkr__test(), new Bry_eval_wkr__concat());
|
||||
public Bry_eval_mgr__fxt Test__eval(String raw, String expd) {
|
||||
Gftest.Eq__bry(Bry_.new_u8(expd), mgr.Eval(Bry_.new_u8(raw)));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class Bry_eval_wkr__test implements Bry_eval_wkr {
|
||||
public String Key() {return "test";}
|
||||
public void Resolve(Bry_bfr rv, byte[] src, int src_bgn, int src_end) {
|
||||
rv.Add_str_a7("test");
|
||||
}
|
||||
}
|
||||
class Bry_eval_wkr__concat implements Bry_eval_wkr {
|
||||
public String Key() {return "concat";}
|
||||
public void Resolve(Bry_bfr rv, byte[] src, int src_bgn, int src_end) {
|
||||
byte[][] ary = Bry_split_.Split(src, src_bgn, src_end, Byte_ascii.Pipe, false);
|
||||
for (byte[] itm : ary) {
|
||||
rv.Add(itm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
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.evals; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
|
||||
public interface Bry_eval_wkr {
|
||||
String Key();
|
||||
void Resolve(Bry_bfr rv, byte[] src, int args_bgn, int args_end);
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
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_u8_mgr_tst {
|
||||
@Before public void init() {fxt.Clear();} private Btrie_u8_mgr_fxt fxt = new Btrie_u8_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_.New_by_ints(196,176)
|
||||
fxt.Test_match("i" , "1"); // lower=y; i = Bry_.New_by_ints(105)
|
||||
fxt.Test_match("I" , null); // upper=n; I = Bry_.New_by_ints( 73); see Btrie_u8_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("İ" , "1"); // utf_8=y; note that "i" matches "İ" b/c hash is case-insensitive and "İ" lower-cases to "i"; DATE:2015-09-07
|
||||
}
|
||||
@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_u8_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_u8_mgr_fxt {
|
||||
private Btrie_u8_mgr trie;
|
||||
public void Clear() {
|
||||
trie = Btrie_u8_mgr.new_(Xol_case_mgr_.U8());
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
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.caches; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.envs.*;
|
||||
class Gfo_cache_data implements gplx.CompareAble, Rls_able {
|
||||
private int count = 0;
|
||||
public Gfo_cache_data(byte[] key, Rls_able val, int size) {
|
||||
this.key = key; this.val = val;
|
||||
this.size = size;
|
||||
this.count = 1;
|
||||
}
|
||||
public byte[] Key() {return key;} private final byte[] key;
|
||||
public Rls_able Val() {return val;} private Rls_able val;
|
||||
public int Size() {return size;} private int size;
|
||||
|
||||
public Object Val_and_update() {
|
||||
++count;
|
||||
return val;
|
||||
}
|
||||
public void Val_(Rls_able val, int size) {
|
||||
this.val = val;
|
||||
this.size = size;
|
||||
}
|
||||
public int compareTo(Object obj) {
|
||||
Gfo_cache_data comp = (Gfo_cache_data)obj;
|
||||
return -Long_.Compare(count, comp.count); // "-" to sort most-recent first
|
||||
}
|
||||
public void Rls() {
|
||||
val.Rls();
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
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.caches; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cache_mgr {
|
||||
private final Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
private final List_adp tmp_delete = List_adp_.New();
|
||||
public int Cur_size() {return cur_size;} private int cur_size;
|
||||
public int Max_size() {return max_size;} public Gfo_cache_mgr Max_size_(int v) {max_size = v; return this;} private int max_size;
|
||||
public int Reduce_by() {return reduce_by;} public Gfo_cache_mgr Reduce_by_(int v) {reduce_by = v; return this;} private int reduce_by;
|
||||
public void Clear() {
|
||||
synchronized (tmp_delete) {
|
||||
hash.Clear();
|
||||
cur_size = 0;
|
||||
}
|
||||
}
|
||||
public Object Get_by_key(byte[] key) {
|
||||
Object o = hash.Get_by(key);
|
||||
return o == null ? null : ((Gfo_cache_data)o).Val_and_update();
|
||||
}
|
||||
public void Add_replace(byte[] key, Rls_able val, int size) {
|
||||
Object o = hash.Get_by(key);
|
||||
if (o == null)
|
||||
Add(key, val, size);
|
||||
else {
|
||||
Gfo_cache_data itm = (Gfo_cache_data)o;
|
||||
synchronized (itm) {
|
||||
cur_size -= itm.Size();
|
||||
cur_size += size;
|
||||
itm.Val_(val, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Add(byte[] key, Rls_able val, int size) {
|
||||
synchronized (tmp_delete) {
|
||||
if (hash.Has(key)) return; // THREAD: since Get is not locked, it's possible to Add the same item twice
|
||||
cur_size += size;
|
||||
Gfo_cache_data itm = new Gfo_cache_data(key, val, size);
|
||||
hash.Add(key, itm);
|
||||
if (cur_size > max_size) this.Reduce();
|
||||
}
|
||||
}
|
||||
private void Reduce() {
|
||||
hash.Sort();
|
||||
int len = hash.Len();
|
||||
int list_size = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfo_cache_data itm = (Gfo_cache_data)hash.Get_at(i);
|
||||
int new_size = list_size + itm.Size();
|
||||
if (new_size > reduce_by)
|
||||
tmp_delete.Add(itm);
|
||||
else
|
||||
list_size = new_size;
|
||||
}
|
||||
this.cur_size = list_size;
|
||||
len = tmp_delete.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfo_cache_data itm = (Gfo_cache_data)tmp_delete.Get_at(i);
|
||||
hash.Del(itm.Key());
|
||||
}
|
||||
tmp_delete.Clear();
|
||||
}
|
||||
public int Test__len() {return hash.Len();}
|
||||
public Object Test__get_at(int i) {
|
||||
Gfo_cache_data rv = (Gfo_cache_data)hash.Get_at(i);
|
||||
return rv.Val();
|
||||
}
|
||||
// NOTE: not called yet
|
||||
/*
|
||||
public void Del(byte[] key) {
|
||||
Object o = hash.Get_by(key); if (o == null) return;
|
||||
Gfo_cache_data itm = (Gfo_cache_data)o;
|
||||
cur_size -= itm.Size();
|
||||
hash.Del(itm.Key());
|
||||
itm.Rls();
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
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.caches; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cache_mgr_base {
|
||||
private final Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
public int Compress_max() {return compress_max;} public void Compress_max_(int v) {compress_max = v;} private int compress_max = 16;
|
||||
public int Compress_to() {return compress_to;} public void Compress_to_(int v) {compress_to = v;} private int compress_to = 8;
|
||||
protected Object Base_get_or_null(byte[] key) {
|
||||
Object rv_obj = hash.Get_by(key);
|
||||
return rv_obj == null ? null : ((Gfo_cache_itm)rv_obj).Val();
|
||||
}
|
||||
protected void Base_add(byte[] key, Object val) {
|
||||
if (hash.Count() >= compress_max) Compress();
|
||||
Gfo_cache_itm itm = new Gfo_cache_itm(key, val);
|
||||
hash.Add(key, itm);
|
||||
}
|
||||
protected void Base_del(byte[] key) {
|
||||
hash.Del(key);
|
||||
}
|
||||
public void Compress() {
|
||||
hash.Sort_by(Gfo_cache_itm_comparer.Touched_asc);
|
||||
int del_len = hash.Count() - compress_to;
|
||||
List_adp del_list = List_adp_.New();
|
||||
for (int i = 0; i < del_len; i++) {
|
||||
Gfo_cache_itm itm = (Gfo_cache_itm)hash.Get_at(i);
|
||||
del_list.Add(itm);
|
||||
}
|
||||
for (int i = 0; i < del_len; i++) {
|
||||
Gfo_cache_itm itm = (Gfo_cache_itm)del_list.Get_at(i);
|
||||
hash.Del(itm.Key());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
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.caches; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.primitives.*; import gplx.core.envs.*;
|
||||
public class Gfo_cache_mgr_bry extends Gfo_cache_mgr_base {
|
||||
public Object Get_or_null(byte[] key) {return Base_get_or_null(key);}
|
||||
public void Add(byte[] key, Object val) {Base_add(key, val);}
|
||||
public void Del(byte[] key) {Base_del(key);}
|
||||
}
|
||||
class Gfo_cache_itm {
|
||||
public Gfo_cache_itm(Object key, Object val) {this.key = key; this.val = val; this.Touched_update();}
|
||||
public Object Key() {return key;} private Object key;
|
||||
public Object Val() {return val;} private Object val;
|
||||
public long Touched() {return touched;} private long touched;
|
||||
public Gfo_cache_itm Touched_update() {touched = System_.Ticks(); return this;}
|
||||
}
|
||||
class Gfo_cache_itm_comparer implements gplx.core.lists.ComparerAble {
|
||||
public int compare(Object lhsObj, Object rhsObj) {
|
||||
Gfo_cache_itm lhs = (Gfo_cache_itm)lhsObj;
|
||||
Gfo_cache_itm rhs = (Gfo_cache_itm)rhsObj;
|
||||
return Long_.Compare(lhs.Touched(), rhs.Touched());
|
||||
}
|
||||
public static final Gfo_cache_itm_comparer Touched_asc = new Gfo_cache_itm_comparer(); // TS.static
|
||||
}
|
||||
class Io_url_exists_mgr {
|
||||
private gplx.core.caches.Gfo_cache_mgr_bry cache_mgr = new gplx.core.caches.Gfo_cache_mgr_bry();
|
||||
public Io_url_exists_mgr() {
|
||||
cache_mgr.Compress_max_(Int_.Max_value);
|
||||
}
|
||||
public boolean Has(Io_url url) {
|
||||
byte[] url_key = url.RawBry();
|
||||
Object rv_obj = cache_mgr.Get_or_null(url_key);
|
||||
if (rv_obj != null) return ((Bool_obj_ref)rv_obj).Val(); // cached val exists; use it
|
||||
boolean exists = Io_mgr.Instance.ExistsFil(url);
|
||||
cache_mgr.Add(url_key, Bool_obj_ref.new_(exists));
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
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.caches; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.tests.*; import gplx.core.envs.*;
|
||||
public class Gfo_cache_mgr_tst {
|
||||
@Before public void init() {fxt.Clear();} private final Gfo_cache_mgr_fxt fxt = new Gfo_cache_mgr_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Exec__add("a");
|
||||
fxt.Test__cur_size(1);
|
||||
fxt.Test__itms("a");
|
||||
}
|
||||
@Test public void Reduce() {
|
||||
fxt.Exec__add("a", "b", "c", "d", "e");
|
||||
fxt.Test__cur_size(2);
|
||||
fxt.Test__itms("a", "b");
|
||||
}
|
||||
@Test public void Reduce_after_get() {
|
||||
fxt.Exec__add("a", "b", "c", "d");
|
||||
fxt.Exec__get("a", "c");
|
||||
fxt.Exec__add("e");
|
||||
fxt.Test__itms("a", "c");
|
||||
}
|
||||
}
|
||||
class Gfo_cache_mgr_fxt {
|
||||
private final Gfo_cache_mgr mgr = new Gfo_cache_mgr().Max_size_(4).Reduce_by_(2);
|
||||
public void Clear() {mgr.Clear();}
|
||||
public Gfo_cache_mgr_fxt Exec__add(String... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
String itm = ary[i];
|
||||
byte[] key = Bry_.new_u8(itm);
|
||||
mgr.Add(key, new Gfo_cache_itm_mock(itm), key.length);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Gfo_cache_mgr_fxt Exec__get(String... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
String itm = ary[i];
|
||||
mgr.Get_by_key(Bry_.new_u8(itm));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Gfo_cache_mgr_fxt Test__cur_size(int expd) {Gftest.Eq__int(expd, mgr.Cur_size(), "cur_size"); return this;}
|
||||
public Gfo_cache_mgr_fxt Test__itms(String... expd) {
|
||||
int len = mgr.Test__len();
|
||||
String[] actl = new String[len];
|
||||
for (int i = 0; i < len; ++i)
|
||||
actl[i] = ((Gfo_cache_itm_mock)mgr.Test__get_at(i)).Val();
|
||||
Gftest.Eq__ary(expd, actl, "itms");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class Gfo_cache_itm_mock implements Rls_able {
|
||||
public Gfo_cache_itm_mock(String val) {this.val = val;}
|
||||
public String Val() {return val;} private String val;
|
||||
public void Rls() {}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_itm {
|
||||
public Gfo_cmd_arg_itm(int tid, boolean reqd, String key, int val_tid) {this.tid = tid; this.reqd = reqd; this.key = key; this.val_tid = val_tid;}
|
||||
public int Tid() {return tid;} private final int tid;
|
||||
public boolean Reqd() {return reqd;} private final boolean reqd;
|
||||
public String Key() {return key;} private final String key;
|
||||
public int Val_tid() {return val_tid;} private int val_tid;
|
||||
public Object Val() {return val;} public Gfo_cmd_arg_itm Val_(Object v) {this.val = v; dirty = true; return this;} private Object val;
|
||||
public String Note() {return note;} public Gfo_cmd_arg_itm Note_(String v) {note = v; return this;} private String note = "";
|
||||
public String Example() {return example;} public Gfo_cmd_arg_itm Example_(String v) {example = v; return this;} private String example = "";
|
||||
public Object Dflt() {return dflt;} public Gfo_cmd_arg_itm Dflt_(Object v) {dflt = v; return this;} private Object dflt;
|
||||
public boolean Dirty() {return dirty;} private boolean dirty;
|
||||
public void Clear() {
|
||||
dirty = false;
|
||||
val = null;
|
||||
}
|
||||
public Gfo_cmd_arg_itm Example_url_(String v) {
|
||||
Example_(v);
|
||||
this.val_tid = Gfo_cmd_arg_itm_.Val_tid_url;
|
||||
return this;
|
||||
}
|
||||
public String Reqd_str() {return reqd ? "required" : "optional";}
|
||||
public String Val_tid_str() {
|
||||
switch (val_tid) {
|
||||
case Gfo_cmd_arg_itm_.Val_tid_string: return "string";
|
||||
case Gfo_cmd_arg_itm_.Val_tid_yn: return "y/n";
|
||||
case Gfo_cmd_arg_itm_.Val_tid_url: return "path";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
public boolean Val_as_bool() {return Bool_.cast(val);}
|
||||
public String Val_as_str_or(String or) {return val == null ? or : (String)val;}
|
||||
public String Val_as_str() {return (String)val;}
|
||||
public int Val_as_int_or(int or) {return val == null ? or : Int_.parse_or((String)val, or);}
|
||||
public Io_url Val_as_url__rel_dir_or(Io_url owner_dir, Io_url or) {return Val_as_url__rel_url_or(Bool_.Y, owner_dir, or);}
|
||||
public Io_url Val_as_url__rel_fil_or(Io_url owner_dir, Io_url or) {return Val_as_url__rel_url_or(Bool_.N, owner_dir, or);}
|
||||
public Io_url Val_as_url__rel_url_or(boolean to_dir, Io_url owner_dir, Io_url or) {return Gfo_cmd_arg_itm_.Val_as_url__rel_url_or(Val_as_str(), to_dir, owner_dir, or);}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
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.consoles; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.envs.*;
|
||||
public class Gfo_cmd_arg_itm_ {
|
||||
public static final int Tid_general = 0, Tid_system = 1;
|
||||
public static final int Val_tid_string = 0, Val_tid_yn = 1, Val_tid_url = 2, Val_tid_list_string = 3;
|
||||
public static Gfo_cmd_arg_itm req_(String key) {return new Gfo_cmd_arg_itm(Tid_general, Bool_.Y, key, Val_tid_string);}
|
||||
public static Gfo_cmd_arg_itm opt_(String key) {return new Gfo_cmd_arg_itm(Tid_general, Bool_.N, key, Val_tid_string);}
|
||||
public static Gfo_cmd_arg_itm new_(String key, boolean reqd, int val_tid) {return new Gfo_cmd_arg_itm(Tid_general, reqd , key, val_tid);}
|
||||
public static Gfo_cmd_arg_itm sys_(String key) {return new Gfo_cmd_arg_itm(Tid_system , Bool_.N, key, Val_tid_yn);}
|
||||
public static Gfo_cmd_arg_itm new_(int tid, String key, boolean reqd, int val_tid) {return new Gfo_cmd_arg_itm(tid , reqd , key, val_tid);}
|
||||
public static Io_url Val_as_url__rel_url_or(String raw, boolean to_dir, Io_url owner_dir, Io_url or) {
|
||||
if (raw == null) return or;
|
||||
byte val_has_dir = Op_sys.Tid_nil; // if raw is to_dir, use it literally (only checking for closing dir_spr); if it's just a name, assume a simple relative path
|
||||
if (String_.Has(raw, Op_sys.Lnx.Fsys_dir_spr_str()))
|
||||
val_has_dir = Op_sys.Tid_lnx;
|
||||
else if (String_.Has(raw, Op_sys.Wnt.Fsys_dir_spr_str()))
|
||||
val_has_dir = Op_sys.Tid_wnt;
|
||||
if (val_has_dir != Op_sys.Tid_nil) {
|
||||
if (to_dir) { // NOTE: need to do extra logic to guarantee trailing "/"; JAVA:7 apparently strips "/to_dir/" to "/to_dir" when passed in as argument; DATE:2013-03-20
|
||||
String val_dir_spr = val_has_dir == Op_sys.Tid_lnx ? Op_sys.Lnx.Fsys_dir_spr_str() : Op_sys.Wnt.Fsys_dir_spr_str();
|
||||
if (!String_.Has_at_end(raw, val_dir_spr))
|
||||
raw += val_dir_spr;
|
||||
return Io_url_.new_dir_(raw);
|
||||
}
|
||||
else
|
||||
return Io_url_.new_fil_(raw);
|
||||
}
|
||||
else
|
||||
return to_dir ? owner_dir.GenSubDir(raw) : owner_dir.GenSubFil(raw);
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
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.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_mgr {
|
||||
private final Ordered_hash hash = Ordered_hash_.New();
|
||||
private final List_adp err_list = List_adp_.New(), tmp_vals = List_adp_.New();
|
||||
public String[] Orig_ary() {return orig_ary;} private String[] orig_ary;
|
||||
public void Reset() {
|
||||
hash.Clear();
|
||||
this.Clear();
|
||||
}
|
||||
public void Clear() {
|
||||
int len = hash.Count();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfo_cmd_arg_itm itm = (Gfo_cmd_arg_itm)hash.Get_at(i);
|
||||
itm.Clear();
|
||||
}
|
||||
err_list.Clear();
|
||||
}
|
||||
public Gfo_cmd_arg_mgr Reg_many(Gfo_cmd_arg_itm... ary) {for (Gfo_cmd_arg_itm itm : ary) Reg(itm); return this;}
|
||||
public int Len() {return hash.Count();}
|
||||
public boolean Has(String k) {
|
||||
Gfo_cmd_arg_itm arg = (Gfo_cmd_arg_itm)hash.Get_by(k);
|
||||
return arg != null && arg.Dirty();
|
||||
}
|
||||
public boolean Get_by_as_bool(String k) {
|
||||
Gfo_cmd_arg_itm arg = (Gfo_cmd_arg_itm)hash.Get_by(k);
|
||||
return arg != null && arg.Val() != null && arg.Val_as_bool();
|
||||
}
|
||||
public Gfo_cmd_arg_itm Get_at(int i) {return (Gfo_cmd_arg_itm)hash.Get_at(i);}
|
||||
public Gfo_cmd_arg_itm Get_by(String key) {return (Gfo_cmd_arg_itm)hash.Get_by(key);}
|
||||
public void Parse(String[] orig_ary) {
|
||||
this.Clear();
|
||||
this.orig_ary = orig_ary; int orig_len = orig_ary.length;
|
||||
Gfo_cmd_arg_itm cur_itm = null;
|
||||
int orig_idx = 0;
|
||||
while (true) {
|
||||
boolean done = orig_idx == orig_len;
|
||||
String itm = done ? "" : orig_ary[orig_idx++];
|
||||
boolean itm_is_key = String_.Has_at_bgn(itm, Key_prefix); // has "--" -> is key
|
||||
if ( cur_itm != null // pending itm
|
||||
&& (itm_is_key || done)) { // cur arg is key ("--key2"), or all done
|
||||
cur_itm.Val_(Gfo_cmd_arg_mgr_.Parse_ary_to_str(this, cur_itm.Val_tid(), tmp_vals.To_str_ary_and_clear()));
|
||||
cur_itm = null;
|
||||
}
|
||||
if (done) break;
|
||||
if (itm_is_key) {
|
||||
String key = String_.Mid(itm, prefix_len);
|
||||
Object o = hash.Get_by(key); if (o == null) {Errs__add(Gfo_cmd_arg_mgr_.Err__key__unknown , key); continue;}
|
||||
cur_itm = (Gfo_cmd_arg_itm)o; if (cur_itm.Dirty()) {Errs__add(Gfo_cmd_arg_mgr_.Err__key__duplicate , key); continue;}
|
||||
}
|
||||
else {
|
||||
if (cur_itm == null) {Errs__add(Gfo_cmd_arg_mgr_.Err__key__missing, itm); continue;} // should only happen if 1st itm is not "--%"
|
||||
tmp_vals.Add(itm);
|
||||
}
|
||||
}
|
||||
|
||||
// calc .Reqd and .Dflt
|
||||
int len = hash.Count();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
cur_itm = (Gfo_cmd_arg_itm)hash.Get_at(i);
|
||||
if (!cur_itm.Dirty()) { // arg not passed
|
||||
if (cur_itm.Reqd()) // arg required but no value passed; add error
|
||||
Errs__add(Gfo_cmd_arg_mgr_.Err__val__required, cur_itm.Key());
|
||||
else if (cur_itm.Dflt() != null) // arg has default
|
||||
cur_itm.Val_(cur_itm.Dflt());
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean Errs__exist() {return err_list.Count() > 0;}
|
||||
public void Errs__add(String key, String val) {err_list.Add(key + ": " + val);}
|
||||
public String[] Errs__to_str_ary() {return err_list.To_str_ary();}
|
||||
public Gfo_cmd_arg_itm[] To_ary() {return (Gfo_cmd_arg_itm[])hash.To_ary(Gfo_cmd_arg_itm.class);}
|
||||
private void Reg(Gfo_cmd_arg_itm defn) {hash.Add(defn.Key(), defn);}
|
||||
public static final String Key_prefix = "--"; private static final int prefix_len = 2;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
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.consoles; import gplx.*; import gplx.core.*;
|
||||
class Gfo_cmd_arg_mgr_ {
|
||||
public static final String
|
||||
Err__key__unknown = "unknown key"
|
||||
, Err__key__duplicate = "duplicate key"
|
||||
, Err__key__missing = "first argument must be prefixed with --"
|
||||
, Err__val__required = "value is required"
|
||||
, Err__val__invalid__yn = "value must be either y or n"
|
||||
;
|
||||
public static Object Parse_ary_to_str(Gfo_cmd_arg_mgr mgr, int val_tid, String[] ary) {
|
||||
String itm = ary.length == 0 ? "" : ary[0];
|
||||
switch (val_tid) {
|
||||
case Gfo_cmd_arg_itm_.Val_tid_string: return itm;
|
||||
case Gfo_cmd_arg_itm_.Val_tid_url: return itm; // NOTE: do not parse urls as it can either be absolute (C:\dir\fil.txt) or relative (fil.txt). relative cannot be parsed without knowing owner dir
|
||||
case Gfo_cmd_arg_itm_.Val_tid_yn:
|
||||
int itm_as_int = Yn.parse_as_int(itm);
|
||||
if (itm_as_int == Bool_.__int) {
|
||||
mgr.Errs__add(Gfo_cmd_arg_mgr_.Err__val__invalid__yn, itm);
|
||||
return null;
|
||||
}
|
||||
return itm_as_int == Bool_.Y_int;
|
||||
default: throw Err_.new_unhandled(val_tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
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.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_mgr_printer {
|
||||
private final Gfo_cmd_arg_mgr arg_mgr;
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
|
||||
public Gfo_cmd_arg_mgr_printer(Gfo_cmd_arg_mgr arg_mgr) {this.arg_mgr = arg_mgr;}
|
||||
public boolean Print(Gfo_usr_dlg usr_dlg, String header, String app_name, String key__print_help, String key__print_header, String key__print_args) {
|
||||
if (arg_mgr.Get_by_as_bool(key__print_header))
|
||||
usr_dlg.Note_gui_none("", "", header);
|
||||
if (arg_mgr.Errs__exist()) {
|
||||
usr_dlg.Note_none("", "", Get_args());
|
||||
usr_dlg.Note_none("", "", Get_fail());
|
||||
usr_dlg.Note_none("", "", Get_help(app_name));
|
||||
return false;
|
||||
}
|
||||
if (arg_mgr.Has(key__print_help)) {
|
||||
usr_dlg.Note_none("", "", Get_help(app_name));
|
||||
return false;
|
||||
}
|
||||
if (arg_mgr.Get_by_as_bool(key__print_args))
|
||||
usr_dlg.Note_none("", "", Get_args());
|
||||
return true;
|
||||
}
|
||||
public String Get_args() {
|
||||
tmp_bfr.Add_byte_nl();
|
||||
tmp_bfr.Add_str_a7_w_nl("arguments:");
|
||||
String[] orig_ary = arg_mgr.Orig_ary();
|
||||
int len = orig_ary.length;
|
||||
if (len == 0) {
|
||||
tmp_bfr.Add_str_a7_w_nl(" **** NONE ****");
|
||||
tmp_bfr.Add_str_a7_w_nl(" use --help to show help");
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
String line = String_.Format(" [{0}] = '{1}'", i, orig_ary[i]);
|
||||
tmp_bfr.Add_str_u8_w_nl(line);
|
||||
}
|
||||
}
|
||||
return tmp_bfr.To_str_and_clear();
|
||||
}
|
||||
public String Get_fail() {
|
||||
tmp_bfr.Add_str_a7_w_nl("** error: ");
|
||||
String[] err_ary = arg_mgr.Errs__to_str_ary();
|
||||
int len = err_ary.length;
|
||||
for (int i = 0; i < len; ++i)
|
||||
tmp_bfr.Add_str_u8_w_nl(" " + err_ary[i]);
|
||||
tmp_bfr.Add_byte_nl();
|
||||
tmp_bfr.Add_str_a7_w_nl(String_.Repeat("-", 80));
|
||||
return tmp_bfr.To_str_and_clear();
|
||||
}
|
||||
public String Get_help(String app_name) {
|
||||
tmp_bfr.Add_str_a7_w_nl("example:");
|
||||
tmp_bfr.Add_str_a7(String_.Format(" java -jar {0}.jar", app_name));
|
||||
int key_max = 0, tid_max = 0;
|
||||
int len = arg_mgr.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_cmd_arg_itm arg = arg_mgr.Get_at(i); if (arg.Tid() != Gfo_cmd_arg_itm_.Tid_general) continue; // skip header, help
|
||||
tmp_bfr.Add_str_a7(" ").Add_str_a7(Gfo_cmd_arg_mgr.Key_prefix).Add_str_u8(arg.Key()).Add_str_a7(" ").Add_str_u8(arg.Example());
|
||||
int key_len = String_.Len(arg.Key()); if (key_len > key_max) key_max = key_len;
|
||||
int tid_len = String_.Len(String_.Format("[{0}:{1}]", arg.Reqd_str(), arg.Val_tid_str())); if (tid_len > tid_max) tid_max = tid_len;
|
||||
}
|
||||
tmp_bfr.Add_byte_nl().Add_byte_nl();
|
||||
tmp_bfr.Add_str_a7_w_nl("detail:");
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_cmd_arg_itm arg = (Gfo_cmd_arg_itm)arg_mgr.Get_at(i);
|
||||
tmp_bfr.Add_str_a7(" ").Add_str_a7(Gfo_cmd_arg_mgr.Key_prefix)
|
||||
.Add_str_u8(String_.PadEnd(arg.Key(), key_max + 1, " "))
|
||||
.Add_str_u8(String_.PadEnd(String_.Format("[{0}:{1}]", arg.Reqd_str(), arg.Val_tid_str()), tid_max, " "));
|
||||
if (arg.Dflt() != null) {
|
||||
String dflt_val = Object_.Xto_str_strict_or_null_mark(arg.Dflt());
|
||||
tmp_bfr.Add_str_u8(String_.Format(" default={0}", dflt_val));
|
||||
}
|
||||
tmp_bfr.Add_byte_nl();
|
||||
if (arg.Note() != null)
|
||||
tmp_bfr.Add_str_a7(" ").Add_str_u8(arg.Note()).Add_byte_nl();
|
||||
}
|
||||
return tmp_bfr.To_str_and_clear();
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
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.consoles; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.tests.*; import gplx.core.envs.*;
|
||||
public class Gfo_cmd_arg_mgr_tst {
|
||||
@Before public void init() {fxt.Clear();} private final Gfo_cmd_arg_mgr_fxt fxt = new Gfo_cmd_arg_mgr_fxt();
|
||||
@Test public void Val__many() {
|
||||
fxt.Init_args(fxt.Make_arg("a"), fxt.Make_arg("b"));
|
||||
fxt.Exec_process("--a", "0", "--b", "1");
|
||||
fxt.Test_errs_none();
|
||||
fxt.Test_actl(fxt.Make_chkr("a", "0"), fxt.Make_chkr("b", "1"));
|
||||
}
|
||||
@Test public void Val__yn() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Gfo_cmd_arg_itm_.Val_tid_yn), fxt.Make_arg("b", Gfo_cmd_arg_itm_.Val_tid_yn));
|
||||
fxt.Exec_process("--a", "y", "--b", "n");
|
||||
fxt.Test_errs_none();
|
||||
fxt.Test_actl(fxt.Make_chkr("a", Bool_.Y), fxt.Make_chkr("b", Bool_.N));
|
||||
}
|
||||
@Test public void Dflt() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Gfo_cmd_arg_itm_.Val_tid_yn).Dflt_(Bool_.Y));
|
||||
fxt.Exec_process("--a", "n").Test_actl(fxt.Make_chkr("a", Bool_.N)); // if val, use it
|
||||
fxt.Exec_process() .Test_actl(fxt.Make_chkr("a", Bool_.Y)); // if no val, use default
|
||||
}
|
||||
@Test public void Err__key__unknown() {
|
||||
fxt.Init_args(fxt.Make_arg("a"));
|
||||
fxt.Exec_process("--b");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__key__unknown);
|
||||
}
|
||||
@Test public void Err__key__missing() {
|
||||
fxt.Init_args(fxt.Make_arg("a"));
|
||||
fxt.Exec_process("a");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__key__missing);
|
||||
}
|
||||
@Test public void Err__key__dupe() {
|
||||
fxt.Init_args(fxt.Make_arg("a"));
|
||||
fxt.Exec_process("--a", "0", "--a", "0");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__key__duplicate);
|
||||
}
|
||||
@Test public void Err__val__reqd() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Bool_.Y), fxt.Make_arg("b", Bool_.N));
|
||||
fxt.Exec_process("--b", "1");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__val__required);
|
||||
}
|
||||
@Test public void Err__val__parse__yn() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Gfo_cmd_arg_itm_.Val_tid_yn));
|
||||
fxt.Exec_process("--a", "x");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__val__invalid__yn);
|
||||
}
|
||||
@Test public void Val_as_url_rel_dir_or() { // PURPOSE: "/xowa" -> "/xowa/"
|
||||
String root_dir = Op_sys.Cur().Tid_is_wnt() ? "C:\\" : "/", dir_spr = Op_sys.Cur().Fsys_dir_spr_str();
|
||||
fxt.Test_val_as_url_rel_dir_or(root_dir, dir_spr, root_dir + "sub" , root_dir + "sub" + dir_spr); // /sub -> /sub/
|
||||
fxt.Test_val_as_url_rel_dir_or(root_dir, dir_spr, root_dir + "sub" + dir_spr , root_dir + "sub" + dir_spr); // /sub/ -> /sub/
|
||||
fxt.Test_val_as_url_rel_dir_or(root_dir, dir_spr, "sub" , root_dir + "dir" + dir_spr + "sub" + dir_spr); // sub -> /dir/sub/
|
||||
}
|
||||
}
|
||||
class Gfo_cmd_arg_mgr_fxt {
|
||||
private final Tst_mgr tst_mgr = new Tst_mgr();
|
||||
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} Gfo_usr_dlg usr_dlg;
|
||||
public Gfo_cmd_arg_mgr Mgr() {return mgr;} private final Gfo_cmd_arg_mgr mgr = new Gfo_cmd_arg_mgr();
|
||||
public Gfo_cmd_arg_mgr_fxt Clear() {
|
||||
if (usr_dlg == null)
|
||||
usr_dlg = Gfo_usr_dlg_.Test();
|
||||
mgr.Reset();
|
||||
usr_dlg.Gui_wkr().Clear();
|
||||
return this;
|
||||
}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key) {return Make_arg(key, false);}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key, int tid) {return Make_arg(key, false, tid);}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key, boolean reqd) {return Gfo_cmd_arg_itm_.new_(key, reqd, Gfo_cmd_arg_itm_.Val_tid_string);}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key, boolean reqd, int tid) {return Gfo_cmd_arg_itm_.new_(key, reqd, tid);}
|
||||
public Gfo_cmd_itm_chkr Make_chkr(String key, Object val) {return new Gfo_cmd_itm_chkr(key, val);}
|
||||
public Gfo_cmd_arg_mgr_fxt Init_args(Gfo_cmd_arg_itm... v) {mgr.Reg_many(v); return this;}
|
||||
public Gfo_cmd_arg_mgr_fxt Exec_process(String... v) {mgr.Parse(v); return this;}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_actl(Gfo_cmd_itm_chkr... expd) {
|
||||
Gfo_cmd_arg_itm[] actl = mgr.To_ary();
|
||||
tst_mgr.Tst_ary("", expd, actl);
|
||||
return this;
|
||||
}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_errs_none() {return Test_errs(String_.Ary_empty);}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_errs(String... expd) {
|
||||
String[] actl = mgr.Errs__to_str_ary();
|
||||
int len = actl.length;
|
||||
for (int i = 0; i < len; ++i) { // extract key part; EX: "unknown key: abc" -> unknown key
|
||||
actl[i] = String_.GetStrBefore(actl[i], ":");
|
||||
}
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
return this;
|
||||
}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_write(String... expd) {
|
||||
Tfds.Eq_ary_str(expd, ((Gfo_usr_dlg__gui_test)usr_dlg.Gui_wkr()).Msgs().To_str_ary_and_clear());
|
||||
return this;
|
||||
}
|
||||
public void Test_val_as_url_rel_dir_or(String root_dir, String dir_spr, String val, String expd) {
|
||||
Io_url actl = Make_arg("key").Val_(val).Val_as_url__rel_dir_or(Io_url_.new_dir_(root_dir).GenSubDir("dir"), null);
|
||||
Tfds.Eq(expd, actl.Raw());
|
||||
}
|
||||
}
|
||||
class Gfo_cmd_itm_chkr implements Tst_chkr {
|
||||
public Gfo_cmd_itm_chkr(String key, Object val) {this.key = key; this.val = val;} private String key; Object val;
|
||||
public Class<?> TypeOf() {return Gfo_cmd_arg_itm.class;}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Gfo_cmd_arg_itm actl = (Gfo_cmd_arg_itm)actl_obj;
|
||||
int err = 0;
|
||||
err += mgr.Tst_val(false, path, "key", key, actl.Key());
|
||||
err += mgr.Tst_val(false, path, "val", val, actl.Val());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
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.Null;
|
||||
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.Null;
|
||||
for (int i = 0; i < 256; i++)
|
||||
encode_regy[i] = Byte_ascii.Null;
|
||||
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.Null, 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.Null)
|
||||
.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_a7("\\Z")
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
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.core.encoders.*;
|
||||
public class Gfo_fld_rdr extends Gfo_fld_base {
|
||||
private Bry_bfr bfr = Bry_bfr_.New();
|
||||
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_.To_int_by_bry(data, fld_bgn, fld_end);}
|
||||
public int Read_int_base85_len5() {fld_bgn = pos; fld_end = pos + 4 ; pos = pos + 6 ; return Base85_.To_int_by_bry(data, fld_bgn, fld_end);}
|
||||
public int Read_int() {Move_next_simple(); return Bry_.To_int_or(data, fld_bgn, fld_end, -1);}
|
||||
public byte Read_int_as_byte() {Move_next_simple(); return (byte)Bry_.To_int_or(data, fld_bgn, fld_end, -1);}
|
||||
public byte Read_byte() {Move_next_simple(); return data[fld_bgn];}
|
||||
public double Read_double() {Move_next_simple(); return Bry_.To_double(data, fld_bgn, fld_end);}
|
||||
public DateAdp Read_dte() {// NOTE: fmt = yyyyMMdd HHmmss.fff
|
||||
int y = 0, M = 0, d = 0, H = 0, m = 0, s = 0, f = 0;
|
||||
if (pos < data_len && data[pos] == row_dlm) {++pos; ++row_idx; fld_idx = 0;} fld_bgn = pos;
|
||||
y += (data[fld_bgn + 0] - Byte_ascii.Num_0) * 1000;
|
||||
y += (data[fld_bgn + 1] - Byte_ascii.Num_0) * 100;
|
||||
y += (data[fld_bgn + 2] - Byte_ascii.Num_0) * 10;
|
||||
y += (data[fld_bgn + 3] - Byte_ascii.Num_0);
|
||||
M += (data[fld_bgn + 4] - Byte_ascii.Num_0) * 10;
|
||||
M += (data[fld_bgn + 5] - Byte_ascii.Num_0);
|
||||
d += (data[fld_bgn + 6] - Byte_ascii.Num_0) * 10;
|
||||
d += (data[fld_bgn + 7] - Byte_ascii.Num_0);
|
||||
H += (data[fld_bgn + 9] - Byte_ascii.Num_0) * 10;
|
||||
H += (data[fld_bgn + 10] - Byte_ascii.Num_0);
|
||||
m += (data[fld_bgn + 11] - Byte_ascii.Num_0) * 10;
|
||||
m += (data[fld_bgn + 12] - Byte_ascii.Num_0);
|
||||
s += (data[fld_bgn + 13] - Byte_ascii.Num_0) * 10;
|
||||
s += (data[fld_bgn + 14] - Byte_ascii.Num_0);
|
||||
f += (data[fld_bgn + 16] - Byte_ascii.Num_0) * 100;
|
||||
f += (data[fld_bgn + 17] - Byte_ascii.Num_0) * 10;
|
||||
f += (data[fld_bgn + 18] - Byte_ascii.Num_0);
|
||||
if (data[fld_bgn + 19] != fld_dlm) throw Err_.new_wo_type("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 Err_.new_wo_type("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.To_bry_and_clear());}
|
||||
public byte[] Read_bry_escape() {Move_next_escaped(bfr); return bfr.To_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_wo_type("escape char at end of String");
|
||||
b = data[i];
|
||||
byte escape_val = decode_regy[b];
|
||||
if (escape_val == Byte_ascii.Null) {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.Null) {
|
||||
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();}
|
||||
private static final byte[] Bry_nil = Bry_.new_a7("\\0");
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
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.core.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.To_str());
|
||||
return this;
|
||||
} private Bry_bfr bfr = Bry_bfr_.New();
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
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.core.ios.*; import gplx.core.encoders.*;
|
||||
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_.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_.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.Null) 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.Instance.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();}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
public class Gfobj_ary implements Gfobj_grp { // NOTE: items in array can vary in types; EX:['a', 1, false]
|
||||
public Gfobj_ary(Object[] ary) {this.ary = ary;}
|
||||
public byte Grp_tid() {return Gfobj_grp_.Grp_tid__ary;}
|
||||
public int Len() {return ary.length;}
|
||||
public Object Get_at(int i) {return ary[i];}
|
||||
public Object[] Ary_obj() {return ary;} private Object[] ary;
|
||||
public Gfobj_ary Ary_(Object[] v) {this.ary = v; return this;}
|
||||
public Gfobj_nde New_nde_at(int i) {
|
||||
Gfobj_nde rv = Gfobj_nde.New();
|
||||
ary[i] = rv;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
public interface Gfobj_fld {
|
||||
byte Fld_tid();
|
||||
String Key();
|
||||
Object As_obj();
|
||||
}
|
||||
class Gfobj_fld_ {
|
||||
public static final byte
|
||||
Fld_tid__ary = 0
|
||||
, Fld_tid__nde = 1
|
||||
, Fld_tid__bool = 2
|
||||
, Fld_tid__int = 3
|
||||
, Fld_tid__long = 4
|
||||
, Fld_tid__double = 5
|
||||
, Fld_tid__str = 6
|
||||
;
|
||||
}
|
||||
class Gfobj_fld_str implements Gfobj_fld {
|
||||
public Gfobj_fld_str(String key, String val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__str;}
|
||||
public Object As_obj() {return val;}
|
||||
public String As_str() {return val;} private String val;
|
||||
}
|
||||
class Gfobj_fld_bool implements Gfobj_fld {
|
||||
public Gfobj_fld_bool(String key, boolean val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__bool;}
|
||||
public Object As_obj() {return val;}
|
||||
public boolean As_bool() {return val;} private boolean val;
|
||||
}
|
||||
class Gfobj_fld_int implements Gfobj_fld {
|
||||
public Gfobj_fld_int(String key, int val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__int;}
|
||||
public Object As_obj() {return val;}
|
||||
public int As_int() {return val;} private int val;
|
||||
}
|
||||
class Gfobj_fld_long implements Gfobj_fld {
|
||||
public Gfobj_fld_long(String key, long val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__long;}
|
||||
public Object As_obj() {return val;}
|
||||
public long As_long() {return val;} private long val;
|
||||
}
|
||||
class Gfobj_fld_double implements Gfobj_fld {
|
||||
public Gfobj_fld_double(String key, double val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__double;}
|
||||
public Object As_obj() {return val;}
|
||||
public double As_double() {return val;} private double val;
|
||||
}
|
||||
class Gfobj_fld_nde implements Gfobj_fld {
|
||||
public Gfobj_fld_nde(String key, Gfobj_nde val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__nde;}
|
||||
public Object As_obj() {return val;}
|
||||
public Gfobj_nde As_nde() {return val;} private Gfobj_nde val;
|
||||
}
|
||||
class Gfobj_fld_ary implements Gfobj_fld {
|
||||
public Gfobj_fld_ary(String key, Gfobj_ary val) {this.key = key; this.val = val;}
|
||||
public String Key() {return key;} private final String key;
|
||||
public byte Fld_tid() {return Gfobj_fld_.Fld_tid__ary;}
|
||||
public Object As_obj() {return val;}
|
||||
public Gfobj_ary As_ary() {return val;} private Gfobj_ary val;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
public interface Gfobj_grp {
|
||||
byte Grp_tid();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
class Gfobj_grp_ {
|
||||
public static final byte
|
||||
Grp_tid__ary = 0
|
||||
, Grp_tid__nde = 1
|
||||
;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
public class Gfobj_nde implements Gfobj_grp {
|
||||
private Ordered_hash subs;
|
||||
public byte Grp_tid() {return Gfobj_grp_.Grp_tid__nde;}
|
||||
public int Len() {return subs == null ? 0 : subs.Len();}
|
||||
public Gfobj_fld Get_at(int i) {return subs == null ? null : (Gfobj_fld)subs.Get_at(i);}
|
||||
public Gfobj_fld Get_by(String k) {return subs == null ? null : (Gfobj_fld)subs.Get_by(k);}
|
||||
public Gfobj_ary Get_ary(String k) {return ((Gfobj_fld_ary)Get_by(k)).As_ary();}
|
||||
public Gfobj_nde Get_nde(int i) {return ((Gfobj_fld_nde)Get_at(i)).As_nde();}
|
||||
public Gfobj_nde Get_nde(String k) {return ((Gfobj_fld_nde)Get_by(k)).As_nde();}
|
||||
public long Get_long(String k) {
|
||||
Gfobj_fld fld = Get_by(k);
|
||||
switch (fld.Fld_tid()) {
|
||||
case Gfobj_fld_.Fld_tid__long: return ((Gfobj_fld_long)fld).As_long();
|
||||
case Gfobj_fld_.Fld_tid__int : return ((Gfobj_fld_int )fld).As_int();
|
||||
default: throw Err_.new_unhandled_default(fld.Fld_tid());
|
||||
}
|
||||
}
|
||||
public int Get_int(String k) {
|
||||
Gfobj_fld fld = Get_by(k);
|
||||
switch (fld.Fld_tid()) {
|
||||
case Gfobj_fld_.Fld_tid__int : return ((Gfobj_fld_int )fld).As_int();
|
||||
default: throw Err_.new_unhandled_default(fld.Fld_tid());
|
||||
}
|
||||
}
|
||||
public byte Get_byte(String k) {return (byte)Get_int(k);}
|
||||
public String Get_str(String k) {return ((Gfobj_fld_str)Get_by(k)).As_str();}
|
||||
public Io_url Get_url(String k) {return Io_url_.new_any_(((Gfobj_fld_str)Get_by(k)).As_str());}
|
||||
public Gfobj_nde Add_fld(Gfobj_fld fld) {if (subs == null) subs = Ordered_hash_.New(); subs.Add(fld.Key(), fld); return this;}
|
||||
public Gfobj_nde Add_bool(String key, boolean val) {return Add_fld(new Gfobj_fld_bool(key, val));}
|
||||
public Gfobj_nde Add_byte(String key, byte val) {return Add_fld(new Gfobj_fld_int(key, val));}
|
||||
public Gfobj_nde Add_int(String key, int val) {return Add_fld(new Gfobj_fld_int(key, val));}
|
||||
public Gfobj_nde Add_long(String key, long val) {return Add_fld(new Gfobj_fld_long(key, val));}
|
||||
public Gfobj_nde Add_str(String key, String val) {return Add_fld(new Gfobj_fld_str(key, val));}
|
||||
public Gfobj_nde Add_url(String key, Io_url val) {return Add_fld(new Gfobj_fld_str(key, val.Raw()));}
|
||||
public Gfobj_nde Add_double(String key, double val) {return Add_fld(new Gfobj_fld_double(key, val));}
|
||||
public Gfobj_nde Add_nde(String key, Gfobj_nde val) {return Add_fld(new Gfobj_fld_nde(key, val));}
|
||||
public Gfobj_nde Add_ary(String key, Gfobj_ary val) {return Add_fld(new Gfobj_fld_ary(key, val));}
|
||||
public Gfobj_nde New_nde(String key) {Gfobj_nde rv = new Gfobj_nde(); Add_fld(new Gfobj_fld_nde(key, rv)); return rv;}
|
||||
public Gfobj_ary New_ary(String key) {Gfobj_ary rv = new Gfobj_ary(null); Add_fld(new Gfobj_fld_ary(key, rv)); return rv;}
|
||||
public Gfobj_ary New_ary(String key, int subs_len) {return New_ary(key).Ary_(new Object[subs_len]);}
|
||||
public static Gfobj_nde New() {return new Gfobj_nde();}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
import gplx.langs.jsons.*;
|
||||
public class Gfobj_rdr__json {
|
||||
private final Json_parser parser = new Json_parser();
|
||||
public Gfobj_grp Load(Io_url url) {
|
||||
byte[] src = Io_mgr.Instance.LoadFilBryOrNull(url); if (src == null) return null;
|
||||
return this.Parse(src);
|
||||
}
|
||||
public Gfobj_grp Parse(byte[] src) {
|
||||
Json_doc jdoc = parser.Parse(src);
|
||||
if (jdoc.Root_grp().Tid() == Json_itm_.Tid__nde) {
|
||||
Gfobj_nde rv_nde = Gfobj_nde.New();
|
||||
Parse_nde((Json_nde)jdoc.Root_grp(), rv_nde);
|
||||
return rv_nde;
|
||||
}
|
||||
else {
|
||||
Gfobj_ary rv_ary = new Gfobj_ary(null);
|
||||
Parse_ary((Json_ary)jdoc.Root_grp(), rv_ary);
|
||||
return rv_ary;
|
||||
}
|
||||
}
|
||||
private void Parse_nde(Json_nde jnde, Gfobj_nde gnde) {
|
||||
int len = jnde.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Json_kv kv = jnde.Get_at_as_kv(i);
|
||||
String key_str = kv.Key_as_str();
|
||||
Json_itm val = kv.Val();
|
||||
byte val_tid = val.Tid();
|
||||
switch (val_tid) {
|
||||
case Json_itm_.Tid__str: gnde.Add_str (key_str, ((Json_itm_str)val).Data_as_str()); break;
|
||||
case Json_itm_.Tid__bool: gnde.Add_bool (key_str, ((Json_itm_bool)val).Data_as_bool()); break;
|
||||
case Json_itm_.Tid__int: gnde.Add_int (key_str, ((Json_itm_int)val).Data_as_int()); break;
|
||||
case Json_itm_.Tid__long: gnde.Add_long (key_str, ((Json_itm_long)val).Data_as_long()); break;
|
||||
case Json_itm_.Tid__decimal: gnde.Add_double (key_str, ((Json_itm_decimal)val).Data_as_decimal().To_double()); break;
|
||||
case Json_itm_.Tid__null: gnde.Add_str (key_str, null); break;
|
||||
case Json_itm_.Tid__ary:
|
||||
Gfobj_ary sub_ary = new Gfobj_ary(null);
|
||||
gnde.Add_ary(key_str, sub_ary);
|
||||
Parse_ary(Json_ary.cast(val), sub_ary);
|
||||
break;
|
||||
case Json_itm_.Tid__nde:
|
||||
Gfobj_nde sub_gnde = Gfobj_nde.New();
|
||||
gnde.Add_nde(key_str, sub_gnde);
|
||||
Parse_nde(Json_nde.cast(val), sub_gnde);
|
||||
break;
|
||||
default: throw Err_.new_unhandled_default(val_tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Parse_ary(Json_ary jry, Gfobj_ary gry) {
|
||||
int len = jry.Len();
|
||||
Object[] ary = new Object[len];
|
||||
gry.Ary_(ary);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Json_itm jsub = jry.Get_at(i);
|
||||
switch (jsub.Tid()) {
|
||||
case Json_itm_.Tid__ary: {
|
||||
Gfobj_ary sub_ary = new Gfobj_ary(null);
|
||||
Parse_ary(Json_ary.cast(jsub), sub_ary);
|
||||
ary[i] = sub_ary;
|
||||
break;
|
||||
}
|
||||
case Json_itm_.Tid__nde: {
|
||||
Gfobj_nde sub_ary = Gfobj_nde.New();
|
||||
Parse_nde(Json_nde.cast(jsub), sub_ary);
|
||||
ary[i] = sub_ary;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ary[i] = jsub.Data();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
import gplx.langs.jsons.*;
|
||||
public class Gfobj_rdr__json_tst {
|
||||
private final Gfobj_wtr__json_fxt fxt = new Gfobj_wtr__json_fxt();
|
||||
@Test public void Type() {
|
||||
fxt.Test__parse(String_.Concat_lines_nl_skip_last
|
||||
( "{ 'k1':true"
|
||||
, ", 'k2':123"
|
||||
, ", 'k3':9876543210"
|
||||
, ", 'k4':1.23"
|
||||
, ", 'k5':null"
|
||||
, ", 'k6':'abc'"
|
||||
, "}"
|
||||
)
|
||||
, fxt.Make__nde
|
||||
( fxt.Make__fld_bool ("k1", true)
|
||||
, fxt.Make__fld_int ("k2", 123)
|
||||
, fxt.Make__fld_long ("k3", 9876543210L)
|
||||
, fxt.Make__fld_double ("k4", 1.23)
|
||||
, fxt.Make__fld_str ("k5", null)
|
||||
, fxt.Make__fld_str ("k6", "abc")
|
||||
));
|
||||
}
|
||||
@Test public void Nested() {
|
||||
fxt.Test__parse(String_.Concat_lines_nl_skip_last
|
||||
( "{ 'a1':'1a'"
|
||||
, ", 'a2':"
|
||||
, " { 'b1':'1b'"
|
||||
, " , 'b2':"
|
||||
, " { 'c1':'1c'"
|
||||
, " }"
|
||||
, " }"
|
||||
, ", 'a3':[1, 2, 3]"
|
||||
, "}"
|
||||
)
|
||||
, fxt.Make__nde
|
||||
( fxt.Make__fld_str ("a1", "1a")
|
||||
, fxt.Make__fld_nde ("a2"
|
||||
, fxt.Make__fld_str("b1", "1b")
|
||||
, fxt.Make__fld_nde("b2"
|
||||
, fxt.Make__fld_str("c1", "1c"))
|
||||
)
|
||||
, fxt.Make__fld_ary ("a3", 1, 2, 3)
|
||||
));
|
||||
}
|
||||
@Test public void Array() {
|
||||
fxt.Test__parse(String_.Concat_lines_nl_skip_last
|
||||
( "["
|
||||
, " [1, 2, 3]"
|
||||
, ", ['a', 'b', 'c']"
|
||||
, ", [true, false]"
|
||||
, ", [9876543210, 9876543211, 9876543212]"
|
||||
//, ", [1.23, 1.24, 1.25]"
|
||||
, ", [{'a':1}, {'b':2}, {'c':3}]"
|
||||
, "]"
|
||||
)
|
||||
, fxt.Make__ary
|
||||
( fxt.Make__ary (1, 2, 3)
|
||||
, fxt.Make__ary ("a", "b", "c")
|
||||
, fxt.Make__ary (true, false)
|
||||
, fxt.Make__ary (9876543210L, 9876543211L, 9876543212L)
|
||||
// , fxt.Make__ary (1.23, 1.24, 1.25)
|
||||
, fxt.Make__ary
|
||||
( fxt.Make__nde(fxt.Make__fld_int("a", 1))
|
||||
, fxt.Make__nde(fxt.Make__fld_int("b", 2))
|
||||
, fxt.Make__nde(fxt.Make__fld_int("c", 3))
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
import gplx.langs.jsons.*;
|
||||
public class Gfobj_wtr__json {
|
||||
private final Json_wtr wtr = new Json_wtr();
|
||||
public Gfobj_wtr__json Opt_ws_(boolean v) {wtr.Opt_ws_(v); return this;}
|
||||
public Gfobj_wtr__json Opt_backslash_2x_(boolean v) {wtr.Opt_backslash_2x_(v); return this;}
|
||||
public Bry_bfr Bfr() {return wtr.Bfr();}
|
||||
public String To_str() {return wtr.To_str_and_clear();}
|
||||
public void Save(Io_url url) {
|
||||
Io_mgr.Instance.SaveFilBry(url, wtr.To_bry_and_clear());
|
||||
}
|
||||
public Gfobj_wtr__json Write(Gfobj_grp root) {
|
||||
switch (root.Grp_tid()) {
|
||||
case Gfobj_grp_.Grp_tid__nde:
|
||||
wtr.Doc_nde_bgn();
|
||||
Write_nde((Gfobj_nde)root);
|
||||
wtr.Doc_nde_end();
|
||||
break;
|
||||
case Gfobj_grp_.Grp_tid__ary:
|
||||
wtr.Doc_ary_bgn();
|
||||
Write_ary((Gfobj_ary)root);
|
||||
wtr.Doc_ary_end();
|
||||
break;
|
||||
default:
|
||||
throw Err_.new_unhandled_default(root.Grp_tid());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
private void Write_nde(Gfobj_nde nde) {
|
||||
int len = nde.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfobj_fld fld = (Gfobj_fld)nde.Get_at(i);
|
||||
Write_fld(fld);
|
||||
}
|
||||
}
|
||||
private void Write_fld(Gfobj_fld itm) {
|
||||
switch (itm.Fld_tid()) {
|
||||
case Gfobj_fld_.Fld_tid__str: wtr.Kv_str(itm.Key() , ((Gfobj_fld_str)itm).As_str()); break;
|
||||
case Gfobj_fld_.Fld_tid__int: wtr.Kv_int(itm.Key() , ((Gfobj_fld_int)itm).As_int()); break;
|
||||
case Gfobj_fld_.Fld_tid__long: wtr.Kv_long(itm.Key() , ((Gfobj_fld_long)itm).As_long()); break;
|
||||
case Gfobj_fld_.Fld_tid__bool: wtr.Kv_bool(itm.Key() , ((Gfobj_fld_bool)itm).As_bool()); break;
|
||||
case Gfobj_fld_.Fld_tid__double: wtr.Kv_double(itm.Key() , ((Gfobj_fld_double)itm).As_double()); break;
|
||||
case Gfobj_fld_.Fld_tid__nde: wtr.Nde_bgn(itm.Key()); Write_nde(((Gfobj_fld_nde)itm).As_nde()); wtr.Nde_end();break;
|
||||
case Gfobj_fld_.Fld_tid__ary: wtr.Ary_bgn(itm.Key()); Write_ary(((Gfobj_fld_ary)itm).As_ary()); wtr.Ary_end();break;
|
||||
default: throw Err_.new_unhandled_default(itm.Fld_tid());
|
||||
}
|
||||
}
|
||||
private void Write_ary(Gfobj_ary ary) {
|
||||
int len = ary.Len();
|
||||
Object[] ary_obj = ((Gfobj_ary)ary).Ary_obj();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Object sub_itm = ary_obj[i];
|
||||
Class<?> sub_itm_type = Type_adp_.ClassOf_obj(sub_itm);
|
||||
if (Type_adp_.Eq(sub_itm_type, Gfobj_ary.class)) {
|
||||
wtr.Ary_bgn_ary();
|
||||
Write_ary((Gfobj_ary)sub_itm);
|
||||
wtr.Ary_end();
|
||||
}
|
||||
else if (Type_adp_.Eq(sub_itm_type, Gfobj_nde.class)) {
|
||||
wtr.Nde_bgn_ary();
|
||||
Write_nde((Gfobj_nde)sub_itm);
|
||||
wtr.Nde_end();
|
||||
}
|
||||
else
|
||||
wtr.Ary_itm_obj(sub_itm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.tests.*; import gplx.langs.jsons.*;
|
||||
public class Gfobj_wtr__json_fxt {
|
||||
protected final Gfobj_wtr__json mgr = new Gfobj_wtr__json();
|
||||
public Gfobj_nde Make__nde(Gfobj_fld... ary) {return Make__nde(Gfobj_nde.New(), ary);}
|
||||
private Gfobj_nde Make__nde(Gfobj_nde nde, Gfobj_fld[] ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfobj_fld fld = (Gfobj_fld)ary[i];
|
||||
nde.Add_fld(fld);
|
||||
}
|
||||
return nde;
|
||||
}
|
||||
public Gfobj_fld Make__fld_bool (String key, boolean val) {return new Gfobj_fld_bool(key, val);}
|
||||
public Gfobj_fld Make__fld_str (String key, String val) {return new Gfobj_fld_str(key, val);}
|
||||
public Gfobj_fld Make__fld_int (String key, int val) {return new Gfobj_fld_int(key, val);}
|
||||
public Gfobj_fld Make__fld_long (String key, long val) {return new Gfobj_fld_long(key, val);}
|
||||
public Gfobj_fld Make__fld_double (String key, double val) {return new Gfobj_fld_double(key, val);}
|
||||
public Gfobj_fld Make__fld_nde(String key, Gfobj_fld... ary) {
|
||||
Gfobj_nde nde = Make__nde(Gfobj_nde.New(), ary);
|
||||
Gfobj_fld_nde rv = new Gfobj_fld_nde(key, nde);
|
||||
return rv;
|
||||
}
|
||||
public Gfobj_fld Make__fld_ary (String key, Object... ary) {return new Gfobj_fld_ary(key, new Gfobj_ary(ary));}
|
||||
public Gfobj_ary Make__ary (Object... ary) {return new Gfobj_ary(ary);}
|
||||
public Gfobj_wtr__json_fxt Test__write(Gfobj_grp root, String... lines) {
|
||||
String[] expd = Json_doc.Make_str_ary_by_apos(lines);
|
||||
Gftest.Eq__ary(expd, Bry_.Ary(String_.SplitLines_nl(mgr.Write(root).To_str())), "json_write");
|
||||
return this;
|
||||
}
|
||||
public Gfobj_wtr__json_fxt Test__parse(String src, Gfobj_grp expd) {
|
||||
Gfobj_rdr__json rdr = new Gfobj_rdr__json();
|
||||
Gfobj_grp actl = rdr.Parse(Bry_.new_u8(Json_doc.Make_str_by_apos(src)));
|
||||
Gftest.Eq__ary(Bry_.Ary(String_.SplitLines_nl(mgr.Write(expd).To_str())), Bry_.Ary(String_.SplitLines_nl(mgr.Write(actl).To_str())), "json_write");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
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.gfobjs; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
import gplx.langs.jsons.*;
|
||||
public class Gfobj_wtr__json_tst {
|
||||
private final Gfobj_wtr__json_fxt fxt = new Gfobj_wtr__json_fxt();
|
||||
@Test public void Flds() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__nde
|
||||
( fxt.Make__fld_str ("k1", "v1")
|
||||
, fxt.Make__fld_long ("k2", 2)
|
||||
, fxt.Make__fld_int ("k3", 3)
|
||||
)
|
||||
, "{ 'k1':'v1'"
|
||||
, ", 'k2':2"
|
||||
, ", 'k3':3"
|
||||
, "}"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
@Test public void Sub_ndes() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__nde
|
||||
( fxt.Make__fld_str ("k1", "v1")
|
||||
, fxt.Make__fld_nde ("k2"
|
||||
, fxt.Make__fld_str ("k2a", "v2a")
|
||||
, fxt.Make__fld_int ("k2b", 2)
|
||||
)
|
||||
, fxt.Make__fld_int ("k3", 3)
|
||||
)
|
||||
, "{ 'k1':'v1'"
|
||||
, ", 'k2':"
|
||||
, " { 'k2a':'v2a'"
|
||||
, " , 'k2b':2"
|
||||
, " }"
|
||||
, ", 'k3':3"
|
||||
, "}"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
@Test public void Ary_str() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__nde
|
||||
( fxt.Make__fld_str ("k1", "v1")
|
||||
, fxt.Make__fld_ary ("k2", "a1", "a2", "a3")
|
||||
, fxt.Make__fld_int ("k3", 3)
|
||||
)
|
||||
, "{ 'k1':'v1'"
|
||||
, ", 'k2':"
|
||||
, " [ 'a1'"
|
||||
, " , 'a2'"
|
||||
, " , 'a3'"
|
||||
, " ]"
|
||||
, ", 'k3':3"
|
||||
, "}"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
@Test public void Ary_int() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__nde
|
||||
( fxt.Make__fld_str ("k1", "v1")
|
||||
, fxt.Make__fld_ary ("k2", 1, 2, 3)
|
||||
, fxt.Make__fld_int ("k3", 3)
|
||||
)
|
||||
, "{ 'k1':'v1'"
|
||||
, ", 'k2':"
|
||||
, " [ 1"
|
||||
, " , 2"
|
||||
, " , 3"
|
||||
, " ]"
|
||||
, ", 'k3':3"
|
||||
, "}"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
@Test public void Ary_nde() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__nde
|
||||
( fxt.Make__fld_str ("k1", "v1")
|
||||
, fxt.Make__fld_ary ("k2"
|
||||
, fxt.Make__nde (fxt.Make__fld_str("k21", "v21"))
|
||||
, fxt.Make__nde (fxt.Make__fld_str("k22", "v22"))
|
||||
)
|
||||
, fxt.Make__fld_int ("k3", 3)
|
||||
)
|
||||
, "{ 'k1':'v1'"
|
||||
, ", 'k2':"
|
||||
, " ["
|
||||
, " { 'k21':'v21'"
|
||||
, " }"
|
||||
, " ,"
|
||||
, " { 'k22':'v22'"
|
||||
, " }"
|
||||
, " ]"
|
||||
, ", 'k3':3"
|
||||
, "}"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
@Test public void Ary_ary() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__nde
|
||||
( fxt.Make__fld_str ("k1", "v1")
|
||||
, fxt.Make__fld_ary ("k2"
|
||||
, fxt.Make__ary (1, 2, 3)
|
||||
, fxt.Make__ary (4, 5, 6)
|
||||
)
|
||||
, fxt.Make__fld_int ("k3", 3)
|
||||
)
|
||||
, "{ 'k1':'v1'"
|
||||
, ", 'k2':"
|
||||
, " ["
|
||||
, " [ 1"
|
||||
, " , 2"
|
||||
, " , 3"
|
||||
, " ]"
|
||||
, " ,"
|
||||
, " [ 4"
|
||||
, " , 5"
|
||||
, " , 6"
|
||||
, " ]"
|
||||
, " ]"
|
||||
, ", 'k3':3"
|
||||
, "}"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
@Test public void Root_ary() {
|
||||
fxt.Test__write
|
||||
( fxt.Make__ary(1, 2, 3)
|
||||
, "[ 1"
|
||||
, ", 2"
|
||||
, ", 3"
|
||||
, "]"
|
||||
, ""
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
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.intls; import gplx.*; import gplx.core.*;
|
||||
public class String_surrogate_utl {
|
||||
public int Byte_pos() {return byte_pos;} int byte_pos;
|
||||
public int Count_surrogates__char_idx(byte[] src, int src_len, int byte_bgn, int char_idx) {return Count_surrogates(src, src_len, byte_bgn, Bool_.Y, char_idx);}
|
||||
public int Count_surrogates__codepoint_idx1(byte[] src, int src_len, int byte_bgn, int codepoint_idx) {return Count_surrogates(src, src_len, byte_bgn, Bool_.N, codepoint_idx);}
|
||||
private int Count_surrogates(byte[] src, int src_len, int byte_bgn, boolean stop_idx_is_char, int stop_idx) {
|
||||
int char_count = 0, codepoint_count = 0;
|
||||
byte_pos = byte_bgn;
|
||||
while (true) {
|
||||
if ( stop_idx == (stop_idx_is_char ? char_count : codepoint_count) // requested # of chars found
|
||||
|| byte_pos >= src_len // eos reached; DATE:2014-09-02
|
||||
) return codepoint_count - char_count;
|
||||
int char_len_in_bytes = gplx.core.intls.Utf8_.Len_of_char_by_1st_byte(src[byte_pos]);
|
||||
++char_count; // char_count always incremented by 1
|
||||
codepoint_count += (char_len_in_bytes == 4) ? 2 : 1; // codepoint_count incremented by 2 if surrogate pair; else 1
|
||||
byte_pos += char_len_in_bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
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.intls; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class String_surrogate_utl_tst {
|
||||
@Before public void init() {fxt.Clear();} private String_surrogate_utl_fxt fxt = new String_surrogate_utl_fxt();
|
||||
@Test public void Char_idx() {
|
||||
String test_str = "aé𡼾bî𡼾";
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 0, 1, 0, 1); // a
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 0, 2, 0, 3); // aé
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 0, 3, 1, 7); // aé𡼾
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 7, 1, 0, 8); // b
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 7, 2, 0, 10); // bî
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 7, 3, 1, 14); // bî𡼾
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 0, 6, 2, 14); // aé𡼾bî𡼾
|
||||
fxt.Test_count_surrogates__char_idx (test_str, 14, 7, 0, 14); // PURPOSE: test out of bounds; DATE:2014-09-02
|
||||
}
|
||||
@Test public void Codepoint_idx() {
|
||||
String test_str = "aé𡼾bî𡼾";
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 0, 1, 0, 1); // a
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 0, 2, 0, 3); // aé
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 0, 4, 1, 7); // aé𡼾
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 7, 1, 0, 8); // b
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 7, 2, 0, 10); // bî
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 7, 4, 1, 14); // bî𡼾
|
||||
fxt.Test_count_surrogates__codepoint_idx (test_str, 0, 8, 2, 14); // aé𡼾bî𡼾
|
||||
}
|
||||
}
|
||||
class String_surrogate_utl_fxt {
|
||||
private String_surrogate_utl codepoint_utl = new String_surrogate_utl();
|
||||
public void Clear() {}
|
||||
public void Test_count_surrogates__char_idx(String src_str, int bgn_byte, int char_idx, int expd_count, int expd_pos) {
|
||||
byte[] src_bry = Bry_.new_u8(src_str); int src_len = src_bry.length;
|
||||
Tfds.Eq(expd_count , codepoint_utl.Count_surrogates__char_idx(src_bry, src_len, bgn_byte, char_idx));
|
||||
Tfds.Eq(expd_pos , codepoint_utl.Byte_pos());
|
||||
}
|
||||
public void Test_count_surrogates__codepoint_idx(String src_str, int bgn_byte, int char_idx, int expd_count, int expd_pos) {
|
||||
byte[] src_bry = Bry_.new_u8(src_str); int src_len = src_bry.length;
|
||||
Tfds.Eq(expd_count , codepoint_utl.Count_surrogates__codepoint_idx1(src_bry, src_len, bgn_byte, char_idx), "count");
|
||||
Tfds.Eq(expd_pos , codepoint_utl.Byte_pos(), "pos");
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
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.intls.ucas; import gplx.*; import gplx.core.*; import gplx.core.intls.*;
|
||||
public interface Uca_collator {
|
||||
void Init(String locale, boolean numeric_ordering);
|
||||
byte[] Get_sortkey(String s);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
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.intls.ucas; import gplx.*; import gplx.core.*; import gplx.core.intls.*;
|
||||
public class Uca_collator_ {
|
||||
public static Uca_collator New(String locale, boolean numeric_ordering) {
|
||||
Uca_collator rv = new Uca_collator__icu__4_8();
|
||||
rv.Init(locale, numeric_ordering);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
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.intls.ucas; import gplx.*; import gplx.core.*; import gplx.core.intls.*;
|
||||
import java.util.Locale;
|
||||
import com.ibm.icu.text.CollationKey;
|
||||
import com.ibm.icu.text.Collator;
|
||||
import com.ibm.icu.text.RuleBasedCollator;
|
||||
class Uca_collator__icu__4_8 implements Uca_collator {
|
||||
private Collator collator;
|
||||
public void Init(String locale, boolean numeric_ordering) {
|
||||
try {
|
||||
this.collator = Collator.getInstance(Locale.forLanguageTag(locale));
|
||||
if (numeric_ordering) {
|
||||
RuleBasedCollator rbc = (RuleBasedCollator)collator;
|
||||
rbc.setNumericCollation(true);
|
||||
}
|
||||
} catch (Exception e) {throw Err_.new_wo_type("collator init failed", "err", Err_.Message_lang(e));}
|
||||
}
|
||||
public byte[] Get_sortkey(String s) {
|
||||
CollationKey key = collator.getCollationKey(s);
|
||||
byte[] src = key.toByteArray();
|
||||
int src_len = src.length;
|
||||
byte[] rv = src;
|
||||
|
||||
// remove last byte if it is 0 (which it often is)
|
||||
if (src_len > 0 && src[src_len - 1] == 0) {
|
||||
int rv_len = src_len - 1;
|
||||
rv = new byte[rv_len];
|
||||
for (int i = 0; i < rv_len; ++i)
|
||||
rv[i] = src[i];
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
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.intls.ucas; import gplx.*; import gplx.core.*; import gplx.core.intls.*;
|
||||
public class Uca_ltr_extractor {
|
||||
private final boolean numeric;
|
||||
private final byte[] numeric_heading;
|
||||
private final Hash_adp_bry numeric_hash;
|
||||
public Uca_ltr_extractor(boolean numeric) {
|
||||
this.numeric = numeric;
|
||||
if (numeric) {
|
||||
numeric_heading = Bry_.new_a7("0-9");
|
||||
|
||||
// create hash of "0", "1", "2", ...
|
||||
numeric_hash = Hash_adp_bry.cs();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
byte[] digit_bry = Bry_.new_by_int(Byte_ascii.Num_0 + i);
|
||||
numeric_hash.Add(digit_bry, digit_bry);
|
||||
}
|
||||
}
|
||||
else {
|
||||
numeric_heading = null;
|
||||
numeric_hash = null;
|
||||
}
|
||||
}
|
||||
public byte[] Get_1st_ltr(byte[] bry) {
|
||||
// NOTE: this is simplified and only does numeric logic; MW code loads up all ICU chars via first-letters-root.ser, adds custom chars, sorts them, and then does a binary search to find it; REF:IcuCollation.php!getFirstLetter
|
||||
int bry_len = bry.length;
|
||||
if (bry_len == 0) return Bry_.Empty;
|
||||
byte[] rv = gplx.core.intls.Utf8_.Get_char_at_pos_as_bry(bry, 0);
|
||||
if (numeric) {
|
||||
if (numeric_hash.Has(rv))
|
||||
rv = numeric_heading;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.lists.*;
|
||||
class BinaryHeap_Io_line_rdr {
|
||||
public BinaryHeap_Io_line_rdr(ComparerAble comparer) {this.comparer = comparer;} ComparerAble comparer;
|
||||
Io_line_rdr[] ary = Ary_empty; int ary_len = 0, ary_max = 0;
|
||||
public int Len() {return ary_len;}
|
||||
public void Add(Io_line_rdr itm) {
|
||||
int new_len = ary_len + 1;
|
||||
if (new_len > ary_max) {
|
||||
ary_max = new_len * 2;
|
||||
ary = (Io_line_rdr[])Array_.Resize(ary, ary_max);
|
||||
}
|
||||
ary[ary_len] = itm;
|
||||
ary_len = new_len;
|
||||
Add_move_up(ary_len - 1);
|
||||
}
|
||||
public Io_line_rdr Pop() {
|
||||
if (ary_len == 0) return null;
|
||||
Io_line_rdr rv = ary[0];
|
||||
--ary_len;
|
||||
if (ary_len > 0) {
|
||||
ary[0] = ary[ary_len];
|
||||
Pop_move_down(0);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public void Rls() {
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
Io_line_rdr rdr = ary[i];
|
||||
if (rdr != null) rdr.Rls();
|
||||
ary[i] = null;
|
||||
}
|
||||
ary = null;
|
||||
ary_len = 0;
|
||||
}
|
||||
private void Add_move_up(int pos) {
|
||||
while (pos > 0) {
|
||||
int owner = (pos - 1) / 2;
|
||||
if (Compare(pos, owner) > CompareAble_.Less) break;
|
||||
Swap(pos, owner);
|
||||
pos = owner;
|
||||
}
|
||||
}
|
||||
private void Pop_move_down(int pos) {
|
||||
int idx_last = ary_len - 1;
|
||||
while (pos < ary_len / 2) {
|
||||
int sub = 2 * pos + 1;
|
||||
if (sub < idx_last && Compare(sub, sub + 1) > CompareAble_.Same)
|
||||
++sub;
|
||||
if (Compare(pos, sub) < CompareAble_.More) break;
|
||||
Swap(pos, sub);
|
||||
pos = sub;
|
||||
}
|
||||
}
|
||||
int Compare(int lhs_idx, int rhs_idx) {
|
||||
Io_line_rdr lhs = ary[lhs_idx], rhs = ary[rhs_idx];
|
||||
lhs_itm.Set(lhs); rhs_itm.Set(rhs);
|
||||
return comparer.compare(lhs_itm, rhs_itm);
|
||||
// return Bry_.Compare(lhs.Bfr(), lhs.Key_pos_bgn(), lhs.Key_pos_end(), rhs.Bfr(), rhs.Key_pos_bgn(), rhs.Key_pos_end());
|
||||
} Io_sort_split_itm lhs_itm = new Io_sort_split_itm(), rhs_itm = new Io_sort_split_itm();
|
||||
private void Swap(int lhs_idx, int rhs_idx) {
|
||||
Io_line_rdr tmp = ary[lhs_idx];
|
||||
ary[lhs_idx] = ary[rhs_idx];
|
||||
ary[rhs_idx] = tmp;
|
||||
}
|
||||
private static final Io_line_rdr[] Ary_empty = new Io_line_rdr[0];
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class BinaryHeap_Io_line_rdr_tst {
|
||||
BinaryHeap_Io_line_rdr_fxt fxt = new BinaryHeap_Io_line_rdr_fxt();
|
||||
@Test public void Add() {
|
||||
fxt.Add("c", "a", "b").tst("a", "b", "c");
|
||||
fxt.Add("b", "a", "a").tst("a", "a", "b");
|
||||
fxt.Add("f", "b", "d", "c", "e", "a").tst("a", "b", "c", "d", "e", "f");
|
||||
}
|
||||
}
|
||||
class BinaryHeap_Io_line_rdr_fxt {
|
||||
BinaryHeap_Io_line_rdr heap = new BinaryHeap_Io_line_rdr(Io_sort_split_itm_sorter.Instance); int file_total;
|
||||
public BinaryHeap_Io_line_rdr_fxt Add(String... ary) {
|
||||
file_total = ary.length;
|
||||
for (int i = 0; i < file_total; i++) {
|
||||
Io_url url = Io_url_.mem_fil_("mem/fil_" + ary[i] + ".txt");
|
||||
Io_mgr.Instance.SaveFilStr(url, ary[i]);
|
||||
Io_line_rdr stream = new Io_line_rdr(Gfo_usr_dlg_.Test(), url);
|
||||
stream.Read_next();
|
||||
heap.Add(stream);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public BinaryHeap_Io_line_rdr_fxt tst(String... expd) {
|
||||
String[] actl = new String[file_total];
|
||||
for (int i = 0; i < actl.length; i++) {
|
||||
Io_line_rdr bfr = heap.Pop();
|
||||
actl[i] = String_.new_u8(bfr.Bfr(), 0, bfr.Bfr_len());
|
||||
}
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.ios.streams.*;/*IoStream*/
|
||||
public class Io_buffer_rdr implements Rls_able {
|
||||
private Io_stream_rdr rdr;
|
||||
Io_buffer_rdr(Io_stream_rdr rdr, Io_url url, int bfr_len) {
|
||||
this.rdr = rdr; this.url = url;
|
||||
if (bfr_len <= 0) throw Err_.new_wo_type("bfr_len must be > 0", "bfr_len", bfr_len);
|
||||
bfr = new byte[bfr_len]; this.bfr_len = bfr_len;
|
||||
IoItmFil fil = Io_mgr.Instance.QueryFil(url); if (!fil.Exists()) throw Err_.new_wo_type("fil does not exist", "url", url);
|
||||
fil_len = fil.Size();
|
||||
fil_pos = 0;
|
||||
fil_eof = false;
|
||||
}
|
||||
public Io_url Url() {return url;} private Io_url url;
|
||||
public byte[] Bfr() {return bfr;} private byte[] bfr;
|
||||
public int Bfr_len() {return bfr_len;} private int bfr_len;
|
||||
public long Fil_len() {return fil_len;} long fil_len;
|
||||
public long Fil_pos() {return fil_pos;} long fil_pos;
|
||||
public boolean Fil_eof() {return fil_eof;} private boolean fil_eof;
|
||||
public boolean Bfr_load_all() {return Bfr_load(0, bfr_len);}
|
||||
public boolean Bfr_load_from(int bfr_pos) {
|
||||
if (bfr_pos < 0 || bfr_pos > bfr_len) throw Err_.new_wo_type("invalid bfr_pos", "bfr_pos", bfr_pos, "bfr_len", bfr_len);
|
||||
for (int i = bfr_pos; i < bfr_len; i++) // shift end of bfr to bgn; EX: bfr[10] and load_from(8); [8] -> [0]; [9] -> [1];
|
||||
bfr[i - bfr_pos] = bfr[i];
|
||||
return Bfr_load(bfr_len - bfr_pos, bfr_pos); // fill rest of bfr; EX: [2]... will come from file
|
||||
}
|
||||
private boolean Bfr_load(int bgn, int len) {
|
||||
int read = rdr.Read(bfr, bgn, len);
|
||||
if (read == gplx.core.ios.streams.Io_stream_rdr_.Read_done) {fil_eof = true; return false;}
|
||||
fil_pos += read;
|
||||
bfr_len = bgn + read;
|
||||
if (read < len) fil_eof = true;
|
||||
return true;
|
||||
}
|
||||
public void Seek(long fil_pos) {
|
||||
this.fil_pos = fil_pos;
|
||||
rdr.Skip(fil_pos);
|
||||
this.Bfr_load_all();
|
||||
}
|
||||
public void Rls() {
|
||||
bfr = null;
|
||||
bfr_len = -1;
|
||||
if (rdr != null) rdr.Rls();
|
||||
}
|
||||
@gplx.Internal protected void Dump_to_file(int bgn, int len, String url_str, String msg) { // DBG:
|
||||
String text = String_.new_u8__by_len(bfr, bgn, len);
|
||||
Io_mgr.Instance.AppendFilStr(Io_url_.new_any_(url_str), msg + text + "\n");
|
||||
}
|
||||
public static Io_buffer_rdr new_(Io_stream_rdr rdr, int bfr_len) {
|
||||
Io_buffer_rdr rv = new Io_buffer_rdr(rdr, rdr.Url(), bfr_len);
|
||||
rdr.Open();
|
||||
rv.Bfr_load(0, bfr_len);
|
||||
return rv;
|
||||
}
|
||||
public static final Io_buffer_rdr Null = new Io_buffer_rdr(); Io_buffer_rdr() {}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.ios.*; import gplx.core.ios.streams.*;
|
||||
public class Io_buffer_rdr_tst {
|
||||
@Before public void init() {
|
||||
Io_mgr.Instance.InitEngine_mem();
|
||||
fil = Io_url_.mem_fil_("mem/byteStreamRdr.txt");
|
||||
ini_Write("0123456789");
|
||||
rdr = Io_buffer_rdr.new_(Io_stream_rdr_.New__raw(fil), 4);
|
||||
} Io_buffer_rdr rdr; Io_url fil;
|
||||
@After public void teardown() {rdr.Rls();}
|
||||
@Test public void Bfr_load_all() {
|
||||
tst_Bfr("0", "1", "2", "3").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_all();
|
||||
tst_Bfr("4", "5", "6", "7").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_all();
|
||||
tst_Bfr("8", "9");
|
||||
rdr.Bfr_load_all(); // NOTE: change to zip_rdrs make eof detection difficult; force another load to ensure that file_pos goes past file_len
|
||||
tst_ReadDone(true); // NOTE: bfr truncated from 4 to 2
|
||||
}
|
||||
@Test public void Bfr_load_from() {
|
||||
tst_Bfr("0", "1", "2", "3").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(3); // read from pos 3
|
||||
tst_Bfr("3", "4", "5", "6").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(1); // read from pos 1
|
||||
tst_Bfr("4", "5", "6", "7").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(1);
|
||||
tst_Bfr("5", "6", "7", "8").tst_ReadDone(false);
|
||||
|
||||
rdr.Bfr_load_from(3);
|
||||
rdr.Bfr_load_all(); // NOTE: change to zip_rdrs make eof detection difficult; force another load to ensure that file_pos goes past file_len
|
||||
tst_Bfr("8", "9").tst_ReadDone(true);
|
||||
}
|
||||
private void ini_Write(String s) {Io_mgr.Instance.SaveFilStr(fil, s);}
|
||||
Io_buffer_rdr_tst tst_Bfr(String... expdAry) {
|
||||
String[] actlAry = new String[rdr.Bfr_len()];
|
||||
for (int i = 0; i < actlAry.length; i++)
|
||||
actlAry[i] = String_.new_u8(rdr.Bfr(), i, i + 1);
|
||||
Tfds.Eq_ary(expdAry, actlAry);
|
||||
return this;
|
||||
}
|
||||
Io_buffer_rdr_tst tst_ReadDone(boolean expd) {Tfds.Eq(expd, rdr.Fil_eof()); return this;}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.tests.*;
|
||||
public class Io_fil_chkr implements Tst_chkr {
|
||||
public Io_fil_chkr(Io_url url, String data) {this.expd_url = url; this.expd_data = data;}
|
||||
public Io_url Expd_url() {return expd_url;} public Io_fil_chkr Expd_url_(Io_url v) {expd_url = v; return this;} Io_url expd_url;
|
||||
public String Expd_data() {return expd_data;} public Io_fil_chkr Expd_data_(String v) {expd_data = v; return this;} private String expd_data;
|
||||
public Class<?> TypeOf() {return gplx.core.ios.Io_fil.class;}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl) {
|
||||
gplx.core.ios.Io_fil fil = (gplx.core.ios.Io_fil)actl;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(expd_url == null, path, "url", expd_url, fil.Url());
|
||||
rv += mgr.Tst_val(expd_data == null, path, "data", expd_data, fil.Data());
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.ios.streams.*;
|
||||
public class Io_line_rdr {
|
||||
public Io_line_rdr (Gfo_usr_dlg usr_dlg, Io_url... urls) {this.usr_dlg = usr_dlg; this.urls = urls; if (urls.length == 0) bfr_state = Bfr_state_end;} Gfo_usr_dlg usr_dlg;
|
||||
public int Url_idx() {return url_idx;} private int url_idx;
|
||||
public Io_url[] Urls() {return urls;} Io_url[] urls;
|
||||
public void Reset_one(Io_url url) {
|
||||
this.Clear();
|
||||
urls[0] = url;
|
||||
url_idx = 0;
|
||||
}
|
||||
public byte Line_dlm() {return line_dlm;} public Io_line_rdr Line_dlm_(byte v) {line_dlm = v; return this;} private byte line_dlm = Byte_ascii.Nl;
|
||||
public byte[] Bfr() {return bfr;} private byte[] bfr;
|
||||
public int Bfr_len() {return bfr_len;} private int bfr_len;
|
||||
public byte Bfr_state() {return bfr_state;} private byte bfr_state = Bfr_state_bgn; static final byte Bfr_state_bgn = 0, Bfr_state_mid = 1, Bfr_state_end = 2;
|
||||
public int Bfr_last_read() {return bfr_last_read;} private int bfr_last_read;
|
||||
public void Bfr_last_read_add(int v) {bfr_last_read += v;}
|
||||
public int Load_len() {return load_len;} public Io_line_rdr Load_len_(int v) {load_len = v; return this;} private int load_len = 4096;
|
||||
long File_len() {return file_len;} long file_len = 0;
|
||||
long File_pos() {return file_pos;} long file_pos = 0;
|
||||
public boolean File_skip_line0() {return file_skip_line0;} public Io_line_rdr File_skip_line0_(boolean v) {file_skip_line0 = v; return this;} private boolean file_skip_line0;
|
||||
public int Itm_pos_bgn() {return itm_pos_bgn;} private int itm_pos_bgn = 0;
|
||||
public int Itm_pos_end() {return itm_pos_end;} private int itm_pos_end = 0;
|
||||
public int Key_pos_bgn() {return key_pos_bgn;} public Io_line_rdr Key_pos_bgn_(int v) {key_pos_bgn = v; return this;} private int key_pos_bgn = -1;
|
||||
public int Key_pos_end() {return key_pos_end;} public Io_line_rdr Key_pos_end_(int v) {key_pos_end = v; return this;} private int key_pos_end = -1;
|
||||
public Io_line_rdr_key_gen Key_gen() {return key_gen;} public Io_line_rdr Key_gen_(Io_line_rdr_key_gen v) {key_gen = v; return this;} Io_line_rdr_key_gen key_gen = Io_line_rdr_key_gen_.first_pipe;
|
||||
public void Truncate(int pos) {
|
||||
this.Read_next();
|
||||
int end = Bry_find_.Find_fwd(bfr, Byte_ascii.Null); if (end == -1) end = bfr.length;
|
||||
bfr = Bry_.Mid(bfr, pos, end);
|
||||
bfr_len = bfr.length;
|
||||
bfr_last_read = 0;
|
||||
}
|
||||
public boolean Read_next() {
|
||||
switch (bfr_state) {
|
||||
case Bfr_state_bgn:
|
||||
bfr_state = Bfr_state_mid; // do not place after Load
|
||||
Open_fil();
|
||||
if (!Load()) return false;
|
||||
break;
|
||||
case Bfr_state_end:
|
||||
return false;
|
||||
}
|
||||
itm_pos_bgn = bfr_last_read; itm_pos_end = bfr_len; key_pos_bgn = key_pos_end = -1;
|
||||
while (true) {
|
||||
for (int i = bfr_last_read; i < bfr_len; i++) {
|
||||
if (bfr[i] == line_dlm) {
|
||||
itm_pos_end = i + 1; // +1: include find
|
||||
bfr_last_read = itm_pos_end;
|
||||
key_gen.Gen(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (Load()) // line_dlm not found; load more
|
||||
itm_pos_bgn = 0;
|
||||
else { // nothing loaded; return;
|
||||
itm_pos_end = bfr_len;
|
||||
key_gen.Gen(this); // call key_gen b/c there may be a stray line at end; EX: "\nb|c"; call key_gen to get "b"
|
||||
bfr_state = Bfr_state_end;
|
||||
return bfr_last_read < bfr_len; // true if stray line at end; otherwise bfr_last_read == bfr_len and return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean Match(byte[] ttl) {
|
||||
switch (bfr_state) {
|
||||
case Bfr_state_bgn:
|
||||
if (!Read_next()) return false;
|
||||
bfr_state = Bfr_state_mid; // NOTE: must set back to mid; possible for 1st read to read entire buffer; EX: 8 MB bfr, but only 1 MB file;
|
||||
break;
|
||||
case Bfr_state_end:
|
||||
return false;
|
||||
}
|
||||
while (true) {
|
||||
int compare = Bry_.Compare(ttl, 0, ttl.length, bfr, key_pos_bgn, key_pos_end);
|
||||
if (compare == CompareAble_.Same) { // eq; return true and move fwd; EX: "BA" and "BA"
|
||||
return true;
|
||||
}
|
||||
else if (compare < CompareAble_.Same) { // lt; return false; EX: ttl is "BA" but rdr is "BC"
|
||||
return false;
|
||||
}
|
||||
else { // gt; keep reading; EX: ttl is "BC" but rdr is "BA"
|
||||
if (!this.Read_next()) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean Load() {
|
||||
int old_bfr_len = bfr_len - bfr_last_read; // NOTE: preserve bytes between bfr_last_read and bfr_len; EX: "ab\nc"; preserve "c" for next ary
|
||||
if (file_done) {++url_idx; if (url_idx == urls.length) {bfr_state = Bfr_state_end; return false;} Open_fil(); file_done = false;}
|
||||
byte[] load_ary = new byte[old_bfr_len + load_len]; int load_ary_len = load_ary.length; // NOTE: must go after file_done chk; otherwise small wikis will allocate another 32 MB bry for sort_memory_len and cause an OutOfMemory error; DATE:20130112
|
||||
int read_len = stream.Read(load_ary, old_bfr_len, load_ary_len - old_bfr_len);
|
||||
if (read_len == 0) { // nothing read; return;
|
||||
++url_idx;
|
||||
if (url_idx < urls.length) {
|
||||
stream.Rls();
|
||||
Open_fil();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
stream.Rls();
|
||||
bfr_state = Bfr_state_end;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (read_len == file_len) {
|
||||
stream.Rls();
|
||||
file_done = true;
|
||||
// ++url_idx;
|
||||
// bfr_state = Bfr_state_end;
|
||||
}
|
||||
if (old_bfr_len > 0) Array_.Copy_to(bfr, bfr_last_read, load_ary, 0, old_bfr_len); // copy old_bfr over
|
||||
file_pos += read_len;
|
||||
bfr = load_ary;
|
||||
bfr_last_read = 0;
|
||||
bfr_len = read_len == load_len ? load_ary_len : old_bfr_len + read_len; // stream.Read() may return less bytes than load_ary at EOF; if so, don't shrink bfr; just mark bfr_len less
|
||||
return true;
|
||||
} IoStream stream;
|
||||
private void Open_fil() {
|
||||
Io_url url = urls[url_idx];
|
||||
usr_dlg.Prog_many(GRP_KEY, "load", "loading dump file: ~{0}", url.NameAndExt());
|
||||
if (file_skip_line0) {
|
||||
byte[] stream_bry = Io_mgr.Instance.LoadFilBry(url);
|
||||
int stream_bry_len = stream_bry.length;
|
||||
int nl_pos = Bry_find_.Find_fwd(stream_bry, Byte_ascii.Nl, 0, stream_bry_len);
|
||||
if (nl_pos == Bry_find_.Not_found)
|
||||
stream_bry = Bry_.Empty;
|
||||
else
|
||||
stream_bry = Bry_.Mid(stream_bry, nl_pos + 1, stream_bry_len);
|
||||
stream = gplx.core.ios.streams.IoStream_.ary_(stream_bry);
|
||||
}
|
||||
else {
|
||||
stream = Io_mgr.Instance.OpenStreamRead(url);
|
||||
}
|
||||
file_pos = 0; file_len = stream.Len();
|
||||
file_done = false;
|
||||
} boolean file_done = false;
|
||||
public void Clear() {
|
||||
bfr_state = Bfr_state_bgn;
|
||||
if (stream != null) stream.Rls();
|
||||
bfr = null;
|
||||
}
|
||||
public void Rls() {
|
||||
this.Clear();
|
||||
bfr = null;
|
||||
}
|
||||
static final String GRP_KEY = "xowa.bldr.line_rdr";
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public interface Io_line_rdr_key_gen {
|
||||
void Gen(Io_line_rdr bfr);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public class Io_line_rdr_key_gen_ {
|
||||
public static final Io_line_rdr_key_gen first_pipe = new Io_line_rdr_key_gen_first(Byte_ascii.Pipe);
|
||||
public static final Io_line_rdr_key_gen last_pipe = new Io_line_rdr_key_gen_last(Byte_ascii.Pipe);
|
||||
public static final Io_line_rdr_key_gen noop = new Io_line_rdr_key_gen_noop();
|
||||
}
|
||||
class Io_line_rdr_key_gen_last implements Io_line_rdr_key_gen {
|
||||
public Io_line_rdr_key_gen_last(byte fld_dlm) {this.fld_dlm = fld_dlm;} private byte fld_dlm;
|
||||
public void Gen(Io_line_rdr bfr) {
|
||||
int bgn = bfr.Itm_pos_bgn(), end = bfr.Itm_pos_end() - 1; // -1: ignore row_dlm
|
||||
bfr.Key_pos_bgn_(end).Key_pos_end_(end);
|
||||
byte[] bry = bfr.Bfr();
|
||||
for (int i = end; i >= bgn; i--) {
|
||||
if (bry[i] == fld_dlm) {
|
||||
bfr.Key_pos_bgn_(i + 1); // +1 to position after fldDlm
|
||||
return;
|
||||
}
|
||||
}
|
||||
bfr.Key_pos_bgn_(0); // nothing found; position at bgn
|
||||
}
|
||||
}
|
||||
class Io_line_rdr_key_gen_first implements Io_line_rdr_key_gen {
|
||||
public Io_line_rdr_key_gen_first(byte fld_dlm) {this.fld_dlm = fld_dlm;} private byte fld_dlm;
|
||||
public void Gen(Io_line_rdr bfr) {
|
||||
int bgn = bfr.Itm_pos_bgn(), end = bfr.Itm_pos_end();
|
||||
bfr.Key_pos_bgn_(bgn).Key_pos_end_(bgn);
|
||||
byte[] bry = bfr.Bfr();
|
||||
for (int i = bgn; i < end; i++) {
|
||||
if (bry[i] == fld_dlm) {
|
||||
bfr.Key_pos_end_(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bfr.Key_pos_end_(end); // nothing found; position at end
|
||||
}
|
||||
}
|
||||
class Io_line_rdr_key_gen_noop implements Io_line_rdr_key_gen {
|
||||
public void Gen(Io_line_rdr bfr) {}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.envs.*;
|
||||
public class Io_line_rdr_tst {
|
||||
Io_line_rdr_fxt fxt;
|
||||
@Before public void init() {
|
||||
fxt = new Io_line_rdr_fxt(Io_url_.new_fil_("mem/test.txt"));
|
||||
fxt.Clear();
|
||||
}
|
||||
@Test public void Basic() {
|
||||
fxt.File_lines_(3).tst_Read_til_lines(3, "00", "01", "02");
|
||||
fxt.tst_Read_til_lines(1); // make sure nothing more is read
|
||||
}
|
||||
@Test public void Load_3x() {
|
||||
fxt.File_lines_(9).Load_len_lines_(3).tst_Read_til_lines(9, "00", "01", "02", "03", "04", "05", "06", "07", "08");
|
||||
}
|
||||
@Test public void Load_irregular() {
|
||||
fxt.File_lines_(9).Load_len_(4).tst_Read_til_lines(9, "00", "01", "02", "03", "04", "05", "06", "07", "08");
|
||||
}
|
||||
@Test public void Load_multiple_files() {
|
||||
fxt = new Io_line_rdr_fxt(Io_url_.new_fil_("mem/test0.txt"), Io_url_.new_fil_("mem/test1.txt"), Io_url_.new_fil_("mem/test2.txt"));
|
||||
fxt.File_lines_(0, 0, 3).File_lines_(1, 3, 5).File_lines_(2, 5, 9).Load_len_(4).tst_Read_til_lines(9, "00", "01", "02", "03", "04", "05", "06", "07", "08");
|
||||
}
|
||||
@Test public void Match() {
|
||||
fxt.File_lines_pipe_(9).Load_len_(6);
|
||||
fxt.tst_Match("00", "00");
|
||||
fxt.tst_Match("01", "01");
|
||||
fxt.tst_Match("03", "03");
|
||||
fxt.tst_Match("08", "08");
|
||||
fxt.tst_Match("12", "");
|
||||
}
|
||||
}
|
||||
class Io_line_rdr_fxt {
|
||||
Io_line_rdr rdr;
|
||||
List_adp lines = List_adp_.New(); Bry_bfr tmp = Bry_bfr_.New();
|
||||
public Io_line_rdr_fxt(Io_url... urls) {rdr = new Io_line_rdr(Gfo_usr_dlg_.Test(), urls);}
|
||||
public Io_line_rdr_fxt Load_len_lines_(int v) {return Load_len_(v * 3);} // 3: 2=##, 1=\n
|
||||
public Io_line_rdr_fxt Load_len_(int v) {rdr.Load_len_(v); return this;}
|
||||
public Io_line_rdr_fxt File_lines_(int count) {
|
||||
for (int i = 0; i < count; i++)
|
||||
tmp.Add_int_fixed(i, 2).Add_byte_nl();
|
||||
Io_mgr.Instance.SaveFilBry(rdr.Urls()[0], tmp.To_bry_and_clear());
|
||||
return this;
|
||||
}
|
||||
// public Io_url[] Src_fils() {return src_fils;} public Io_line_rdr_fxt Src_fils_(Io_url[] v) {src_fils = v; return this;} Io_url[] src_fils;
|
||||
public Io_line_rdr_fxt tst_Match(String match, String expd) {
|
||||
rdr.Key_gen_(Io_line_rdr_key_gen_.first_pipe);
|
||||
boolean match_v = rdr.Match(Bry_.new_u8(match));
|
||||
String actl = match_v ? String_.new_u8(rdr.Bfr(), rdr.Key_pos_bgn(), rdr.Key_pos_end()) : "";
|
||||
Tfds.Eq(expd, actl);
|
||||
return this;
|
||||
}
|
||||
public Io_line_rdr_fxt File_lines_pipe_(int count) {
|
||||
for (int i = 0; i < count; i++)
|
||||
tmp.Add_int_fixed(i, 2).Add_byte(Byte_ascii.Pipe).Add_byte_nl();
|
||||
Io_mgr.Instance.SaveFilBry(rdr.Urls()[0], tmp.To_bry_and_clear());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Io_line_rdr_fxt File_lines_(int fil_idx, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++)
|
||||
tmp.Add_int_fixed(i, 2).Add_byte_nl();
|
||||
Io_mgr.Instance.SaveFilBry(rdr.Urls()[fil_idx], tmp.To_bry_and_clear());
|
||||
return this;
|
||||
}
|
||||
public Io_line_rdr_fxt Clear() {rdr.Clear(); return this;}
|
||||
public Io_line_rdr_fxt tst_Read_til_lines(int count, String... expd) {
|
||||
lines.Clear();
|
||||
for (int i = 0; i < expd.length; i++)
|
||||
expd[i] = expd[i] + Op_sys.Lnx.Nl_str();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (rdr.Read_next())
|
||||
lines.Add(String_.new_u8(rdr.Bfr(), rdr.Itm_pos_bgn(), rdr.Itm_pos_end()));
|
||||
else
|
||||
break;
|
||||
}
|
||||
Tfds.Eq_ary_str(expd, lines.To_str_ary());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public interface Io_make_cmd extends Io_sort_cmd {
|
||||
Io_sort_cmd Make_dir_(Io_url v);
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.envs.*;
|
||||
import gplx.core.lists.*;
|
||||
public class Io_sort {
|
||||
public Io_sort Memory_max_(int v) {memory_max = v; return this;} private int memory_max = Io_mgr.Len_kb;
|
||||
public Io_url[] Split(Gfo_usr_dlg usr_dlg, Io_url_gen src_fil_gen, Io_url_gen trg_fil_gen, Io_line_rdr_key_gen key_gen) {return Split(usr_dlg, src_fil_gen, trg_fil_gen, Io_sort_split_itm_sorter.Instance, key_gen);}
|
||||
public Io_url[] Split(Gfo_usr_dlg usr_dlg, Io_url_gen src_fil_gen, Io_url_gen trg_fil_gen, ComparerAble row_comparer, Io_line_rdr_key_gen key_gen) {
|
||||
Io_line_rdr rdr = new Io_line_rdr(usr_dlg, src_fil_gen.Prv_urls()).Load_len_(4 * Io_mgr.Len_kb).Key_gen_(key_gen); // NOTE: do not set load_len to memory_max; only want to load in increments
|
||||
List_adp rv = List_adp_.New();
|
||||
Bry_bfr bfr = Bry_bfr_.Reset(Const_bfr_max); int size_cur = 0;
|
||||
List_adp row_list = List_adp_.New();
|
||||
while (true) {
|
||||
boolean reading = rdr.Read_next();
|
||||
int size_row = rdr.Itm_pos_end() - rdr.Itm_pos_bgn();
|
||||
int size_new = size_cur + size_row;
|
||||
if (size_new > memory_max || !reading) {
|
||||
usr_dlg.Prog_none(GRP_KEY, "sort", "sorting chunk");
|
||||
row_list.Sort_by(row_comparer);
|
||||
Io_url trg_url = trg_fil_gen.Nxt_url();
|
||||
usr_dlg.Prog_one(GRP_KEY, "write", "writing chunk: ~{0}", trg_url.Raw());
|
||||
Split_flush(trg_url, row_list, memory_max, bfr, rv);
|
||||
row_list.Resize_bounds(16); // MEM: resize bounds manually; note that each Flush-set may have widely disparately #of rows (EX: 1 row with a million pages vs. 1 million rows with 1 page)
|
||||
size_new = size_row; System_.Garbage_collect();
|
||||
if (!reading) break;
|
||||
}
|
||||
row_list.Add(new Io_sort_split_itm(rdr));
|
||||
size_cur = size_new;
|
||||
}
|
||||
rdr.Rls(); bfr.Rls(); System_.Garbage_collect();
|
||||
return (Io_url[])rv.To_ary(Io_url.class);
|
||||
}
|
||||
public void Merge(Gfo_usr_dlg usr_dlg, Io_url[] src_ary, ComparerAble comparer, Io_line_rdr_key_gen key_gen, Io_sort_cmd cmd) {
|
||||
BinaryHeap_Io_line_rdr heap = load_(usr_dlg, src_ary, comparer, key_gen, memory_max); if (heap.Len() == 0) return;//throw Err_.new_wo_type(Array_.To_str(src_ary));
|
||||
Io_line_rdr stream = null;
|
||||
cmd.Sort_bgn();
|
||||
while (true) {
|
||||
if (stream != null) { // stream found on previous iteration; try to put it back on heap
|
||||
boolean read = stream.Read_next();
|
||||
if (read) // stream has line; add to heap
|
||||
heap.Add(stream);
|
||||
else { // stream is empty; rls
|
||||
stream.Rls();
|
||||
if (heap.Len() == 0) break; // heap is empty; stop;
|
||||
}
|
||||
}
|
||||
stream = heap.Pop(); // note that .Pop removes stream from heap
|
||||
cmd.Sort_do(stream);
|
||||
}
|
||||
cmd.Sort_end();
|
||||
heap.Rls();
|
||||
}
|
||||
private static void Split_flush(Io_url url, List_adp list, int max, Bry_bfr tmp, List_adp url_list) {
|
||||
int len = list.Count();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Io_sort_split_itm itm = (Io_sort_split_itm)list.Get_at(i);
|
||||
int add_len = itm.Row_end() - itm.Row_bgn();
|
||||
if ((tmp.Len() + add_len) > Const_bfr_max) Io_mgr.Instance.AppendFilBfr(url, tmp);
|
||||
tmp.Add_mid(itm.Bfr(), itm.Row_bgn(), itm.Row_end());
|
||||
itm.Rls();
|
||||
}
|
||||
Io_mgr.Instance.AppendFilBfr(url, tmp);
|
||||
list.Clear();
|
||||
url_list.Add(url);
|
||||
}
|
||||
private static BinaryHeap_Io_line_rdr load_(Gfo_usr_dlg usr_dlg, Io_url[] urls, ComparerAble comparer, Io_line_rdr_key_gen key_gen, int memory_max) {
|
||||
BinaryHeap_Io_line_rdr rv = new BinaryHeap_Io_line_rdr(comparer);
|
||||
int urls_len = urls.length;
|
||||
int default_load_len = memory_max / urls_len + 1;
|
||||
for (int i = 0; i < urls_len; i++) {
|
||||
Io_url url = urls[i];
|
||||
int file_len = (int)Io_mgr.Instance.QueryFil(url).Size();
|
||||
int load_len = file_len < default_load_len ? file_len : default_load_len; // PERF.NOTE: 32 MB is default, but if file is 1 MB (or else) only create a bfr for 1 MB; using 32 MB will throw OutOfMemory on -Xmx 64m; DATE:20130112
|
||||
Io_line_rdr stream_bfr = new Io_line_rdr(usr_dlg, url).Key_gen_(key_gen).Load_len_(load_len);
|
||||
boolean read = stream_bfr.Read_next();
|
||||
if (read) // guard against empty files
|
||||
rv.Add(stream_bfr);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
static final int Const_bfr_max = Io_mgr.Len_mb;
|
||||
static final String GRP_KEY = "xowa.bldr.io_sort";
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public interface Io_sort_cmd {
|
||||
void Sort_bgn();
|
||||
void Sort_do(Io_line_rdr rdr);
|
||||
void Sort_end();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public interface Io_sort_filCmd {
|
||||
void Bfr_add(Io_line_rdr stream);
|
||||
void Fil_bgn(Io_line_rdr stream);
|
||||
void Fil_end();
|
||||
}
|
||||
class Io_sort_filCmd_null implements Io_sort_filCmd {
|
||||
public void Bfr_add(Io_line_rdr stream) {}
|
||||
public void Fil_bgn(Io_line_rdr stream) {}
|
||||
public void Fil_end() {}
|
||||
public static final Io_sort_filCmd_null Instance = new Io_sort_filCmd_null(); Io_sort_filCmd_null() {} // TS.static
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public class Io_sort_fil_basic implements Io_sort_cmd { // 123|bgn|end|1
|
||||
public Io_sort_fil_basic(Gfo_usr_dlg usr_dlg, Io_url_gen url_gen, int flush_len) {this.usr_dlg = usr_dlg; this.url_gen = url_gen; this.flush_len = flush_len;} Io_url_gen url_gen; Bry_bfr bfr = Bry_bfr_.New(); int flush_len; Gfo_usr_dlg usr_dlg;
|
||||
public void Sort_bgn() {}
|
||||
public void Sort_do(Io_line_rdr rdr) {
|
||||
int bgn = rdr.Itm_pos_bgn(), end = rdr.Itm_pos_end();
|
||||
if (bfr.Len() + (end - bgn) > flush_len) Flush();
|
||||
bfr.Add_mid(rdr.Bfr(), bgn, end);
|
||||
}
|
||||
public void Sort_end() {
|
||||
Flush();
|
||||
bfr.Rls();
|
||||
}
|
||||
private void Flush() {
|
||||
Io_url url = url_gen.Nxt_url();
|
||||
usr_dlg.Prog_one(GRP_KEY, "make", "making: ~{0}", url.NameAndExt());
|
||||
Io_mgr.Instance.SaveFilBry(url, bfr.Bfr(), bfr.Len());
|
||||
bfr.Clear();
|
||||
}
|
||||
static final String GRP_KEY = "xowa.bldr.io_sort";
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class Io_sort_misc_tst {
|
||||
@Before public void init() {
|
||||
}
|
||||
@Test public void Io_url_gen_dir() {
|
||||
tst_Io_url_gen_dir("mem/dir/", "{0}.xdat", 4, 3, "0000.xdat", "0001.xdat", "0002.xdat");
|
||||
}
|
||||
private void tst_Io_url_gen_dir(String dir_str, String fmt, int digits, int calls, String... expd) {
|
||||
Io_url dir = Io_url_.mem_dir_(dir_str);
|
||||
List_adp actl_list = List_adp_.New();
|
||||
Io_url_gen wkr = Io_url_gen_.dir_(dir, fmt, digits);
|
||||
for (int i = 0; i < calls; i++)
|
||||
actl_list.Add(wkr.Nxt_url().Raw());
|
||||
String[] actl = actl_list.To_str_ary();
|
||||
for (int i = 0; i < expd.length; i++)
|
||||
expd[i] = dir_str + expd[i];
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
}
|
||||
@Test public void Io_line_rdr_comparer_all() {
|
||||
tst_Io_line_rdr_fld_comparer(-1, "a", "b");
|
||||
tst_Io_line_rdr_fld_comparer( 0, "a", "a");
|
||||
tst_Io_line_rdr_fld_comparer( 1, "b", "a");
|
||||
tst_Io_line_rdr_fld_comparer(-1, "a", "ab");
|
||||
tst_Io_line_rdr_fld_comparer( 1, "ab", "a");
|
||||
}
|
||||
private void tst_Io_line_rdr_fld_comparer(int expd, String lhs_str, String rhs_str) {
|
||||
byte[] lhs = Bry_.new_u8(lhs_str), rhs = Bry_.new_u8(rhs_str);
|
||||
Tfds.Eq(expd, Bry_.Compare(lhs, 0, lhs.length, rhs, 0, rhs.length));
|
||||
}
|
||||
Io_line_rdr new_Io_line_rdr(String url_str, String text) {
|
||||
Io_url url = Io_url_.mem_fil_(url_str);
|
||||
Io_mgr.Instance.SaveFilStr(url, text);
|
||||
Io_line_rdr rv = new Io_line_rdr(Gfo_usr_dlg_.Test(), url);
|
||||
rv.Read_next();
|
||||
return rv;
|
||||
}
|
||||
@Test public void ExternalSort() {
|
||||
// fxt("c", "a", "b")
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public class Io_sort_split_itm {
|
||||
public Io_sort_split_itm() {}
|
||||
public Io_sort_split_itm(Io_line_rdr rdr) {Set(rdr);}
|
||||
public int Row_bgn() {return row_bgn;} private int row_bgn;
|
||||
public int Row_end() {return row_end;} private int row_end;
|
||||
public int Key_bgn() {return key_bgn;} private int key_bgn;
|
||||
public int Key_end() {return key_end;} private int key_end;
|
||||
public byte[] Bfr() {return bfr;} private byte[] bfr;
|
||||
public void Set(Io_line_rdr rdr) {
|
||||
bfr = rdr.Bfr();
|
||||
row_bgn = rdr.Itm_pos_bgn();
|
||||
row_end = rdr.Itm_pos_end();
|
||||
key_bgn = rdr.Key_pos_bgn();
|
||||
key_end = rdr.Key_pos_end();
|
||||
}
|
||||
public void Rls() {bfr = null;}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public class Io_sort_split_itm_sorter implements gplx.core.lists.ComparerAble {
|
||||
public int compare(Object lhsObj, Object rhsObj) {
|
||||
Io_sort_split_itm lhs = (Io_sort_split_itm)lhsObj, rhs = (Io_sort_split_itm)rhsObj;
|
||||
return Bry_.Compare(lhs.Bfr(), lhs.Key_bgn(), lhs.Key_end(), rhs.Bfr(), rhs.Key_bgn(), rhs.Key_end());
|
||||
}
|
||||
public static final Io_sort_split_itm_sorter Instance = new Io_sort_split_itm_sorter(); Io_sort_split_itm_sorter() {} // TS.static
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.strings.*;
|
||||
public class Io_sort_tst {
|
||||
Io_sort_fxt fxt = new Io_sort_fxt();
|
||||
@Test public void ExternalSort() {
|
||||
fxt.Clear().Memory_max_(12).Src_(fxt.GenRandom(6, 4)).Sorted_(fxt.GenOrdered(6, 4)).tst();
|
||||
fxt.Clear().Memory_max_(64).Src_(fxt.GenRandom(50, 4)).Sorted_(fxt.GenOrdered(50, 4)).tst();
|
||||
}
|
||||
}
|
||||
class Io_sort_fxt {
|
||||
Io_sort externalSort = new Io_sort().Memory_max_(Io_mgr.Len_kb);
|
||||
String_bldr sb = String_bldr_.new_();
|
||||
public Io_sort_fxt Clear() {Io_mgr.Instance.InitEngine_mem(); return this;}
|
||||
public Io_sort_fxt Memory_max_(int v) {externalSort.Memory_max_(v); return this;}
|
||||
public Io_sort_fxt Src_(String v) {src = v; return this;} private String src;
|
||||
public Io_sort_fxt Sorted_(String v) {sorted = v; return this;} private String sorted;
|
||||
public void tst() {
|
||||
Io_url src_url = Io_url_.mem_fil_("mem/src.txt");
|
||||
Io_url trg_url = Io_url_.mem_fil_("mem/trg.txt");
|
||||
Io_mgr.Instance.DeleteFil(src_url); Io_mgr.Instance.DeleteFil(trg_url);
|
||||
|
||||
Io_mgr.Instance.SaveFilStr(src_url, src);
|
||||
|
||||
Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Test();
|
||||
Io_url_gen src_fil_gen = Io_url_gen_.fil_(src_url);
|
||||
Io_url[] tmp_url_ary = externalSort.Split(usr_dlg, src_fil_gen, Io_url_gen_.dir_(src_url.OwnerDir()), Io_line_rdr_key_gen_.first_pipe);
|
||||
Io_sort_fil_basic cmd = new Io_sort_fil_basic(usr_dlg, Io_url_gen_.fil_(trg_url), Io_mgr.Len_kb);
|
||||
externalSort.Merge(usr_dlg, tmp_url_ary, Io_sort_split_itm_sorter.Instance, Io_line_rdr_key_gen_.first_pipe, cmd);
|
||||
|
||||
String actl = Io_mgr.Instance.LoadFilStr(trg_url);
|
||||
Tfds.Eq_ary_str(String_.SplitLines_nl(sorted), String_.SplitLines_nl(actl));
|
||||
}
|
||||
public String GenRandom(int rows, int pad) {
|
||||
List_adp list = List_adp_.New();
|
||||
for (int i = 0; i < rows; i++)
|
||||
list.Add(Int_.To_str_pad_bgn_zero(i, pad) + "|");
|
||||
list.Shuffle();
|
||||
for (int i = 0; i < rows; i++) {
|
||||
String itm = (String)list.Get_at(i);
|
||||
sb.Add(itm).Add_char_nl();
|
||||
}
|
||||
return sb.To_str_and_clear();
|
||||
}
|
||||
public String GenOrdered(int rows, int pad) {
|
||||
for (int i = 0; i < rows; i++)
|
||||
sb.Add(Int_.To_str_pad_bgn_zero(i, pad) + "|" + "\n");
|
||||
return sb.To_str_and_clear();
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import java.io.InputStream;
|
||||
import gplx.core.ios.streams.*;
|
||||
public class Io_stream_rdr_process implements Io_stream_rdr {
|
||||
private Process process;
|
||||
private InputStream stream_read;
|
||||
private String[] process_args;
|
||||
Io_stream_rdr_process(Io_url process_exe, Io_url stream_url, String[] process_args) {this.process_exe = process_exe; this.url = stream_url; this.process_args = process_args;}
|
||||
public byte Tid() {return Io_stream_tid_.Tid__bzip2;} // for now, classify as bzip2; not sure if separate tid is necessary
|
||||
public boolean Exists() {return this.Len() > 0;}
|
||||
public Io_url Url() {return url;} public Io_stream_rdr Url_(Io_url v) {url = v; return this;} private Io_url url;
|
||||
public long Len() {return len;} public Io_stream_rdr Len_(long v) {len = v; return this;} private long len;
|
||||
public Io_url Process_exe() {return process_exe;} private Io_url process_exe;
|
||||
public Io_stream_rdr Open() {
|
||||
ProcessBuilder pb = new ProcessBuilder(process_args);
|
||||
pb.redirectErrorStream(false);
|
||||
try {process = pb.start();}
|
||||
catch (Exception e) {throw Err_.new_exc(e, "core", "process init failed", "args", String_.AryXtoStr(process_args));}
|
||||
stream_read = process.getInputStream();
|
||||
return this;
|
||||
}
|
||||
public void Open_mem(byte[] v) {throw Err_.new_unimplemented();}
|
||||
public Object Under() {throw Err_.new_unimplemented();}
|
||||
|
||||
public int Read(byte[] bry, int bgn, int len) {
|
||||
try {
|
||||
int rv = 0;
|
||||
int cur_pos = bgn;
|
||||
int cur_len = len;
|
||||
while (true) {
|
||||
int read = stream_read.read(bry, cur_pos, cur_len);
|
||||
if (read <= 0) break;
|
||||
rv += read;
|
||||
cur_pos += read;
|
||||
cur_len -= read;
|
||||
if (rv >= len) break;
|
||||
}
|
||||
return rv;
|
||||
} catch (Exception e) {throw Err_.new_exc(e, "io", "process read failed", "bgn", bgn, "len", len);}
|
||||
}
|
||||
public long Skip(long len) {
|
||||
try {return stream_read.skip(len);}
|
||||
catch (Exception e) {throw Err_.new_exc(e, "io", "process skip failed", "len", len);}
|
||||
}
|
||||
public void Rls() {
|
||||
try {stream_read.close();}
|
||||
catch (Exception e) {throw Err_.new_exc(e, "io", "process rls failed");}
|
||||
process.destroy();
|
||||
}
|
||||
public static Io_stream_rdr_process new_(Io_url process_exe, Io_url stream_url, String... process_args) {return new Io_stream_rdr_process(process_exe, stream_url, process_args);}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.ios.streams.*;
|
||||
public class Io_stream_zip_mgr {
|
||||
private Io_stream_wtr wtr__gzip, wtr__zip, wtr__bzip2, wtr__xz;
|
||||
public byte[] Zip(byte type, byte[] val) {
|
||||
if (type == Io_stream_tid_.Tid__raw) return val;
|
||||
Io_stream_wtr wtr = Wtr(type);
|
||||
wtr.Write(val, 0, val.length);
|
||||
wtr.Flush();
|
||||
return wtr.To_ary_and_clear();
|
||||
}
|
||||
public byte[] Unzip(byte type, byte[] val) {
|
||||
if (type == Io_stream_tid_.Tid__raw) return val;
|
||||
Io_stream_rdr rdr = Rdr(type);
|
||||
rdr.Open_mem(val);
|
||||
return Io_stream_rdr_.Load_all_as_bry(Bry_bfr_.New(), rdr);
|
||||
}
|
||||
private Io_stream_wtr Wtr(byte type) {
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
switch (type) {
|
||||
case Io_stream_tid_.Tid__gzip: if (wtr__gzip == null) wtr__gzip = Io_stream_wtr_.New_by_mem(bfr, Io_stream_tid_.Tid__gzip); return wtr__gzip.Open();
|
||||
case Io_stream_tid_.Tid__zip: if (wtr__zip == null) wtr__zip = Io_stream_wtr_.New_by_mem(bfr, Io_stream_tid_.Tid__zip); return wtr__zip.Open();
|
||||
case Io_stream_tid_.Tid__bzip2: if (wtr__bzip2 == null) wtr__bzip2 = Io_stream_wtr_.New_by_mem(bfr, Io_stream_tid_.Tid__bzip2); return wtr__bzip2.Open();
|
||||
case Io_stream_tid_.Tid__xz: if (wtr__xz == null) wtr__xz = Io_stream_wtr_.New_by_mem(bfr, Io_stream_tid_.Tid__xz); return wtr__xz.Open();
|
||||
case Io_stream_tid_.Tid__raw:
|
||||
default: throw Err_.new_unhandled(type);
|
||||
}
|
||||
}
|
||||
private Io_stream_rdr Rdr(byte type) { // TS.MEM: DATE:2016-07-12
|
||||
switch (type) {
|
||||
case Io_stream_tid_.Tid__gzip: return Io_stream_rdr_.New_by_tid(Io_stream_tid_.Tid__gzip);
|
||||
case Io_stream_tid_.Tid__zip: return Io_stream_rdr_.New_by_tid(Io_stream_tid_.Tid__zip);
|
||||
case Io_stream_tid_.Tid__bzip2: return Io_stream_rdr_.New_by_tid(Io_stream_tid_.Tid__bzip2);
|
||||
case Io_stream_tid_.Tid__xz: return Io_stream_rdr_.New_by_tid(Io_stream_tid_.Tid__xz);
|
||||
case Io_stream_tid_.Tid__raw:
|
||||
default: throw Err_.new_unhandled(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public interface Io_url_gen {
|
||||
Io_url Cur_url();
|
||||
Io_url Nxt_url();
|
||||
Io_url[] Prv_urls();
|
||||
void Del_all();
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
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.ios; import gplx.*; import gplx.core.*;
|
||||
public class Io_url_gen_ {
|
||||
public static Io_url_gen dir_(Io_url v) {return new Io_url_gen_dir(v);}
|
||||
public static Io_url_gen dir_(Io_url v, String fmt, int digits) {return new Io_url_gen_dir(v).Fmt_(fmt).Fmt_digits_(digits);}
|
||||
public static Io_url_gen fil_(Io_url v) {return new Io_url_gen_fil(v);}
|
||||
}
|
||||
class Io_url_gen_dir implements Io_url_gen {
|
||||
public String Fmt() {return fmt;} public Io_url_gen_dir Fmt_(String v) {fmt = v; return this;} private String fmt = "{0}.csv";
|
||||
public int Fmt_digits() {return fmt_digits;} public Io_url_gen_dir Fmt_digits_(int v) {fmt_digits = v; return this;} private int fmt_digits = 10;
|
||||
public Io_url Cur_url() {return cur_url;} Io_url cur_url;
|
||||
public Io_url Nxt_url() {cur_url = dir.GenSubFil(String_.Format(fmt, Int_.To_str_pad_bgn_zero(idx++, fmt_digits))); return cur_url;} private int idx = 0;
|
||||
public Io_url[] Prv_urls() {
|
||||
Io_url[] rv = new Io_url[idx];
|
||||
for (int i = 0; i < idx; i++) {
|
||||
rv[i] = dir.GenSubFil(String_.Format(fmt, Int_.To_str_pad_bgn_zero(i, fmt_digits)));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public void Del_all() {if (Io_mgr.Instance.ExistsDir(dir)) Io_mgr.Instance.DeleteDirDeep(dir);}
|
||||
public Io_url_gen_dir(Io_url dir) {this.dir = dir;} Io_url dir;
|
||||
}
|
||||
class Io_url_gen_fil implements Io_url_gen {
|
||||
public Io_url Cur_url() {return cur_url;} Io_url cur_url;
|
||||
public Io_url Nxt_url() {return cur_url;}
|
||||
public Io_url[] Prv_urls() {return new Io_url[]{cur_url};}
|
||||
public void Del_all() {Io_mgr.Instance.DeleteFil_args(cur_url).MissingFails_off().Exec();}
|
||||
public Io_url_gen_fil(Io_url fil) {this.cur_url = fil;}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
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.*;
|
||||
class StatRng_fxt { // UNUSED:useful for stat processing
|
||||
StatRng rng;
|
||||
public StatRng_fxt ini_(int lo_ary_len, int hi_ary_len, int... slot_hi_ary) {
|
||||
rng = new StatRng(lo_ary_len, hi_ary_len, slot_hi_ary);
|
||||
return this;
|
||||
}
|
||||
public StatRng_fxt tst_(int... vals) {
|
||||
for (int i = 0; i < vals.length; i++) {
|
||||
int val = vals[i];
|
||||
rng.Assign(val, val);
|
||||
}
|
||||
Tfds.Eq(expd_count, rng.Count, "Count");
|
||||
Tfds.Eq(expd_lo, rng.Lo, "Lo");
|
||||
Tfds.Eq(expd_hi, rng.Hi, "Hi");
|
||||
Tfds.Eq_float(expd_avg, rng.Avg());
|
||||
Tfds.Eq_ary(expd_lo_ary, XtoIntAry(rng.Lo_ary), "Lo_ary");
|
||||
Tfds.Eq_ary(expd_hi_ary, XtoIntAry(rng.Hi_ary), "Hi_ary");
|
||||
Tfds.Eq_ary(expd_slots, XtoIntAry(rng.Slot_ary), "Slots");
|
||||
return this;
|
||||
}
|
||||
int[] XtoIntAry(StatItm[] ary) {
|
||||
int[] rv = new int[ary.length];
|
||||
for (int i = 0; i < rv.length; i++)
|
||||
rv[i] = ary[i].Val;
|
||||
return rv;
|
||||
}
|
||||
int[] XtoIntAry(StatRng[] ary) {
|
||||
int[] rv = new int[ary.length];
|
||||
for (int i = 0; i < rv.length; i++)
|
||||
rv[i] = ary[i].Count;
|
||||
return rv;
|
||||
}
|
||||
public StatRng_fxt Count_(int v) {expd_count = v; return this;} private int expd_count;
|
||||
public StatRng_fxt Lo_(int v) {expd_lo = v; return this;} private int expd_lo;
|
||||
public StatRng_fxt Hi_(int v) {expd_hi = v; return this;} private int expd_hi;
|
||||
public StatRng_fxt Avg_(float v) {expd_avg = v; return this;} float expd_avg;
|
||||
public StatRng_fxt Lo_ary_(int... v) {expd_lo_ary = v; return this;} private int[] expd_lo_ary;
|
||||
public StatRng_fxt Hi_ary_(int... v) {expd_hi_ary = v; return this;} private int[] expd_hi_ary;
|
||||
public StatRng_fxt Slots_(int... v) {expd_slots = v; return this;} private int[] expd_slots;
|
||||
}
|
||||
class StatRng {
|
||||
// public String Key;
|
||||
public int Lo = Int_.Max_value;
|
||||
public int Hi = Int_.Min_value;
|
||||
public long Sum = 0;
|
||||
public int Count = 0;
|
||||
public float Avg() {return Sum / Count;}
|
||||
public final StatItm[] Lo_ary;
|
||||
public int Lo_ary_bound;
|
||||
public int Lo_ary_len;
|
||||
public final StatItm[] Hi_ary;
|
||||
public int Hi_ary_bound;
|
||||
public int Hi_ary_len;
|
||||
public StatRng[] Slot_ary;
|
||||
public int Slot_ary_len;
|
||||
public StatRng(int lo_ary_len, int hi_ary_len, int... slot_hi_ary) {
|
||||
this.Lo_ary_len = lo_ary_len;
|
||||
this.Lo_ary_bound = Int_.Max_value;
|
||||
this.Lo_ary = NewBoundAry(lo_ary_len, Int_.Max_value);
|
||||
this.Hi_ary_len = hi_ary_len;
|
||||
this.Hi_ary_bound = Int_.Min_value;
|
||||
this.Hi_ary = NewBoundAry(hi_ary_len, Int_.Min_value);
|
||||
if (slot_hi_ary != null && slot_hi_ary.length > 0) {
|
||||
Slot_ary_len = slot_hi_ary.length + 1; // + 1 to hold max value
|
||||
Slot_ary = new StatRng[Slot_ary_len];
|
||||
int slot_lo = Int_.Min_value;
|
||||
for (int i = 0; i < Slot_ary_len - 1; i++) {
|
||||
int slot_hi = slot_hi_ary[i];
|
||||
Slot_ary[i] = NewSlot(slot_lo, slot_hi);
|
||||
slot_lo = slot_hi;
|
||||
}
|
||||
Slot_ary[Slot_ary_len - 1] = NewSlot(slot_lo, Int_.Max_value);
|
||||
}
|
||||
}
|
||||
public void Assign(Object key, int val) {
|
||||
if (val < Lo) Lo = val;
|
||||
if (val > Hi) Hi = val;
|
||||
Sum += val;
|
||||
++Count;
|
||||
|
||||
if (Slot_ary_len > 0) {
|
||||
for (int i = 0; i < Slot_ary_len; i++) {
|
||||
StatRng slot = Slot_ary[i];
|
||||
if (val >= slot.Lo && val < slot.Hi)
|
||||
slot.Assign(key, val);
|
||||
}
|
||||
}
|
||||
if (val < Lo_ary_bound) {
|
||||
Lo_ary_bound = CalcCutoff(Lo_ary, CompareAble_.More, Int_.Min_value, key, val);
|
||||
}
|
||||
if (val > Hi_ary_bound) {
|
||||
Hi_ary_bound = CalcCutoff(Hi_ary, CompareAble_.Less, Int_.Max_value, key, val);
|
||||
}
|
||||
}
|
||||
int CalcCutoff(StatItm[] ary, int comp, int bgn_bound, Object key, int val) {
|
||||
int new_bound = bgn_bound;
|
||||
for (int i = 0; i < ary.length; i++) {
|
||||
StatItm itm = ary[i];
|
||||
if (Int_.Compare(itm.Val, val) == comp) {
|
||||
itm = new StatItm(key, val);
|
||||
ary[i] = itm;
|
||||
}
|
||||
if (Int_.Compare(itm.Val, new_bound) == comp) new_bound = itm.Val;
|
||||
}
|
||||
return new_bound;
|
||||
}
|
||||
StatRng NewSlot(int lo, int hi) {
|
||||
StatRng rv = new StatRng(0, 0);
|
||||
rv.Lo = lo;
|
||||
rv.Hi = hi;
|
||||
return rv;
|
||||
}
|
||||
StatItm[] NewBoundAry(int len, int dflt) {
|
||||
StatItm[] rv = new StatItm[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
rv[i] = new StatItm(null, dflt);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class StatItm {
|
||||
public Object Key;
|
||||
public int Val;
|
||||
public StatItm(Object key, int val) {this.Key = key; this.Val = val;}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
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.*;
|
||||
public class StatRng_tst {
|
||||
// Mwl_parser_fxt fx = new Mwl_parser_fxt(); Pf_func_lang_rsc rsc = Pf_func_lang_rsc.Instance;
|
||||
StatRng_fxt fx = new StatRng_fxt();
|
||||
@Test public void Empty() {
|
||||
fx.ini_(1, 1, 5);
|
||||
fx.Count_(7).Lo_(2).Hi_(8).Avg_(5)
|
||||
.Lo_ary_(2)
|
||||
.Hi_ary_(8)
|
||||
.Slots_(3, 4);
|
||||
fx.tst_(5,7,2,8,3,4,6);
|
||||
}
|
||||
//@Test public void Basic() {fx.Test_parse_tmpl_str_test("{{#switch:{{{1}}}|a=1|b=2|3}}", "{{test|a}}", "1");}
|
||||
//@Test public void Basic() {fx.Test_parse_tmpl_str_test("{{#switch:{{{1}}}|b=2|#default=3|a=1}}", "{{test|a}}", "1");}
|
||||
//@Test public void Basic() {fx.Test_parse_tmpl_str_test("{{#switch:{{{1}}}|a|b|c=1|d=2}}", "{{test|a}}", "1");}
|
||||
}
|
||||
/*
|
||||
public class Pf_func_switch_tst {
|
||||
// Mwl_parser_fxt fx = new Mwl_parser_fxt(); Pf_func_lang_rsc rsc = Pf_func_lang_rsc.Instance;
|
||||
|
||||
*/
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
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.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
public interface Binary_comparer {
|
||||
int Compare_val_to_obj(Object val, Object obj);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
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.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
public class Binary_search_ {
|
||||
public static int Search(CompareAble[] ary , CompareAble val) {return Search(new Binary_search_grp__ary(ary) , new Binary_search_cmp__comparable(val));}
|
||||
public static int Search(Object[] ary , Binary_comparer comparer, Object val) {return Search(new Binary_search_grp__ary(ary), new Binary_search_cmp__comparer(comparer, val));}
|
||||
private static int Search(Binary_search_grp grp, Binary_search_cmp cmp) {
|
||||
int grp_len = grp.Len();
|
||||
if (grp_len == 1) return 0; // if 1 item, return 0;
|
||||
if (grp_len == 0) return Bry_find_.Not_found; // if 0 item, return -1
|
||||
|
||||
// init
|
||||
int interval = grp_len / 2;
|
||||
int pos = interval - List_adp_.Base1;
|
||||
int pos_last = grp_len - 1;
|
||||
int pos_prv = -1;
|
||||
int loop_count = 0;
|
||||
while (loop_count++ < 32) { // 32=32-bit integer
|
||||
Object lo = grp.Get_at(pos);
|
||||
Object hi = pos + 1 == grp_len ? null : grp.Get_at(pos + 1);
|
||||
int adj = 0;
|
||||
int lo_comp = cmp.Compare(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 = cmp.Compare(hi);
|
||||
switch (hi_comp) {
|
||||
case CompareAble_.More: // val is > hi; search slots above
|
||||
adj = 1;
|
||||
break;
|
||||
case CompareAble_.Same: // val is > hi; search slots above
|
||||
return pos + 1;
|
||||
case CompareAble_.Less: // val is > lo and < hi; return slot
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
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 Bry_find_.Not_found; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
import org.junit.*; import gplx.core.primitives.*;
|
||||
public class Binary_search__tst {
|
||||
private final 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);
|
||||
}
|
||||
@Test public void Catpage() {
|
||||
String[] ary = new String[25];
|
||||
for (int i = 0; i < 25; ++i)
|
||||
ary[i] = Int_.To_str_pad_bgn_zero(i, 2);
|
||||
fxt.Init__ary(ary);
|
||||
fxt.Test__binary_search("10", 10); // was 9
|
||||
}
|
||||
}
|
||||
class Binary_search__fxt {
|
||||
private String_obj_val[] ary;
|
||||
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]);
|
||||
}
|
||||
public void Test__binary_search(String val, int expd) {
|
||||
int actl = Binary_search_.Search(ary, String_obj_val.new_(val));
|
||||
Tfds.Eq(expd, actl, val);
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
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.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
import gplx.core.lists.*;
|
||||
interface Binary_search_cmp {
|
||||
int Compare(Object comp);
|
||||
}
|
||||
class Binary_search_cmp__comparable implements Binary_search_cmp {
|
||||
private final CompareAble val;
|
||||
public Binary_search_cmp__comparable(CompareAble val) {this.val = val;}
|
||||
public int Compare(Object comp) {
|
||||
return val.compareTo((CompareAble)comp);
|
||||
}
|
||||
}
|
||||
class Binary_search_cmp__comparer implements Binary_search_cmp {
|
||||
private final Binary_comparer comparer; private final Object val;
|
||||
public Binary_search_cmp__comparer(Binary_comparer comparer, Object val) {this.comparer = comparer; this.val = val;}
|
||||
public int Compare(Object comp) {
|
||||
return comparer.Compare_val_to_obj(val, comp);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
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.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
interface Binary_search_grp {
|
||||
int Len();
|
||||
Object Get_at(int i);
|
||||
}
|
||||
class Binary_search_grp__ary implements Binary_search_grp {
|
||||
private final Object[] ary;
|
||||
public Binary_search_grp__ary(Object[] ary) {this.ary = ary;}
|
||||
public int Len() {return ary.length;}
|
||||
public Object Get_at(int i) {return ary[i];}
|
||||
}
|
||||
class Binary_search_grp__list implements Binary_search_grp {
|
||||
private final List_adp list;
|
||||
public Binary_search_grp__list(List_adp list) {this.list = list;}
|
||||
public int Len() {return list.Len();}
|
||||
public Object Get_at(int i) {return list.Get_at(i);}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
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.hashs; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
import gplx.core.primitives.*;
|
||||
public class Hash_adp__int {
|
||||
private final Hash_adp hash = Hash_adp_.New();
|
||||
private final Int_obj_ref tmp_key = Int_obj_ref.New_neg1();
|
||||
public void Clear() {hash.Clear();}
|
||||
public int Len() {return hash.Count();}
|
||||
public Object Get_by_or_fail(int key) {synchronized (tmp_key) {return hash.Get_by_or_fail(tmp_key.Val_(key));}} // LOCK:used by Xomp_ns_ord_mgr in xomp; DATE:2016-10-18
|
||||
public Object Get_by_or_null(int key) {synchronized (tmp_key) {return hash.Get_by(tmp_key.Val_(key));}} // LOCK:used by Xomp_ns_ord_mgr in xomp; DATE:2016-10-18
|
||||
public void Add(int key, Object obj) {hash.Add(Int_obj_ref.New(key), obj);}
|
||||
public void Add(Int_obj_ref key, Object obj) {hash.Add(key, obj);}
|
||||
public void Add_if_dupe_use_1st(int key, Object obj) {hash.Add_if_dupe_use_1st(Int_obj_ref.New(key), obj);}
|
||||
public void Add_if_dupe_use_nth(Int_obj_ref key, Object obj) {hash.Add_if_dupe_use_nth(key, obj);}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
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 Gfo_inet_conn {
|
||||
int Tid();
|
||||
void Clear();
|
||||
void Upload_by_bytes(String url, byte[] data);
|
||||
byte[] Download_as_bytes_or_null(String url); // return null instead of throwing exception
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
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 Gfo_inet_conn_ {
|
||||
public static final int Tid__http = 1, Tid__mem__hash = 2, Tid__mem__pile = 3;
|
||||
public static Gfo_inet_conn new_http() {return new Gfo_inet_conn__http();}
|
||||
public static Gfo_inet_conn new_mem_hash() {return new Gfo_inet_conn__mem__hash();}
|
||||
public static Gfo_inet_conn new_mem_pile() {return new Gfo_inet_conn__mem__pile();}
|
||||
public static Gfo_inet_conn new_() {
|
||||
switch (new_prototype) {
|
||||
default:
|
||||
case Tid__http: return new_http();
|
||||
case Tid__mem__hash: return new_mem_hash();
|
||||
case Tid__mem__pile: return new_mem_pile();
|
||||
}
|
||||
}
|
||||
public static void new_prototype_(int v) {new_prototype = v;} private static int new_prototype = Tid__http;
|
||||
}
|
||||
class Gfo_inet_conn__mem__hash implements Gfo_inet_conn {
|
||||
private final Hash_adp hash = Hash_adp_.New();
|
||||
public int Tid() {return Gfo_inet_conn_.Tid__mem__hash;}
|
||||
public void Clear() {hash.Clear();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {hash.Add(url, data);}
|
||||
public byte[] Download_as_bytes_or_null(String url) {return (byte[])hash.Get_by(url);}
|
||||
}
|
||||
class Gfo_inet_conn__mem__pile implements Gfo_inet_conn {
|
||||
private final List_adp pile = List_adp_.New();
|
||||
public int Tid() {return Gfo_inet_conn_.Tid__mem__hash;}
|
||||
public void Clear() {pile.Clear();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {pile.Add(data);}
|
||||
public byte[] Download_as_bytes_or_null(String url) {return (byte[])List_adp_.Pop_last(pile);}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
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.ios.*;
|
||||
class Gfo_inet_conn__http implements Gfo_inet_conn {
|
||||
private final IoEngine_xrg_downloadFil downloader = IoEngine_xrg_downloadFil.new_("", Io_url_.Empty);
|
||||
public int Tid() {return Gfo_inet_conn_.Tid__http;}
|
||||
public void Clear() {throw Err_.new_unsupported();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {throw Err_.new_unsupported();}
|
||||
public byte[] Download_as_bytes_or_null(String url) {
|
||||
try {return downloader.Exec_as_bry(url);}
|
||||
catch (Exception e) {Err_.Noop(e); return null;}
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
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 Gfo_protocol_itm {
|
||||
public Gfo_protocol_itm(byte tid, String text) {
|
||||
this.tid = tid;
|
||||
this.text_bry = Bry_.new_u8(text);
|
||||
this.text_str = text;
|
||||
int text_len = text_bry.length;
|
||||
for (int i = 0; i < text_len; i++) {
|
||||
if (text_bry[i] == Byte_ascii.Colon) {
|
||||
this.key_wo_colon_bry = Bry_.Mid(text_bry, 0, i);
|
||||
this.key_w_colon_bry_len = i;
|
||||
this.key_wo_colon_str = String_.new_u8(key_wo_colon_bry);
|
||||
this.key_w_colon_bry = Bry_.Mid(text_bry, 0, i + 1);
|
||||
this.key_w_colon_str = String_.new_u8(key_w_colon_bry);
|
||||
this.text_ends_w_colon = i == text_len - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Key_wo_colon_bry() {return key_wo_colon_bry;} private byte[] key_wo_colon_bry; // http
|
||||
public String Key_wo_colon_str() {return key_wo_colon_str;} private String key_wo_colon_str;
|
||||
public byte[] Key_w_colon_bry() {return key_w_colon_bry;} private byte[] key_w_colon_bry; // http:
|
||||
public String Key_w_colon_str() {return key_w_colon_str;} private String key_w_colon_str;
|
||||
public int Key_w_colon_bry_len() {return key_w_colon_bry_len;} private int key_w_colon_bry_len;
|
||||
public byte[] Text_bry() {return text_bry;} private byte[] text_bry; // http://
|
||||
public String Text_str() {return text_str;} private String text_str;
|
||||
public boolean Text_ends_w_colon() {return text_ends_w_colon;} private boolean text_ends_w_colon;
|
||||
public static final byte // REF.MW:DefaultSettings|$wgUrlProtocols; NOTE: "news:" not included because it breaks alias "wikinews:"
|
||||
Tid_http = 0
|
||||
, Tid_https = 1
|
||||
, Tid_ftp = 2
|
||||
, Tid_ftps = 3
|
||||
, Tid_ssh = 4
|
||||
, Tid_sftp = 5
|
||||
, Tid_irc = 6
|
||||
, Tid_ircs = 7
|
||||
, Tid_xmpp = 8
|
||||
, Tid_sip = 9
|
||||
, Tid_sips = 10
|
||||
, Tid_gopher = 11
|
||||
, Tid_telnet = 12
|
||||
, Tid_nntp = 13
|
||||
, Tid_worldwind = 14
|
||||
, Tid_mailto = 15
|
||||
, Tid_tel = 16
|
||||
, Tid_sms = 17
|
||||
, Tid_svn = 18
|
||||
, Tid_git = 19
|
||||
, Tid_mms = 20
|
||||
, Tid_bitcoin = 21
|
||||
, Tid_magnet = 22
|
||||
, Tid_urn = 23
|
||||
, Tid_geo = 24
|
||||
, Tid_null = 25
|
||||
, Tid_unknown = 26
|
||||
, Tid_xowa = 27
|
||||
, Tid_file = 28
|
||||
, Tid_relative_1 = 29 // [//a.org]
|
||||
, Tid_relative_2 = 30 // [[//a.org]]
|
||||
;
|
||||
public static final Ordered_hash Regy = Ordered_hash_.New_bry();
|
||||
public static final Gfo_protocol_itm
|
||||
Itm_http = new_(Tid_http , "http://")
|
||||
, Itm_https = new_(Tid_https , "https://")
|
||||
, Itm_ftp = new_(Tid_ftp , "ftp://")
|
||||
, Itm_ftps = new_(Tid_ftps , "ftps://")
|
||||
, Itm_ssh = new_(Tid_ssh , "ssh://")
|
||||
, Itm_sftp = new_(Tid_sftp , "sftp://")
|
||||
, Itm_irc = new_(Tid_irc , "irc://")
|
||||
, Itm_ircs = new_(Tid_ircs , "ircs://")
|
||||
, Itm_xmpp = new_(Tid_xmpp , "xmpp:")
|
||||
, Itm_sip = new_(Tid_sip , "sip:")
|
||||
, Itm_sips = new_(Tid_sips , "sips:")
|
||||
, Itm_gopher = new_(Tid_gopher , "gopher://")
|
||||
, Itm_telnet = new_(Tid_telnet , "telnet://")
|
||||
, Itm_nntp = new_(Tid_nntp , "nntp://")
|
||||
, Itm_worldwind = new_(Tid_worldwind , "worldwind://")
|
||||
, Itm_mailto = new_(Tid_mailto , "mailto:")
|
||||
, Itm_tel = new_(Tid_tel , "tel:")
|
||||
, Itm_sms = new_(Tid_sms , "sms:")
|
||||
, Itm_svn = new_(Tid_svn , "svn://")
|
||||
, Itm_git = new_(Tid_git , "git://")
|
||||
, Itm_mms = new_(Tid_mms , "mms://")
|
||||
, Itm_bitcoin = new_(Tid_bitcoin , "bicoin:")
|
||||
, Itm_magnet = new_(Tid_magnet , "magnet:")
|
||||
, Itm_urn = new_(Tid_urn , "urn:")
|
||||
, Itm_geo = new_(Tid_geo , "geo:")
|
||||
;
|
||||
public static final String Str_file = "file:", Str_xcmd = "xowa-cmd:";
|
||||
public static final byte[] Bry_file = Bry_.new_a7(Str_file), Bry_xcmd = Bry_.new_a7(Str_xcmd);
|
||||
public static final byte[] Bry_file_with_slashes = Bry_.new_a7("file:///");
|
||||
public static final int Len_xcmd = Bry_xcmd.length;
|
||||
public static final byte[] Bry_relative = Bry_.new_a7("//");
|
||||
public static Gfo_protocol_itm Get_or(byte tid, Gfo_protocol_itm or) {
|
||||
Gfo_protocol_itm[] ary = Ary();
|
||||
return tid >= ary.length ? or : ary[tid];
|
||||
}
|
||||
public static Gfo_protocol_itm[] Ary() {
|
||||
if (protocol_itm_ary == null) {
|
||||
int len = Regy.Count();
|
||||
protocol_itm_ary = new Gfo_protocol_itm[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
protocol_itm_ary[i] = (Gfo_protocol_itm)Regy.Get_at(i);
|
||||
}
|
||||
return protocol_itm_ary;
|
||||
} private static Gfo_protocol_itm[] protocol_itm_ary;
|
||||
public static String[] Protocol_str_ary() {
|
||||
if (protocol_str_ary == null) {
|
||||
int len = Regy.Count();
|
||||
protocol_str_ary = new String[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
protocol_str_ary[i] = ((Gfo_protocol_itm)Regy.Get_at(i)).Text_str();
|
||||
}
|
||||
return protocol_str_ary;
|
||||
} private static String[] protocol_str_ary;
|
||||
private static Gfo_protocol_itm new_(byte tid, String text) {
|
||||
Gfo_protocol_itm rv = new Gfo_protocol_itm(tid, text);
|
||||
Regy.Add(rv.Key_wo_colon_bry(), rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
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.net.qargs.*;
|
||||
public class Gfo_url {
|
||||
private final int segs__len;
|
||||
public Gfo_url(byte[] raw, byte protocol_tid, byte[] protocol_bry, byte[][] segs, Gfo_qarg_itm[] qargs, byte[] anch) {
|
||||
this.raw = raw;
|
||||
this.protocol_tid = protocol_tid; this.protocol_bry = protocol_bry;
|
||||
this.segs = segs; this.segs__len = segs.length;
|
||||
this.qargs = qargs;
|
||||
this.anch = anch;
|
||||
}
|
||||
public byte[] Raw() {return raw;} private final byte[] raw;
|
||||
public byte Protocol_tid() {return protocol_tid;} private final byte protocol_tid;
|
||||
public byte[] Protocol_bry() {return protocol_bry;} private final byte[] protocol_bry;
|
||||
public byte[] Anch() {return anch;} private final byte[] anch;
|
||||
public Gfo_qarg_itm[] Qargs() {return qargs;} private final Gfo_qarg_itm[] qargs;
|
||||
public byte[][] Segs() {return segs;} private final byte[][] segs;
|
||||
public byte[] Segs__get_at(int i) {return i < segs__len ? segs[i] : null;}
|
||||
public byte[] Segs__get_at_1st() {return segs__len > 0 ? segs[0] : null;}
|
||||
public byte[] Segs__get_at_nth() {return segs__len > 1 ? segs[segs__len - 1] : null;}
|
||||
|
||||
public static final Gfo_url Empty = new Gfo_url(Bry_.Empty, Gfo_protocol_itm.Tid_unknown, Bry_.Empty, Bry_.Ary_empty, null, null);
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
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.btries.*;
|
||||
import gplx.core.net.qargs.*;
|
||||
import gplx.langs.htmls.encoders.*;
|
||||
public class Gfo_url_parser {
|
||||
private final Btrie_slim_mgr protocols = Btrie_slim_mgr.ci_a7(); // ASCII:url_protocol; EX:"http:", "ftp:", etc
|
||||
private final Btrie_rv trv = new Btrie_rv();
|
||||
private final List_adp segs_list = List_adp_.New(), qargs_list = List_adp_.New();
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.Reset(500);
|
||||
public Gfo_url_parser() {
|
||||
Init_protocols(Gfo_protocol_itm.Ary());
|
||||
Init_protocol_itm(Gfo_protocol_itm.Bry_relative, Gfo_protocol_itm.Tid_relative_1);
|
||||
Init_protocol_itm(Gfo_protocol_itm.Bry_file, Gfo_protocol_itm.Tid_file);
|
||||
Init_protocol_itm(gplx.xowa.parsers.lnkes.Xop_lnke_wkr.Bry_xowa_protocol, Gfo_protocol_itm.Tid_xowa);
|
||||
}
|
||||
public byte[] Relative_url_protocol_bry() {return Gfo_protocol_itm.Itm_https.Key_w_colon_bry();} // NOTE: https b/c any WMF wiki will now default to WMF; DATE:2015-07-26
|
||||
private void Init_protocols(Gfo_protocol_itm... itms) {
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_protocol_itm itm = itms[i];
|
||||
Init_protocol_itm(itm.Key_w_colon_bry(), itm.Tid());
|
||||
}
|
||||
}
|
||||
public void Init_protocol_itm(byte[] key, byte protocol_tid) {protocols.Add_bry_byte(key, protocol_tid);}
|
||||
public void Parse_site_fast(Gfo_url_site_data site_data, byte[] src, int src_bgn, int src_end) {
|
||||
int pos = src_bgn; boolean rel = false;
|
||||
if (pos + 1 < src_end && src[pos] == Byte_ascii.Slash && src[pos + 1] == Byte_ascii.Slash) { // starts with "//"
|
||||
pos += 2;
|
||||
rel = true;
|
||||
}
|
||||
if (!rel) { // search for ":"; NOTE: only search if not rel; i.e.: "//"
|
||||
int colon_pos = Bry_find_.Find_fwd(src, Byte_ascii.Colon, pos, src_end); // no colon found; EX: "//a.org/b"; "a.org/b"
|
||||
if (colon_pos != Bry_find_.Not_found) // colon found; EX: "http://" or "https://"
|
||||
pos = colon_pos + Int_.Const_dlm_len;
|
||||
if (pos < src_end && src[pos] == Byte_ascii.Slash) { // skip slash after colon
|
||||
pos += 1;
|
||||
if (pos < src_end && src[pos] == Byte_ascii.Slash) // skip 2nd slash after colon
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
int slash_pos = Bry_find_.Find_fwd(src, Byte_ascii.Slash, pos, src_end);
|
||||
if (slash_pos == Bry_find_.Not_found) // no terminating slash; EX: http://a.org
|
||||
slash_pos = src_end;
|
||||
slash_pos = Bry_.Trim_end_pos(src, slash_pos);
|
||||
site_data.Atrs_set(rel, pos, slash_pos);
|
||||
}
|
||||
public Gfo_url Parse(byte[] src) {return Parse(src, 0, src.length);}
|
||||
public Gfo_url Parse(byte[] src, int src_bgn, int src_end) {
|
||||
// protocol
|
||||
byte protocol_tid = protocols.Match_byte_or(trv, src, src_bgn, src_end, Gfo_protocol_itm.Tid_unknown);
|
||||
int pos = Bry_find_.Find_fwd_while(src, trv.Pos(), src_end, Byte_ascii.Slash); // set pos after last slash; EX: "https://A" -> position before "A"
|
||||
byte[] protocol_bry = protocol_tid == Gfo_protocol_itm.Tid_unknown
|
||||
? null
|
||||
: Make_bry(false, src, src_bgn, pos);
|
||||
|
||||
// loop chars and handle "/", "#", "?", and "%"
|
||||
boolean encoded = false;
|
||||
int src_zth = src_end - 1;
|
||||
int anch_bgn = -1, qarg_bgn = -1, seg_bgn = pos;
|
||||
for (int i = pos; i < src_end; ++i) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Slash:
|
||||
if (qarg_bgn == -1) { // ignore slash in qargs
|
||||
segs_list.Add(Make_bry(encoded, src, seg_bgn, i));
|
||||
encoded = false;
|
||||
seg_bgn = i + 1; // +1 to skip "/"
|
||||
}
|
||||
break;
|
||||
case Byte_ascii.Hash: // set qarg to first #; also, ignore rest of String; EX: A#B#C -> B#C
|
||||
if (i == src_zth) continue; // ignore # at EOS; EX: "A#"
|
||||
anch_bgn = i;
|
||||
i = src_end;
|
||||
break;
|
||||
case Byte_ascii.Question: // set qarg to last "?"; EX: A?B?C -> C
|
||||
if (i == src_zth) continue; // ignore ? at EOS; EX: "A?"
|
||||
qarg_bgn = i;
|
||||
break;
|
||||
case Byte_ascii.Percent:
|
||||
encoded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int seg_end = src_end; // set seg_end to src_end; EX: "https://site/A" -> "A"; seg_end may be overriden if "#" or "?" exists
|
||||
|
||||
// set anch
|
||||
byte[] anch = null;
|
||||
if (anch_bgn != -1) {
|
||||
seg_end = anch_bgn; // set seg_end to anch_bgn; EX: "https://site/A#B" -> "A" x> "A#B"
|
||||
anch = Make_bry(encoded, src, anch_bgn + 1, src_end); // +1 to skip "#"
|
||||
}
|
||||
|
||||
// set qargs
|
||||
Gfo_qarg_itm[] qarg_ary = Gfo_qarg_itm.Ary_empty;
|
||||
if (qarg_bgn != -1) {
|
||||
int qarg_end = anch_bgn == -1
|
||||
? src_end // # missing; set to src_end; EX: "A?B=C" -> EOS
|
||||
: anch_bgn; // # exists; set to anch_bgn; EX: "A?B=C#D" -> #
|
||||
qarg_ary = Make_qarg_ary(src, qarg_bgn, qarg_end);
|
||||
seg_end = qarg_ary.length == 0
|
||||
? src_end // set seg_end to src_end if pseudo qarg; EX: "https://site/A?B" -> "A?B" x> "A"
|
||||
: qarg_bgn; // set seg_end to qarg_bgn; EX: "https://site/A?B=C" -> "A" x> "A#B"; NOTE: overrides anch; "A?B=C#D" -> "A"
|
||||
}
|
||||
|
||||
// extract seg_end; note that there will always be a seg_end; if src ends with slash, then it will be ""; EX: "A/" -> "A", ""
|
||||
segs_list.Add(Make_bry(encoded, src, seg_bgn, seg_end));
|
||||
|
||||
// build url and return it
|
||||
return new Gfo_url(src, protocol_tid, protocol_bry, (byte[][])segs_list.To_ary_and_clear(byte[].class), qarg_ary, anch);
|
||||
}
|
||||
private Gfo_qarg_itm[] Make_qarg_ary(byte[] src, int qarg_bgn, int qarg_end) {
|
||||
// init
|
||||
int key_bgn = qarg_bgn + 1; // +1 to skip "?"
|
||||
byte[] key_bry = null;
|
||||
int val_bgn = -1;
|
||||
boolean encoded = false;
|
||||
|
||||
// loop qarg for "&", "=", "%"
|
||||
int qarg_pos = qarg_bgn;
|
||||
while (true) {
|
||||
boolean b_is_last = qarg_pos == qarg_end;
|
||||
byte b = b_is_last ? Byte_ascii.Null : src[qarg_pos];
|
||||
boolean make_qarg = false;
|
||||
switch (b) {
|
||||
case Byte_ascii.Amp: // "&" always makes qarg
|
||||
make_qarg = true;
|
||||
break;
|
||||
case Byte_ascii.Null: // "EOS" makes qarg as long as "=" seen or at least one qarg; specifically, "A?B" shouldn't make qarg
|
||||
if ( val_bgn != -1 // "=" seen; EX: "?A=B"
|
||||
|| qargs_list.Count() > 0) // at least one qarg exists; EX: "?A=B&C"
|
||||
make_qarg = true;
|
||||
break;
|
||||
case Byte_ascii.Eq:
|
||||
key_bry = Make_bry(encoded, src, key_bgn, qarg_pos);
|
||||
encoded = false;
|
||||
val_bgn = qarg_pos + 1;
|
||||
break;
|
||||
case Byte_ascii.Percent:
|
||||
encoded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// make qarg
|
||||
if (make_qarg) {
|
||||
byte[] val_bry = null;
|
||||
if (key_bry == null) // key missing; EX: "&A" -> "A,null"
|
||||
key_bry = Make_bry(encoded, src, key_bgn, qarg_pos);
|
||||
else // key exists; EX: "&A=B" -> "A,B"
|
||||
val_bry = Make_bry(encoded, src, val_bgn, qarg_pos);
|
||||
encoded = false;
|
||||
qargs_list.Add(new Gfo_qarg_itm(key_bry, val_bry));
|
||||
|
||||
// reset vars
|
||||
key_bry = null;
|
||||
key_bgn = qarg_pos + 1;
|
||||
val_bgn = -1;
|
||||
}
|
||||
if (b_is_last) break;
|
||||
++qarg_pos;
|
||||
}
|
||||
return (Gfo_qarg_itm[])qargs_list.To_ary_and_clear(Gfo_qarg_itm.class);
|
||||
}
|
||||
private byte[] Make_bry(boolean encoded, byte[] src, int bgn, int end) {
|
||||
return encoded ? Gfo_url_encoder_.Xourl.Decode(tmp_bfr, Bool_.N, src, bgn, end).To_bry_and_clear() : Bry_.Mid(src, bgn, end);
|
||||
}
|
||||
|
||||
public static final byte[] Bry_double_slash = new byte[] {Byte_ascii.Slash, Byte_ascii.Slash};
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
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.net.qargs.*;
|
||||
class Gfo_url_parser_fxt {
|
||||
private final Gfo_url_parser parser = new Gfo_url_parser();
|
||||
private Gfo_url actl;
|
||||
public Gfo_url_parser_fxt Test__protocol_tid(byte v) {Tfds.Eq_byte(v, actl.Protocol_tid(), "protocol_tid"); return this;}
|
||||
public Gfo_url_parser_fxt Test__protocol_bry(String v) {Tfds.Eq_str(v, actl.Protocol_bry(), "protocol_bry"); return this;}
|
||||
public Gfo_url_parser_fxt Test__site(String v) {Tfds.Eq_str(v, actl.Segs__get_at_1st(), "site"); return this;}
|
||||
public Gfo_url_parser_fxt Test__page(String v) {Tfds.Eq_str(v, actl.Segs__get_at_nth(), "page"); return this;}
|
||||
public Gfo_url_parser_fxt Test__anch(String v) {Tfds.Eq_str(v, actl.Anch(), "anch"); return this;}
|
||||
public Gfo_url_parser_fxt Test__segs(String... ary) {
|
||||
Tfds.Eq_str_lines(String_.Concat_lines_nl(ary), String_.Concat_lines_nl(String_.Ary(actl.Segs())), "segs");
|
||||
Tfds.Eq_int(ary.length, actl.Segs().length, "segs_len");
|
||||
return this;
|
||||
}
|
||||
public Gfo_url_parser_fxt Test__qargs(String... ary) {Tfds.Eq_str_lines(String_.To_str__as_kv_ary(ary), Qargs__To_str(actl.Qargs()), "qargs"); return this;}
|
||||
public Gfo_url_parser_fxt Exec__parse(String v) {
|
||||
this.actl = parser.Parse(Bry_.new_u8(v), 0, String_.Len(v));
|
||||
return this;
|
||||
}
|
||||
public void Test_Parse_site_fast(String raw, String expd) {
|
||||
byte[] raw_bry = Bry_.new_u8(raw);
|
||||
parser.Parse_site_fast(site_data, raw_bry, 0, raw_bry.length);
|
||||
String actl = String_.new_u8(raw_bry, site_data.Site_bgn(), site_data.Site_end());
|
||||
Tfds.Eq(expd, actl);
|
||||
} private final Gfo_url_site_data site_data = new Gfo_url_site_data();
|
||||
private static String Qargs__To_str(Gfo_qarg_itm[] ary) {
|
||||
int len = ary.length;
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfo_qarg_itm itm = ary[i];
|
||||
bfr.Add(itm.Key_bry()).Add_byte_eq();
|
||||
if (itm.Val_bry() != null)
|
||||
bfr.Add(itm.Val_bry());
|
||||
bfr.Add_byte_nl();
|
||||
}
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
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 Gfo_url_parser_tst {
|
||||
private final Gfo_url_parser_fxt tstr = new Gfo_url_parser_fxt();
|
||||
@Test public void Protocol__relative() {
|
||||
tstr.Exec__parse("//en.wikipedia.org").Test__protocol_tid(Gfo_protocol_itm.Tid_relative_1).Test__protocol_bry("//").Test__site("en.wikipedia.org");
|
||||
}
|
||||
@Test public void Protocol__none() {
|
||||
tstr.Exec__parse("en.wikipedia.org/wiki/A").Test__protocol_tid(Gfo_protocol_itm.Tid_unknown).Test__segs("en.wikipedia.org", "wiki", "A");
|
||||
}
|
||||
@Test public void Site__parts__3() {
|
||||
tstr.Exec__parse("https://en.wikipedia.org").Test__protocol_tid(Gfo_protocol_itm.Tid_https).Test__protocol_bry("https://").Test__segs("en.wikipedia.org");
|
||||
}
|
||||
@Test public void Site__parts__2() {
|
||||
tstr.Exec__parse("https://wikipedia.org").Test__protocol_tid(Gfo_protocol_itm.Tid_https).Test__segs("wikipedia.org");
|
||||
}
|
||||
@Test public void Site__parts__1() {
|
||||
tstr.Exec__parse("https://wikipedia").Test__protocol_tid(Gfo_protocol_itm.Tid_https).Test__segs("wikipedia");
|
||||
}
|
||||
@Test public void Site__slash__none() {
|
||||
tstr.Exec__parse("https:site").Test__protocol_tid(Gfo_protocol_itm.Tid_https).Test__site("site");
|
||||
}
|
||||
@Test public void Site__slash__eos() {
|
||||
tstr.Exec__parse("https://en.wikipedia.org/").Test__protocol_tid(Gfo_protocol_itm.Tid_https).Test__site("en.wikipedia.org");
|
||||
}
|
||||
@Test public void Paths__1() {
|
||||
tstr.Exec__parse("https://site/A").Test__segs("site", "A");
|
||||
}
|
||||
@Test public void Paths__2() {
|
||||
tstr.Exec__parse("https://site/wiki/A").Test__segs("site", "wiki", "A");
|
||||
}
|
||||
@Test public void Paths__n() {
|
||||
tstr.Exec__parse("https://site/wiki/A/B/C/D").Test__segs("site", "wiki", "A", "B", "C", "D");
|
||||
}
|
||||
@Test public void Qargs__1() {
|
||||
tstr.Exec__parse("https://site/A?B=C").Test__page("A").Test__qargs("B", "C");
|
||||
}
|
||||
@Test public void Qargs__2() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D=E").Test__page("A").Test__qargs("B", "C", "D", "E");
|
||||
}
|
||||
@Test public void Qargs__3() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D=E&F=G").Test__page("A").Test__qargs("B", "C", "D", "E", "F", "G");
|
||||
}
|
||||
@Test public void Qargs__ques__dupe__ques() {
|
||||
tstr.Exec__parse("https://site/A?B?Y=Z").Test__page("A?B").Test__qargs("Y", "Z");
|
||||
}
|
||||
@Test public void Qargs__ques__dupe__amp() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D?Y=Z").Test__page("A?B=C&D").Test__qargs("Y", "Z");
|
||||
}
|
||||
@Test public void Qargs__ques__dupe__eq() {
|
||||
tstr.Exec__parse("https://site/A?B=C?Y=Z").Test__page("A?B=C").Test__qargs("Y", "Z");
|
||||
}
|
||||
@Test public void Qargs__amp__dupe__ques() {
|
||||
tstr.Exec__parse("https://site/A?B&Y=Z").Test__page("A").Test__qargs("B", null, "Y", "Z");
|
||||
}
|
||||
@Test public void Qargs__amp__dupe__amp() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D&Y=Z").Test__page("A").Test__qargs("B", "C", "D", null, "Y", "Z");
|
||||
}
|
||||
@Test public void Qargs__missing_val__0() {
|
||||
tstr.Exec__parse("https://site/A?").Test__page("A?").Test__qargs();
|
||||
}
|
||||
@Test public void Qargs__missing_val__2() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D&F=G").Test__page("A").Test__qargs("B", "C", "D", null, "F", "G");
|
||||
}
|
||||
@Test public void Qargs__missing_val__n() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D=E&F").Test__page("A").Test__qargs("B", "C", "D", "E", "F", null);
|
||||
}
|
||||
@Test public void Qargs__site_less__missing__0() {
|
||||
tstr.Exec__parse("A?B").Test__segs("A?B").Test__qargs();
|
||||
}
|
||||
@Test public void Qargs__site_less() {
|
||||
tstr.Exec__parse("A?B=C&D=E").Test__site("A").Test__qargs("B", "C", "D", "E");
|
||||
}
|
||||
@Test public void Anch__basic() {
|
||||
tstr.Exec__parse("https://site/A#B").Test__page("A").Test__anch("B");
|
||||
}
|
||||
@Test public void Anch__repeat__2() {
|
||||
tstr.Exec__parse("https://site/A#B#C").Test__page("A").Test__anch("B#C");
|
||||
}
|
||||
@Test public void Anch__repeat__3() {
|
||||
tstr.Exec__parse("https://site/A#B#C#D").Test__page("A").Test__anch("B#C#D");
|
||||
}
|
||||
@Test public void Anch__missing() {
|
||||
tstr.Exec__parse("https://site/A#").Test__page("A#").Test__anch(null);
|
||||
}
|
||||
@Test public void Anch__missing__eos() {
|
||||
tstr.Exec__parse("https://site/A#B#").Test__page("A").Test__anch("B#");
|
||||
}
|
||||
@Test public void Anch__qargs__basic() {
|
||||
tstr.Exec__parse("https://site/A?B=C&D=E#F").Test__page("A").Test__qargs("B", "C", "D", "E").Test__anch("F");
|
||||
}
|
||||
@Test public void Anch__site_less() {
|
||||
tstr.Exec__parse("A#B").Test__site("A").Test__anch("B");
|
||||
}
|
||||
@Test public void Encode__page() {
|
||||
tstr.Exec__parse("http://site/A%27s").Test__site("site").Test__page("A's");
|
||||
}
|
||||
@Test public void Protocol_less__qargs() {
|
||||
tstr.Exec__parse("Special:Search/Earth?fulltext=yes").Test__segs("Special:Search", "Earth").Test__page("Earth").Test__qargs("fulltext", "yes");
|
||||
}
|
||||
@Test public void Parse_site_fast() {
|
||||
tstr.Test_Parse_site_fast("http://a.org/B" , "a.org");
|
||||
tstr.Test_Parse_site_fast("http://a.org" , "a.org");
|
||||
tstr.Test_Parse_site_fast("//a.org/B" , "a.org");
|
||||
tstr.Test_Parse_site_fast("//a.org/B:C" , "a.org");
|
||||
}
|
||||
// DELETED: logic isn't right; anch is first # not last; EX: https://en.wikipedia.org/w/index.php?title=Category:2001_albums&pagefrom=Beautiful+#View#mw-pages; DATE:2016-10-10
|
||||
// @Test public void Anch__qargs__repeat() {
|
||||
// tstr.Exec__parse("https://site/A?B=C#&D=E#F").Test__page("A").Test__qargs("B", "C#", "D", "E").Test__anch("F");
|
||||
// }
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
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 Gfo_url_site_data {
|
||||
public boolean Rel() {return rel;} private boolean rel;
|
||||
public int Site_bgn() {return site_bgn;} private int site_bgn;
|
||||
public int Site_end() {return site_end;} private int site_end;
|
||||
public void Atrs_set(boolean rel, int bgn, int end) {this.rel = rel; this.site_bgn = bgn; this.site_end = end;}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
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();
|
||||
int Read_char_ary(char[] ary, int bgn, int len);
|
||||
void Rls();
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
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 int Read_char_ary(char[] ary, int bgn, int len) {throw Err_.new_unimplemented();}
|
||||
public void Rls() {}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
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 Err_.new_exc(e, "net", "Read_line failed");}
|
||||
}
|
||||
public int Read_char_ary(char[] ary, int bgn, int len) {
|
||||
try {return br.read(ary, bgn, len);}
|
||||
catch (IOException e) {throw Err_.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 Err_.new_exc(e, "net", "Rls failed");}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
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.ios.*; import gplx.core.ios.streams.*;
|
||||
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();
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
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();}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
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.ios.*; import gplx.core.ios.streams.*;
|
||||
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 Err_.new_exc(e, "net", "Write_bry failed");}
|
||||
}
|
||||
public void Write_str(String s) {
|
||||
try {stream.writeBytes(s);}
|
||||
catch (Exception e) {throw Err_.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 Err_.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 Err_.new_exc(e, "net", "Rls failed");}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
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, byte[] origin
|
||||
, 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.origin = origin;
|
||||
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 byte[] Origin() {return origin;} private final byte[] origin;
|
||||
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, boolean line) {
|
||||
bfr .Add_kv_dlm(line, "type" , type == Type_get ? "GET" : "POST")
|
||||
.Add_kv_dlm(line, "url" , url)
|
||||
.Add_kv_dlm(line, "protocol" , protocol)
|
||||
.Add_kv_dlm(line, "host" , host)
|
||||
.Add_kv_dlm(line, "user_agent" , user_agent)
|
||||
.Add_kv_dlm(line, "accept" , accept)
|
||||
.Add_kv_dlm(line, "accept_encoding" , accept_encoding)
|
||||
.Add_kv_dlm(line, "dnt" , dnt)
|
||||
.Add_kv_dlm(line, "x_requested_with" , x_requested_with)
|
||||
.Add_kv_dlm(line, "cookie" , cookie)
|
||||
.Add_kv_dlm(line, "referer" , referer)
|
||||
.Add_kv_dlm(line, "content_length" , content_length)
|
||||
.Add_kv_dlm(line, "content_type" , content_type)
|
||||
.Add_kv_dlm(line, "content_type_boundary" , content_type_boundary)
|
||||
.Add_kv_dlm(line, "connection" , connection)
|
||||
.Add_kv_dlm(line, "pragma" , pragma)
|
||||
.Add_kv_dlm(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_dlm(line, String_.new_u8(itm.Key()), itm.Val());
|
||||
}
|
||||
}
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
public static final int Type_get = 1, Type_post = 2;
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
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, origin;
|
||||
private Http_post_data_hash post_data_hash;
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(255); private final Btrie_rv trv = new Btrie_rv();
|
||||
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 = this.origin = null;
|
||||
this.post_data_hash = null;
|
||||
}
|
||||
public Http_request_itm Parse(Http_client_rdr rdr) {
|
||||
synchronized (tmp_bfr) {
|
||||
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 Err_.new_wo_type("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 Err_.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 sends POST request
|
||||
}
|
||||
Object o = trie.Match_at(trv, 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_find_.Find_fwd_while_ws(line, trv.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_.To_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;
|
||||
case Tid_origin: this.origin = Bry_.Mid(line, val_bgn, line_len); break;
|
||||
case Tid_accept_charset: break;
|
||||
default: throw Err_.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_find_.Find_bwd(line, Byte_ascii.Space, line_len); if (url_end == Bry_find_.Not_found) throw Err_.new_wo_type("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 Err_.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
|
||||
// handle wolfram and other clients; DATE:2015-08-03
|
||||
int boundary_bgn = Bry_find_.Find_fwd(line, Tkn_boundary, val_bgn, line_len); if (boundary_bgn == Bry_find_.Not_found) return; // PURPOSE: ignore content-type for GET calls like by Mathematica server; DATE:2015-08-04 // throw Err_.new_wo_type("invalid content_type", "line", line, "request", To_str());
|
||||
int content_type_end = Bry_find_.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, origin, 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 Err_.new_wo_type("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.To_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 Err_.new_wo_type("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 Err_.new_wo_type("http.request.parser; invalid form_data line", "tkn", tkn, "line", src, "request", To_str());
|
||||
int rv = src_pos += tkn_len;
|
||||
return Bry_find_.Find_fwd_while_ws(src, rv, src_len);
|
||||
}
|
||||
private String To_str() {return Make_request_itm().To_str(tmp_bfr, Bool_.N);}
|
||||
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
|
||||
, Tid_origin = 17, Tid_accept_charset = 18;
|
||||
private static final Btrie_slim_mgr trie = Btrie_slim_mgr.ci_a7()
|
||||
.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("Accept-Charset:" , Tid_accept_charset)
|
||||
.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)
|
||||
.Add_str_int("Origin:" , Tid_origin)
|
||||
;
|
||||
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=")
|
||||
;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user