mirror of https://github.com/gnosygnu/xowa
parent
5fe27b5b3b
commit
fa70c05354
@ -0,0 +1,126 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import gplx.core.brys.*;
|
||||
public class Bry_split_ {
|
||||
private static final Object thread_lock = new Object();
|
||||
public static byte[][] Split(byte[] src, byte dlm) {return Split(src, dlm, false);}
|
||||
public static byte[][] Split(byte[] src, byte dlm, boolean trim) {
|
||||
synchronized (thread_lock) {
|
||||
Bry_split_wkr__to_ary wkr = Bry_split_wkr__to_ary.I;
|
||||
Split(src, dlm, trim, wkr);
|
||||
return wkr.To_ary();
|
||||
}
|
||||
}
|
||||
public static void Split(byte[] src, byte dlm, boolean trim, Bry_split_wkr wkr) {
|
||||
if (src == null) return;
|
||||
int src_len = src.length, pos = 0; if (src_len == 0) return;
|
||||
int itm_bgn = -1, itm_end = -1;
|
||||
while (true) {
|
||||
boolean pos_is_last = pos == src_len;
|
||||
byte b = pos_is_last ? dlm : src[pos];
|
||||
int nxt_pos = pos + 1;
|
||||
boolean process = true;
|
||||
switch (b) {
|
||||
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: // ignore ws; assumes that flags have no ws (they are single char) and vnts have no ws (EX: zh-hans)
|
||||
if (trim && b != dlm) process = false; // b != dlm handles cases where ws is dlm, but trim is enabled; EX: " a \n b" -> "a", "b"
|
||||
break;
|
||||
}
|
||||
if (process) {
|
||||
if (b == dlm) {
|
||||
boolean reset = true;
|
||||
if (itm_bgn == -1) {
|
||||
if (pos_is_last) {} // skip dlm at bgn / end; EX: "a,"
|
||||
else {wkr.Split(src, itm_bgn, itm_end);} // else, process "empty" dlm; EX: ",a"
|
||||
}
|
||||
else {
|
||||
int rv = wkr.Split(src, itm_bgn, itm_end);
|
||||
switch (rv) {
|
||||
case Rv__ok: break;
|
||||
case Rv__extend: reset = false; break;
|
||||
case Rv__cancel: pos_is_last = true; break;
|
||||
default: throw Err_.new_unhandled(rv);
|
||||
}
|
||||
}
|
||||
if (reset) itm_bgn = itm_end = -1;
|
||||
}
|
||||
else {
|
||||
if (itm_bgn == -1) itm_bgn = pos;
|
||||
itm_end = nxt_pos;
|
||||
}
|
||||
}
|
||||
if (pos_is_last) break;
|
||||
pos = nxt_pos;
|
||||
}
|
||||
}
|
||||
public static byte[][] Split(byte[] src, byte[] dlm) {
|
||||
if (Bry_.Len_eq_0(src)) return Bry_.Ary_empty;
|
||||
int cur_pos = 0, src_len = src.length, dlm_len = dlm.length;
|
||||
List_adp rv = List_adp_.new_();
|
||||
while (true) {
|
||||
int find_pos = Bry_find_.Find_fwd(src, dlm, cur_pos);
|
||||
if (find_pos == Bry_.NotFound) {
|
||||
if (cur_pos == src_len) break; // dlm is last sequence in src; do not create empty itm
|
||||
find_pos = src_len;
|
||||
}
|
||||
rv.Add(Bry_.Mid(src, cur_pos, find_pos));
|
||||
if (find_pos == src_len) break;
|
||||
cur_pos = find_pos + dlm_len;
|
||||
}
|
||||
return (byte[][])rv.To_ary(byte[].class);
|
||||
}
|
||||
public static byte[][] Split_lines(byte[] src) {
|
||||
if (Bry_.Len_eq_0(src)) return Bry_.Ary_empty;
|
||||
int src_len = src.length, src_pos = 0, fld_bgn = 0;
|
||||
List_adp rv = List_adp_.new_();
|
||||
while (true) {
|
||||
boolean last = src_pos == src_len;
|
||||
byte b = last ? Byte_ascii.Nl : src[src_pos];
|
||||
int nxt_bgn = src_pos + 1;
|
||||
switch (b) {
|
||||
case Byte_ascii.Cr:
|
||||
case Byte_ascii.Nl:
|
||||
if ( b == Byte_ascii.Cr // check for crlf
|
||||
&& nxt_bgn < src_len && src[nxt_bgn] == Byte_ascii.Nl) {
|
||||
++nxt_bgn;
|
||||
}
|
||||
if (last && (src_pos - fld_bgn == 0)) {} // ignore trailing itms
|
||||
else
|
||||
rv.Add(Bry_.Mid(src, fld_bgn, src_pos));
|
||||
fld_bgn = nxt_bgn;
|
||||
break;
|
||||
}
|
||||
if (last) break;
|
||||
src_pos = nxt_bgn;
|
||||
}
|
||||
return (byte[][])rv.To_ary(byte[].class);
|
||||
}
|
||||
public static final int Rv__ok = 0, Rv__extend = 1, Rv__cancel = 2;
|
||||
}
|
||||
class Bry_split_wkr__to_ary implements gplx.core.brys.Bry_split_wkr {
|
||||
private final List_adp list = List_adp_.new_();
|
||||
public int Split(byte[] src, int itm_bgn, int itm_end) {
|
||||
byte[] bry = itm_end == itm_bgn ? Bry_.Empty : Bry_.Mid(src, itm_bgn, itm_end);
|
||||
list.Add(bry);
|
||||
return Bry_split_.Rv__ok;
|
||||
}
|
||||
public byte[][] To_ary() {
|
||||
return (byte[][])list.To_ary_and_clear(byte[].class);
|
||||
}
|
||||
public static final Bry_split_wkr__to_ary I = new Bry_split_wkr__to_ary(); Bry_split_wkr__to_ary() {}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx;
|
||||
import org.junit.*;
|
||||
public class Bry_split__tst {
|
||||
private final Bry_split__fxt fxt = new Bry_split__fxt();
|
||||
@Test public void Split() {
|
||||
fxt.Test_Split("a" , Byte_ascii.Pipe, Bool_.N, "a"); // no trim
|
||||
fxt.Test_Split("a|" , Byte_ascii.Pipe, Bool_.N, "a");
|
||||
fxt.Test_Split("|a" , Byte_ascii.Pipe, Bool_.N, "", "a");
|
||||
fxt.Test_Split("|" , Byte_ascii.Pipe, Bool_.N, "");
|
||||
fxt.Test_Split("" , Byte_ascii.Pipe, Bool_.N);
|
||||
fxt.Test_Split("a|b|c" , Byte_ascii.Pipe, Bool_.N, "a", "b", "c");
|
||||
fxt.Test_Split(" a " , Byte_ascii.Pipe, Bool_.Y, "a"); // trim
|
||||
fxt.Test_Split(" a |" , Byte_ascii.Pipe, Bool_.Y, "a");
|
||||
fxt.Test_Split("| a " , Byte_ascii.Pipe, Bool_.Y, "", "a");
|
||||
fxt.Test_Split(" | " , Byte_ascii.Pipe, Bool_.Y, "");
|
||||
fxt.Test_Split(" " , Byte_ascii.Pipe, Bool_.Y);
|
||||
fxt.Test_Split(" a | b | c " , Byte_ascii.Pipe, Bool_.Y, "a", "b", "c");
|
||||
fxt.Test_Split(" a b | c d " , Byte_ascii.Pipe, Bool_.Y, "a b", "c d");
|
||||
fxt.Test_Split(" a \n b " , Byte_ascii.Nl , Bool_.N, " a ", " b "); // ws as dlm
|
||||
fxt.Test_Split(" a \n b " , Byte_ascii.Nl , Bool_.Y, "a", "b"); // ws as dlm; trim
|
||||
}
|
||||
}
|
||||
class Bry_split__fxt {
|
||||
public void Test_Split(String raw_str, byte dlm, boolean trim, String... expd) {
|
||||
byte[][] actl_ary = Bry_split_.Split(Bry_.new_a7(raw_str), dlm, trim);
|
||||
Tfds.Eq_ary_str(expd, String_.Ary(actl_ary));
|
||||
}
|
||||
}
|
@ -1,18 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="src_060_utl"/>
|
||||
<classpathentry kind="src" path="src_120_wiki"/>
|
||||
<classpathentry kind="src" path="src_140_lang"/>
|
||||
<classpathentry kind="src" path="src_200_bldr"/>
|
||||
<classpathentry kind="src" path="src_210_bldr_core"/>
|
||||
<classpathentry kind="src" path="xtn"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/100_core"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/150_gfui"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/100_core"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/140_dbs"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/150_gfui"/>
|
||||
<classpathentry kind="lib" path="lib/luaj_xowa.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jtidy_xowa.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.primitives; import gplx.*; import gplx.core.*;
|
||||
public class Int_pool {
|
||||
private final List_adp available_list = List_adp_.new_(); private int available_len;
|
||||
private int uid_max = -1;
|
||||
public void Clear() {
|
||||
available_list.Clear();
|
||||
available_len = 0;
|
||||
uid_max = -1;
|
||||
}
|
||||
public int Get_next() {
|
||||
synchronized (available_list) {
|
||||
if (available_len == 0)
|
||||
return ++uid_max;
|
||||
else {
|
||||
Int_obj_val val = (Int_obj_val)List_adp_.Pop_last(available_list);
|
||||
--available_len;
|
||||
return val.Val();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Del(int v) {
|
||||
if (v > uid_max) throw Err_.new_("core", "value is greater than range", "value", v, "max", uid_max);
|
||||
synchronized (available_list) {
|
||||
if (available_len == 0 && v == uid_max) {
|
||||
--this.uid_max;
|
||||
return;
|
||||
}
|
||||
if (available_len == uid_max) {
|
||||
available_list.Sort();
|
||||
for (int i = 0; i < available_len; ++i) {
|
||||
Int_obj_val itm = (Int_obj_val)available_list.Get_at(i);
|
||||
if (i != itm.Val()) throw Err_.new_("core", "available_list out of order", "contents", available_list.To_str());
|
||||
}
|
||||
this.Clear();
|
||||
}
|
||||
else {
|
||||
available_list.Add(Int_obj_val.new_(v));
|
||||
++available_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.primitives; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class Int_pool_tst {
|
||||
private final Int_pool_tstr tstr = new Int_pool_tstr();
|
||||
@Before public void init() {tstr.Clear();}
|
||||
@Test public void Get__one() {
|
||||
tstr.Test_get(0);
|
||||
}
|
||||
@Test public void Get__many() {
|
||||
tstr.Test_get(0);
|
||||
tstr.Test_get(1);
|
||||
tstr.Test_get(2);
|
||||
}
|
||||
@Test public void Del__one() {
|
||||
tstr.Test_get(0);
|
||||
tstr.Exec_del(0);
|
||||
tstr.Test_get(0);
|
||||
}
|
||||
@Test public void Del__sequential() {
|
||||
tstr.Test_get(0);
|
||||
tstr.Test_get(1);
|
||||
tstr.Test_get(2);
|
||||
tstr.Exec_del(2).Test_get(2);
|
||||
tstr.Exec_del(2);
|
||||
tstr.Exec_del(1);
|
||||
tstr.Exec_del(0).Test_get(0);
|
||||
}
|
||||
@Test public void Del__out_of_order() {
|
||||
tstr.Test_get(0);
|
||||
tstr.Test_get(1);
|
||||
tstr.Test_get(2);
|
||||
tstr.Exec_del(0).Test_get(0);
|
||||
tstr.Exec_del(0);
|
||||
tstr.Exec_del(1);
|
||||
tstr.Exec_del(2);
|
||||
tstr.Test_get(0);
|
||||
}
|
||||
}
|
||||
class Int_pool_tstr {
|
||||
private final Int_pool pool = new Int_pool();
|
||||
public void Clear() {pool.Clear();}
|
||||
public Int_pool_tstr Test_get(int expd) {
|
||||
Tfds.Eq(expd, pool.Get_next());
|
||||
return this;
|
||||
}
|
||||
public Int_pool_tstr Exec_del(int val) {
|
||||
pool.Del(val);
|
||||
return this;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue