mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v1.6.5.1
This commit is contained in:
43
400_xowa/.classpath
Normal file
43
400_xowa/.classpath
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="src_020_byte"/>
|
||||
<classpathentry kind="src" path="src_040_io"/>
|
||||
<classpathentry kind="src" path="src_060_utl"/>
|
||||
<classpathentry kind="src" path="src_100_app"/>
|
||||
<classpathentry kind="src" path="src_120_wiki"/>
|
||||
<classpathentry kind="src" path="src_121_wiki_data"/>
|
||||
<classpathentry kind="src" path="src_140_lang"/>
|
||||
<classpathentry kind="src" path="src_160_file"/>
|
||||
<classpathentry kind="src" path="src_161_meta"/>
|
||||
<classpathentry kind="src" path="src_162_xfer"/>
|
||||
<classpathentry kind="src" path="src_200_bldr"/>
|
||||
<classpathentry kind="src" path="src_210_bldr_core"/>
|
||||
<classpathentry kind="src" path="src_220_bldr_file"/>
|
||||
<classpathentry kind="src" path="src_240_install"/>
|
||||
<classpathentry kind="src" path="src_300_html"/>
|
||||
<classpathentry kind="src" path="src_310_url"/>
|
||||
<classpathentry kind="src" path="src_400_parser"/>
|
||||
<classpathentry kind="src" path="src_405_tkn"/>
|
||||
<classpathentry kind="src" path="src_409_tkn_misc"/>
|
||||
<classpathentry kind="src" path="src_420_apos"/>
|
||||
<classpathentry kind="src" path="src_430_lnke"/>
|
||||
<classpathentry kind="src" path="src_440_lnki"/>
|
||||
<classpathentry kind="src" path="src_450_hdr"/>
|
||||
<classpathentry kind="src" path="src_460_para"/>
|
||||
<classpathentry kind="src" path="src_470_list"/>
|
||||
<classpathentry kind="src" path="src_480_tblw"/>
|
||||
<classpathentry kind="src" path="src_490_xnde"/>
|
||||
<classpathentry kind="src" path="src_500_tmpl"/>
|
||||
<classpathentry kind="src" path="src_510_pf_core"/>
|
||||
<classpathentry kind="src" path="src_530_pf_str"/>
|
||||
<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.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/140_dbs"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="lib" path="lib/luaj_xowa.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jtidy_xowa.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
400_xowa/.project
Normal file
17
400_xowa/.project
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>400_xowa</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
BIN
400_xowa/lib/luaj_xowa.jar
Normal file
BIN
400_xowa/lib/luaj_xowa.jar
Normal file
Binary file not shown.
48
400_xowa/src/gplx/cache/Gfo_cache_mgr_base.java
vendored
Normal file
48
400_xowa/src/gplx/cache/Gfo_cache_mgr_base.java
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.cache; import gplx.*;
|
||||
public class Gfo_cache_mgr_base {
|
||||
private OrderedHash hash = OrderedHash_.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.Fetch(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.SortBy(Gfo_cache_itm_comparer.Touched_asc);
|
||||
int del_len = hash.Count() - compress_to;
|
||||
ListAdp del_list = ListAdp_.new_();
|
||||
for (int i = 0; i < del_len; i++) {
|
||||
Gfo_cache_itm itm = (Gfo_cache_itm)hash.FetchAt(i);
|
||||
del_list.Add(itm);
|
||||
}
|
||||
for (int i = 0; i < del_len; i++) {
|
||||
Gfo_cache_itm itm = (Gfo_cache_itm)del_list.FetchAt(i);
|
||||
hash.Del(itm.Key());
|
||||
}
|
||||
}
|
||||
}
|
||||
38
400_xowa/src/gplx/cache/Gfo_cache_mgr_bry.java
vendored
Normal file
38
400_xowa/src/gplx/cache/Gfo_cache_mgr_bry.java
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.cache; import gplx.*;
|
||||
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 = Env_.TickCount(); return this;}
|
||||
}
|
||||
class Gfo_cache_itm_comparer implements gplx.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();
|
||||
}
|
||||
40
400_xowa/src/gplx/core/bytes/Bry_bldr.java
Normal file
40
400_xowa/src/gplx/core/bytes/Bry_bldr.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.bytes; 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.NewLine, Byte_ascii.CarriageReturn);}
|
||||
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;
|
||||
}
|
||||
}
|
||||
54
400_xowa/src/gplx/core/enums/Gfo_enum_grp.java
Normal file
54
400_xowa/src/gplx/core/enums/Gfo_enum_grp.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.enums; import gplx.*; import gplx.core.*;
|
||||
class Gfo_enum_grp {
|
||||
// private OrderedHash itms = OrderedHash_.new_();
|
||||
public Gfo_enum_grp(UuidAdp 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 UuidAdp Uid() {return uid;} private UuidAdp 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(UuidAdp 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 UuidAdp Uid() {return uid;} private UuidAdp uid;
|
||||
public String Key() {return key;} private String key;
|
||||
public int Id() {return id;} private int id;
|
||||
public String Name() {return name;} private String name;
|
||||
public int Sort() {return sort;} private int sort;
|
||||
public String Xtn() {return xtn;} private String xtn;
|
||||
}
|
||||
/*
|
||||
enum_grps
|
||||
grp_guid,grp_key,grp_int,grp_name,grp_sort,grp_xtn
|
||||
0-1-2-3,xowa.wiki,0,wiki,,
|
||||
|
||||
enum_itms
|
||||
grp_int,itm_guid,itm_key,itm_int,itm_name,itm_sort,itm_xtn
|
||||
1,0-1-2-3,0,en.wikipedia.org,0,enwiki,0,''
|
||||
|
||||
class Gfo_enum_mgr {
|
||||
// public Gui
|
||||
}
|
||||
*/
|
||||
23
400_xowa/src/gplx/core/ints/Int_ary_bldr.java
Normal file
23
400_xowa/src/gplx/core/ints/Int_ary_bldr.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.ints; import gplx.*; import gplx.core.*;
|
||||
public class Int_ary_bldr {
|
||||
public Int_ary_bldr(int len) {ary = new int[len];}
|
||||
public Int_ary_bldr Set(int idx, int val) {ary[idx] = val; return this;}
|
||||
public int[] Xto_int_ary() {return ary;} private int[] ary;
|
||||
}
|
||||
52
400_xowa/src/gplx/fsdb/Binary_search_.java
Normal file
52
400_xowa/src/gplx/fsdb/Binary_search_.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Binary_search_ {
|
||||
public static int Search(CompareAble[] ary, int ary_len, CompareAble val) {
|
||||
if (ary_len == 1) return 0;
|
||||
int interval = ary_len / 2;
|
||||
int pos = interval - ListAdp_.Base1;
|
||||
int pos_last = ary_len - 1;
|
||||
int pos_prv = -1;
|
||||
int loop_count = 0;
|
||||
while (loop_count++ < 32) { // 32 bit integer
|
||||
CompareAble lo = ary[pos];
|
||||
CompareAble hi = pos + 1 == ary_len ? null : ary[pos + 1];
|
||||
int adj = 0;
|
||||
int lo_comp = val.compareTo(lo);
|
||||
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
|
||||
adj = -1;
|
||||
else {
|
||||
if (hi == null) return pos; // hi is null when at last slot in ary
|
||||
int hi_comp = val.compareTo(hi);
|
||||
if (hi_comp == CompareAble_.More) // val is > hi; search slots above
|
||||
adj = 1;
|
||||
else
|
||||
return pos; // val is > lo and < hi; return slot
|
||||
}
|
||||
interval /= 2;
|
||||
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
|
||||
pos += (interval * adj);
|
||||
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
|
||||
if (pos < 0) pos = 0;
|
||||
else if (pos > pos_last) pos = pos_last;
|
||||
pos_prv = pos;
|
||||
}
|
||||
return Int_.MinValue; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
|
||||
}
|
||||
}
|
||||
47
400_xowa/src/gplx/fsdb/Binary_search__tst.java
Normal file
47
400_xowa/src/gplx/fsdb/Binary_search__tst.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Binary_search__tst {
|
||||
private Binary_search__fxt fxt = new Binary_search__fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Init_ary("", "e", "j", "o", "t", "y");
|
||||
fxt.Test_binary_search("a", 0);
|
||||
fxt.Test_binary_search("f", 1);
|
||||
fxt.Test_binary_search("k", 2);
|
||||
fxt.Test_binary_search("p", 3);
|
||||
fxt.Test_binary_search("u", 4);
|
||||
fxt.Test_binary_search("z", 5);
|
||||
}
|
||||
@Test public void One() {
|
||||
fxt.Init_ary("");
|
||||
fxt.Test_binary_search("a", 0);
|
||||
}
|
||||
}
|
||||
class Binary_search__fxt {
|
||||
public void Init_ary(String... v) {
|
||||
int ary_len = v.length;
|
||||
ary = new String_obj_val[ary_len];
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i] = String_obj_val.new_(v[i]);
|
||||
} private String_obj_val[] ary;
|
||||
public void Test_binary_search(String val, int expd) {
|
||||
int actl = Binary_search_.Search(ary, ary.length, String_obj_val.new_(val));
|
||||
Tfds.Eq(expd, actl, val);
|
||||
}
|
||||
}
|
||||
131
400_xowa/src/gplx/fsdb/Fsdb_bin_tbl.java
Normal file
131
400_xowa/src/gplx/fsdb/Fsdb_bin_tbl.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*; import gplx.ios.*;
|
||||
public class Fsdb_bin_tbl {
|
||||
public static void Create_table(Db_provider p) {Sqlite_engine_.Tbl_create(p, Tbl_name, Tbl_sql);}
|
||||
public static Db_stmt Insert_stmt(Db_provider p) {return Db_stmt_.new_insert_(p, Tbl_name, Fld_bin_owner_id, Fld_bin_owner_tid, Fld_bin_part_id, Fld_bin_data_url, Fld_bin_data);}
|
||||
public static void Insert_rdr(Db_provider p, int id, byte tid, long bin_len, Io_stream_rdr bin_rdr) {
|
||||
Db_stmt stmt = Insert_stmt(p);
|
||||
try {Insert_rdr(stmt, id, tid, bin_len, bin_rdr);}
|
||||
finally {stmt.Rls();}
|
||||
}
|
||||
public static long Insert_rdr(Db_stmt stmt, int id, byte tid, long bin_len, Io_stream_rdr bin_rdr) {
|
||||
long rv = bin_len;
|
||||
stmt.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_byte_(tid)
|
||||
.Val_int_(Null_part_id)
|
||||
.Val_str_(Null_data_url)
|
||||
;
|
||||
if (Sqlite_engine_.Supports_read_binary_stream)
|
||||
stmt.Val_rdr_(bin_rdr, bin_len);
|
||||
else {
|
||||
byte[] bin_ary = Io_stream_rdr_.Load_all_as_bry(Bry_bfr.new_(), bin_rdr);
|
||||
stmt.Val_bry_(bin_ary);
|
||||
rv = bin_ary.length;
|
||||
}
|
||||
stmt.Exec_insert();
|
||||
return rv;
|
||||
}
|
||||
public static void Delete(Db_provider p, int id) {
|
||||
Db_stmt stmt = Delete_stmt(p);
|
||||
try {Delete(stmt, id);}
|
||||
finally {stmt.Rls();}
|
||||
}
|
||||
private static Db_stmt Delete_stmt(Db_provider p) {return Db_stmt_.new_delete_(p, Tbl_name, Fld_bin_owner_id);}
|
||||
private static void Delete(Db_stmt stmt, int id) {
|
||||
stmt.Clear()
|
||||
.Val_int_(id)
|
||||
.Exec_delete();
|
||||
}
|
||||
public static Io_stream_rdr Select_as_rdr(Db_provider p, int owner) {
|
||||
Db_qry qry = Db_qry_.select_().From_(Tbl_name).Cols_(Fld_bin_data).Where_(Db_crt_.eq_(Fld_bin_owner_id, owner));
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = p.Exec_qry_as_rdr(qry);
|
||||
if (rdr.MoveNextPeer()) {
|
||||
if (Sqlite_engine_.Supports_read_binary_stream)
|
||||
return rdr.ReadRdr(Fld_bin_data);
|
||||
else
|
||||
return gplx.ios.Io_stream_rdr_.mem_(Read_bin_data(rdr));
|
||||
}
|
||||
else
|
||||
return gplx.ios.Io_stream_rdr_.Null;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
public static boolean Select_to_url(Db_provider p, int owner, Io_url url, byte[] bin_bfr, int bin_flush_when) {
|
||||
Db_qry qry = Db_qry_.select_().From_(Tbl_name).Cols_(Fld_bin_data).Where_(Db_crt_.eq_(Fld_bin_owner_id, owner));
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = p.Exec_qry_as_rdr(qry);
|
||||
if (rdr.MoveNextPeer()) {
|
||||
if (Sqlite_engine_.Supports_read_binary_stream)
|
||||
return Select_to_fsys__stream(rdr, url, bin_bfr, bin_flush_when);
|
||||
else {
|
||||
byte[] bry = Read_bin_data(rdr);
|
||||
Io_mgr._.SaveFilBry(url, bry);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
public static boolean Select_to_fsys__stream(DataRdr rdr, Io_url url, byte[] bin_bfr, int bin_flush_when) {
|
||||
Io_stream_rdr db_stream = Io_stream_rdr_.Null;
|
||||
IoStream fs_stream = IoStream_.Null;
|
||||
try {
|
||||
db_stream = rdr.ReadRdr(Fld_bin_data); if (db_stream == Io_stream_rdr_.Null) return false;
|
||||
fs_stream = Io_mgr._.OpenStreamWrite(url);
|
||||
int pos = 0, flush_nxt = bin_flush_when;
|
||||
while (true) {
|
||||
int read = db_stream.Read(bin_bfr, pos, bin_bfr.length); if (read == Io_stream_rdr_.Read_done) break;
|
||||
fs_stream.Write(bin_bfr, 0, read);
|
||||
if (pos > flush_nxt) {
|
||||
fs_stream.Flush();
|
||||
flush_nxt += bin_flush_when;
|
||||
}
|
||||
}
|
||||
fs_stream.Flush();
|
||||
return true;
|
||||
} finally {
|
||||
db_stream.Rls();
|
||||
fs_stream.Rls();
|
||||
}
|
||||
}
|
||||
private static byte[] Read_bin_data(DataRdr rdr) {
|
||||
byte[] rv = rdr.ReadBry(Fld_bin_data);
|
||||
return rv == null ? Bry_.Empty : rv; // NOTE: bug in v0.10.1 where .ogg would save as null; return Bry_.Empty instead, else java.io.ByteArrayInputStream would fail on null
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_bin", Fld_bin_owner_id = "bin_owner_id", Fld_bin_owner_tid = "bin_owner_tid", Fld_bin_part_id = "bin_part_id", Fld_bin_data_url = "bin_data_url", Fld_bin_data = "bin_data";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_bin"
|
||||
, "( bin_owner_id integer NOT NULL PRIMARY KEY"
|
||||
, ", bin_owner_tid byte NOT NULL"
|
||||
, ", bin_part_id integer NOT NULL"
|
||||
, ", bin_data_url varchar(255) NOT NULL"
|
||||
, ", bin_data mediumblob NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
public static final byte Owner_tid_fil = 1, Owner_tid_thm = 2;
|
||||
public static final int Null_db_bin_id = -1, Null_size = -1, Null_part_id = -1;
|
||||
public static final String Null_data_url = "";
|
||||
}
|
||||
63
400_xowa/src/gplx/fsdb/Fsdb_cfg_grp.java
Normal file
63
400_xowa/src/gplx/fsdb/Fsdb_cfg_grp.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_cfg_grp {
|
||||
private OrderedHash itms = OrderedHash_.new_();
|
||||
public Fsdb_cfg_grp(String grp) {this.grp = grp;}
|
||||
public String Grp() {return grp;} private String grp;
|
||||
public void Insert(String key, String val) {
|
||||
if (itms.Has(key)) throw Err_.new_fmt_("cfg_grp.Insert failed; key={0}", key);
|
||||
Fsdb_cfg_itm itm = new Fsdb_cfg_itm(grp, key, val);
|
||||
itms.Add(key, itm);
|
||||
}
|
||||
public void Update(String key, String val) {
|
||||
Fsdb_cfg_itm itm = (Fsdb_cfg_itm)itms.Fetch(key);
|
||||
if (itm == null) throw Err_.new_fmt_("cfg_grp.Update failed; key={0}", key);
|
||||
itm.Val_(val);
|
||||
}
|
||||
public void Upsert(String key, String val) {
|
||||
Fsdb_cfg_itm itm = (Fsdb_cfg_itm)itms.Fetch(key);
|
||||
if (itm == null) {
|
||||
itm = new Fsdb_cfg_itm(grp, key, val);
|
||||
itms.Add(key, itm);
|
||||
}
|
||||
else
|
||||
itm.Val_(val);
|
||||
}
|
||||
public boolean Get_yn_or_y(String key) {return Get_yn_or(key, Bool_.Y);}
|
||||
public boolean Get_yn_or_n(String key) {return Get_yn_or(key, Bool_.N);}
|
||||
public boolean Get_yn_or(String key, boolean or) {
|
||||
String rv = Get_str_or(key, null);
|
||||
return rv == null ? or : Yn.parse_(rv);
|
||||
}
|
||||
public int Get_int_or(String key, int or) {
|
||||
String rv = Get_str_or(key, null);
|
||||
return rv == null ? or : Int_.parse_(rv);
|
||||
}
|
||||
public String Get_str_or(String key, String or) {
|
||||
Fsdb_cfg_itm itm = (Fsdb_cfg_itm)itms.Fetch(key);
|
||||
return itm == null ? or : itm.Val();
|
||||
}
|
||||
public static final Fsdb_cfg_grp Null = new Fsdb_cfg_grp(); Fsdb_cfg_grp() {}
|
||||
}
|
||||
class Fsdb_cfg_itm {
|
||||
public Fsdb_cfg_itm(String grp, String key, String val) {this.grp = grp; this.key = key; this.val = val;}
|
||||
public String Grp() {return grp;} private String grp;
|
||||
public String Key() {return key;} private String key;
|
||||
public String Val() {return val;} public Fsdb_cfg_itm Val_(String v) {val = v; return this;} private String val;
|
||||
}
|
||||
79
400_xowa/src/gplx/fsdb/Fsdb_cfg_mgr.java
Normal file
79
400_xowa/src/gplx/fsdb/Fsdb_cfg_mgr.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_cfg_mgr {
|
||||
private HashAdp grps = HashAdp_.new_();
|
||||
private Fsdb_cfg_tbl cfg_tbl;
|
||||
public int Next_id() {return next_id++;} private int next_id = 1;
|
||||
public boolean Schema_thm_page() {return schema_thm_page;} private boolean schema_thm_page = true;
|
||||
public boolean Patch_next_id() {return patch_next_id;} private boolean patch_next_id = true;
|
||||
public void Patch_next_id_exec(int last_id) {
|
||||
if (last_id >= next_id)
|
||||
next_id = last_id + 1;
|
||||
cfg_tbl.Insert(Grp_core, Key_patch_next_id, "y");
|
||||
}
|
||||
public void Txn_save() {
|
||||
this.Update_next_id();
|
||||
}
|
||||
public void Rls() {cfg_tbl.Rls();}
|
||||
private void Update_next_id() {cfg_tbl.Update("core", "next_id", Int_.XtoStr(next_id));}
|
||||
public Fsdb_cfg_mgr Update(String grp, String key, String new_val) {
|
||||
String cur_val = cfg_tbl.Select_as_str_or(grp, key, null);
|
||||
if (cur_val == null)
|
||||
cfg_tbl.Insert(grp, key, new_val);
|
||||
else
|
||||
cfg_tbl.Update(grp, key, new_val);
|
||||
return this;
|
||||
}
|
||||
public Fsdb_cfg_grp Grps_get_or_load(String grp_key) {
|
||||
Fsdb_cfg_grp grp = (Fsdb_cfg_grp)grps.Fetch(grp_key);
|
||||
if (grp == null) {
|
||||
grp = cfg_tbl.Select_as_grp(grp_key);
|
||||
grps.Add(grp_key, grp);
|
||||
}
|
||||
return grp;
|
||||
}
|
||||
public Fsdb_cfg_grp Grps_get_or_add(String grp_key) { // TEST:
|
||||
Fsdb_cfg_grp grp = (Fsdb_cfg_grp)grps.Fetch(grp_key);
|
||||
if (grp == null) {
|
||||
grp = new Fsdb_cfg_grp(grp_key);
|
||||
grps.Add(grp_key, grp);
|
||||
}
|
||||
return grp;
|
||||
}
|
||||
public static Fsdb_cfg_mgr load_(Fsdb_db_abc_mgr abc_mgr, Db_provider p) {return new Fsdb_cfg_mgr().Init_by_load(p);}
|
||||
public static Fsdb_cfg_mgr make_(Fsdb_db_abc_mgr abc_mgr, Db_provider p) {return new Fsdb_cfg_mgr().Init_by_make(p);}
|
||||
private Fsdb_cfg_mgr Init_by_load(Db_provider p) {
|
||||
this.cfg_tbl = new Fsdb_cfg_tbl_sql().Ctor(p, false);
|
||||
Fsdb_cfg_grp core_grp = Grps_get_or_load(Grp_core);
|
||||
this.next_id = core_grp.Get_int_or(Key_next_id, -1); if (next_id == -1) throw Err_.new_("next_id not found in fsdb_cfg");
|
||||
this.schema_thm_page = core_grp.Get_yn_or_n(Key_schema_thm_page);
|
||||
this.patch_next_id = core_grp.Get_yn_or_n(Key_patch_next_id);
|
||||
return this;
|
||||
}
|
||||
private Fsdb_cfg_mgr Init_by_make(Db_provider p) {
|
||||
this.cfg_tbl = new Fsdb_cfg_tbl_sql().Ctor(p, true);
|
||||
this.cfg_tbl.Insert(Grp_core, Key_next_id , "1"); // start next_id at 1
|
||||
this.cfg_tbl.Insert(Grp_core, Key_schema_thm_page , "y"); // new dbs automatically have page and time in fsdb_xtn_tm
|
||||
this.cfg_tbl.Insert(Grp_core, Key_patch_next_id , "y"); // new dbs automatically have correct next_id
|
||||
return this;
|
||||
}
|
||||
public static final String Grp_core = "core";
|
||||
public static final String Key_next_id = "next_id", Key_schema_thm_page = "schema.thm.page", Key_patch_next_id = "patch.next_id";
|
||||
}
|
||||
143
400_xowa/src/gplx/fsdb/Fsdb_cfg_tbl.java
Normal file
143
400_xowa/src/gplx/fsdb/Fsdb_cfg_tbl.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public interface Fsdb_cfg_tbl extends RlsAble {
|
||||
Fsdb_cfg_tbl Ctor(Db_provider provider, boolean created);
|
||||
void Insert(String grp, String key, String val);
|
||||
void Update(String grp, String key, String val);
|
||||
int Select_as_int_or(String grp, String key, int or);
|
||||
int Select_as_int_or_fail(String grp, String key);
|
||||
String Select_as_str_or(String grp, String key, String or);
|
||||
Fsdb_cfg_grp Select_as_grp(String grp);
|
||||
}
|
||||
abstract class Fsdb_cfg_tbl_base {
|
||||
public abstract int Select_as_int_or(String grp, String key, int or);
|
||||
public int Select_as_int_or_fail(String grp, String key) {
|
||||
int rv = Select_as_int_or(grp, key, Int_.MinValue);
|
||||
if (rv == Int_.MinValue) throw Err_.new_fmt_("fsdb_cfg did not have itm: grp={0} key={1}", grp, key);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Fsdb_cfg_tbl_mem extends Fsdb_cfg_tbl_base implements Fsdb_cfg_tbl {
|
||||
private HashAdp grps = HashAdp_.new_();
|
||||
public Fsdb_cfg_tbl Ctor(Db_provider provider, boolean created) {return this;}
|
||||
public void Insert(String grp, String key, String val) {
|
||||
Fsdb_cfg_grp grp_itm = Grps_get_or_make(grp);
|
||||
grp_itm.Insert(key, val);
|
||||
}
|
||||
public void Update(String grp, String key, String val) {
|
||||
Fsdb_cfg_grp grp_itm = Grps_get_or_make(grp);
|
||||
grp_itm.Update(key, val);
|
||||
}
|
||||
@Override public int Select_as_int_or(String grp, String key, int or) {
|
||||
Fsdb_cfg_grp grp_itm = Grps_get_or_null(grp);
|
||||
return grp_itm == null ? or : grp_itm.Get_int_or(grp, or);
|
||||
}
|
||||
public String Select_as_str_or(String grp, String key, String or) {
|
||||
Fsdb_cfg_grp grp_itm = Grps_get_or_null(grp);
|
||||
return grp_itm == null ? or : grp_itm.Get_str_or(grp, or);
|
||||
}
|
||||
public Fsdb_cfg_grp Select_as_grp(String grp) {return Grps_get_or_null(grp);}
|
||||
public void Rls() {}
|
||||
private Fsdb_cfg_grp Grps_get_or_make(String grp) {
|
||||
Fsdb_cfg_grp rv = (Fsdb_cfg_grp)grps.Fetch(grp);
|
||||
if (rv == null) {
|
||||
rv = new Fsdb_cfg_grp(grp);
|
||||
grps.Add(grp, rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Fsdb_cfg_grp Grps_get_or_null(String grp) {return (Fsdb_cfg_grp)grps.Fetch(grp);}
|
||||
}
|
||||
class Fsdb_cfg_tbl_sql extends Fsdb_cfg_tbl_base implements Fsdb_cfg_tbl {
|
||||
private Db_provider provider;
|
||||
private Db_stmt stmt_insert, stmt_update, stmt_select;
|
||||
public Fsdb_cfg_tbl Ctor(Db_provider provider, boolean created) {
|
||||
this.provider = provider;
|
||||
if (created) Create_table();
|
||||
return this;
|
||||
}
|
||||
private void Create_table() {
|
||||
Sqlite_engine_.Tbl_create(provider, Tbl_name, Tbl_sql);
|
||||
Sqlite_engine_.Idx_create(provider, Idx_main);
|
||||
}
|
||||
private Db_stmt Insert_stmt() {return Db_stmt_.new_insert_(provider, Tbl_name, Fld_cfg_grp, Fld_cfg_key, Fld_cfg_val);}
|
||||
public void Insert(String grp, String key, String val) {
|
||||
if (stmt_insert == null) stmt_insert = Insert_stmt();
|
||||
stmt_insert.Clear()
|
||||
.Val_str_(grp)
|
||||
.Val_str_(key)
|
||||
.Val_str_(val)
|
||||
.Exec_insert();
|
||||
}
|
||||
private Db_stmt Update_stmt() {return Db_stmt_.new_update_(provider, Tbl_name, String_.Ary(Fld_cfg_grp, Fld_cfg_key), Fld_cfg_val);}
|
||||
public void Update(String grp, String key, String val) {
|
||||
if (stmt_update == null) stmt_update = Update_stmt();
|
||||
stmt_update.Clear()
|
||||
.Val_str_(val)
|
||||
.Val_str_(grp)
|
||||
.Val_str_(key)
|
||||
.Exec_update();
|
||||
}
|
||||
private Db_stmt Select_stmt() {
|
||||
Db_qry_select qry = Db_qry_.select_val_(Tbl_name, Fld_cfg_val, gplx.criterias.Criteria_.And_many(Db_crt_.eq_(Fld_cfg_grp, ""), Db_crt_.eq_(Fld_cfg_key, "")));
|
||||
return provider.Prepare(qry);
|
||||
}
|
||||
@Override public int Select_as_int_or(String grp, String key, int or) {return Int_.parse_or_(Select_as_str_or(grp, key, null), or);}
|
||||
public String Select_as_str_or(String grp, String key, String or) {
|
||||
if (stmt_select == null) stmt_select = Select_stmt();
|
||||
Object rv = (String)stmt_select.Clear()
|
||||
.Val_str_(grp)
|
||||
.Val_str_(key)
|
||||
.Exec_select_val();
|
||||
return rv == null ? or : (String)rv;
|
||||
}
|
||||
public Fsdb_cfg_grp Select_as_grp(String grp) {
|
||||
Fsdb_cfg_grp rv = null;
|
||||
Db_qry_select qry = Db_qry_.select_cols_(Tbl_name, gplx.criterias.Criteria_.And_many(Db_crt_.eq_(Fld_cfg_grp, "")), Fld_cfg_key, Fld_cfg_val);
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = provider.Prepare(qry).Clear().Val_str_(grp).Exec_select();
|
||||
while (rdr.MoveNextPeer()) {
|
||||
if (rv == null) rv = new Fsdb_cfg_grp(grp);
|
||||
String key = rdr.ReadStr(Fld_cfg_key);
|
||||
String val = rdr.ReadStr(Fld_cfg_val);
|
||||
rv.Upsert(key, val);
|
||||
}
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
return rv == null ? Fsdb_cfg_grp.Null : rv;
|
||||
}
|
||||
public void Rls() {
|
||||
if (stmt_insert != null) {stmt_insert.Rls(); stmt_insert = null;}
|
||||
if (stmt_update != null) {stmt_update.Rls(); stmt_update = null;}
|
||||
if (stmt_select != null) {stmt_select.Rls(); stmt_select = null;}
|
||||
}
|
||||
private static final String Tbl_name = "fsdb_cfg", Fld_cfg_grp = "cfg_grp", Fld_cfg_key = "cfg_key", Fld_cfg_val = "cfg_val";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_cfg"
|
||||
, "( cfg_grp varchar(255) NOT NULL"
|
||||
, ", cfg_key varchar(255) NOT NULL"
|
||||
, ", cfg_val varchar(1024) NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
private static final Db_idx_itm
|
||||
Idx_main = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS fsdb_cfg__main ON fsdb_cfg (cfg_grp, cfg_key, cfg_val);")
|
||||
;
|
||||
}
|
||||
22
400_xowa/src/gplx/fsdb/Fsdb_cfg_tbl_.java
Normal file
22
400_xowa/src/gplx/fsdb/Fsdb_cfg_tbl_.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_cfg_tbl_ {
|
||||
public static Fsdb_cfg_tbl new_sql_() {return new Fsdb_cfg_tbl_sql();}
|
||||
public static Fsdb_cfg_tbl new_mem_() {return new Fsdb_cfg_tbl_mem();}
|
||||
}
|
||||
112
400_xowa/src/gplx/fsdb/Fsdb_db_abc_mgr.java
Normal file
112
400_xowa/src/gplx/fsdb/Fsdb_db_abc_mgr.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_db_abc_mgr implements RlsAble {
|
||||
private Db_provider boot_provider;
|
||||
public int Next_id() {return cfg_mgr.Next_id();}
|
||||
public Fsdb_mnt_mgr Mnt_mgr() {return mnt_mgr;} private Fsdb_mnt_mgr mnt_mgr;
|
||||
public Fsdb_db_abc_mgr(Fsdb_mnt_mgr mnt_mgr) {this.mnt_mgr = mnt_mgr;}
|
||||
public Fsdb_db_atr_mgr Atr_mgr() {return atr_mgr;} private Fsdb_db_atr_mgr atr_mgr;
|
||||
public Fsdb_db_bin_mgr Bin_mgr() {return bin_mgr;} private Fsdb_db_bin_mgr bin_mgr;
|
||||
public Fsdb_cfg_mgr Cfg_mgr() {return cfg_mgr;} private Fsdb_cfg_mgr cfg_mgr;
|
||||
public Fsdb_db_abc_mgr Init(Io_url dir) {
|
||||
Io_url url = dir.GenSubFil("fsdb.abc.sqlite3");
|
||||
if (Io_mgr._.ExistsFil(url))
|
||||
Init_load(dir, url);
|
||||
else
|
||||
Init_make(dir, url);
|
||||
return this;
|
||||
}
|
||||
public void Fil_insert(Fsdb_fil_itm rv , byte[] dir, byte[] fil, int ext_id, DateAdp modified, String hash, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
int bin_db_id = bin_mgr.Get_id_for_insert(bin_len);
|
||||
rv.Db_bin_id_(bin_db_id);
|
||||
int fil_id = atr_mgr.Fil_insert(rv, dir, fil, ext_id, modified, hash, bin_db_id, bin_len, bin_rdr);
|
||||
bin_len = bin_mgr.Insert(bin_db_id, fil_id, Fsdb_bin_tbl.Owner_tid_fil, bin_len, bin_rdr);
|
||||
bin_mgr.Increment(bin_len);
|
||||
}
|
||||
public void Thm_insert(Fsdb_xtn_thm_itm rv, byte[] dir, byte[] fil, int ext_id, int w, int h, double thumbtime, int page, DateAdp modified, String hash, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
int bin_db_id = bin_mgr.Get_id_for_insert(bin_len);
|
||||
rv.Db_bin_id_(bin_db_id);
|
||||
int thm_id = atr_mgr.Thm_insert(rv, dir, fil, ext_id, w, h, thumbtime, page, modified, hash, bin_db_id, bin_len, bin_rdr);
|
||||
bin_len = bin_mgr.Insert(bin_db_id, thm_id, Fsdb_bin_tbl.Owner_tid_thm, bin_len, bin_rdr);
|
||||
bin_mgr.Increment(bin_len);
|
||||
}
|
||||
public void Img_insert(Fsdb_xtn_img_itm rv, byte[] dir, byte[] fil, int ext_id, DateAdp modified, String hash, long bin_len, gplx.ios.Io_stream_rdr bin_rdr, int img_w, int img_h) {
|
||||
int bin_db_id = bin_mgr.Get_id_for_insert(bin_len);
|
||||
rv.Db_bin_id_(bin_db_id);
|
||||
int fil_id = atr_mgr.Img_insert(rv, String_.new_utf8_(dir), String_.new_utf8_(fil), ext_id, img_w, img_h, modified, hash, bin_db_id, bin_len, bin_rdr);
|
||||
bin_len = bin_mgr.Insert(bin_db_id, fil_id, Fsdb_bin_tbl.Owner_tid_fil, bin_len, bin_rdr);
|
||||
bin_mgr.Increment(bin_len);
|
||||
}
|
||||
public boolean Thm_select_bin(byte[] dir, byte[] fil, Fsdb_xtn_thm_itm thm) {
|
||||
Fsdb_fil_itm fil_itm = atr_mgr.Fil_select(dir, fil);
|
||||
return atr_mgr.Thm_select(fil_itm.Id(), thm);
|
||||
}
|
||||
public Fsdb_fil_itm Fil_select_bin(byte[] dir, byte[] fil, boolean is_thumb, int width, double thumbtime) {
|
||||
return atr_mgr.Fil_select(dir, fil);
|
||||
}
|
||||
public void Txn_open() {
|
||||
boot_provider.Txn_mgr().Txn_bgn_if_none();
|
||||
atr_mgr.Txn_open();
|
||||
bin_mgr.Txn_open();
|
||||
}
|
||||
public void Txn_save() {
|
||||
atr_mgr.Txn_save(boot_provider);
|
||||
bin_mgr.Txn_save();
|
||||
cfg_mgr.Txn_save();
|
||||
}
|
||||
public void Rls() {
|
||||
atr_mgr.Rls();
|
||||
bin_mgr.Rls();
|
||||
cfg_mgr.Rls();
|
||||
boot_provider.Rls();
|
||||
}
|
||||
private void Init_load(Io_url dir, Io_url boot_url) {
|
||||
Db_connect connect = Db_connect_sqlite.load_(boot_url);
|
||||
boot_provider = Db_provider_.new_(connect);
|
||||
atr_mgr = Fsdb_db_atr_mgr.load_(this, boot_provider, dir);
|
||||
bin_mgr = Fsdb_db_bin_mgr.load_(boot_provider, dir);
|
||||
cfg_mgr = Fsdb_cfg_mgr.load_(this, boot_provider);
|
||||
if (!cfg_mgr.Patch_next_id()) Fsdb_db_abc_mgr_.Patch_next_id(this, dir);
|
||||
}
|
||||
private void Init_make(Io_url dir, Io_url boot_url) {
|
||||
Db_connect connect = Db_connect_sqlite.make_(boot_url);
|
||||
boot_provider = Db_provider_.new_(connect);
|
||||
Sqlite_engine_.Pragma_page_size_4096(boot_provider);
|
||||
atr_mgr = Fsdb_db_atr_mgr.make_(this, boot_provider, dir);
|
||||
bin_mgr = Fsdb_db_bin_mgr.make_(boot_provider, dir);
|
||||
cfg_mgr = Fsdb_cfg_mgr.make_(this, boot_provider);
|
||||
this.Txn_save(); // immediately save new entries in atr,cfg
|
||||
}
|
||||
}
|
||||
class Fsdb_db_abc_mgr_ {
|
||||
public static void Patch_next_id(Fsdb_db_abc_mgr abc_mgr, Io_url dir) {
|
||||
if (!String_.Eq(dir.NameOnly(), "fsdb.user")) return;
|
||||
Fsdb_db_atr_mgr atr_mgr = abc_mgr.Atr_mgr();
|
||||
Fsdb_cfg_mgr cfg_mgr = abc_mgr.Cfg_mgr();
|
||||
int last_id = -1;
|
||||
if (atr_mgr.Len() > 0) {
|
||||
Fsdb_db_atr_fil atr_fil = atr_mgr.Get_at(0);
|
||||
int max_fil_id = Db_provider_.Select_fld0_as_int_or(atr_fil.Provider(), "SELECT Max(fil_id) AS MaxId FROM fsdb_fil;", -1);
|
||||
int max_thm_id = Db_provider_.Select_fld0_as_int_or(atr_fil.Provider(), "SELECT Max(thm_id) AS MaxId FROM fsdb_xtn_thm;", -1);
|
||||
last_id = max_fil_id > max_thm_id ? max_fil_id : max_thm_id;
|
||||
}
|
||||
cfg_mgr.Patch_next_id_exec(last_id);
|
||||
}
|
||||
}
|
||||
150
400_xowa/src/gplx/fsdb/Fsdb_db_atr_fil.java
Normal file
150
400_xowa/src/gplx/fsdb/Fsdb_db_atr_fil.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*; import gplx.cache.*;
|
||||
public class Fsdb_db_atr_fil implements RlsAble {
|
||||
private Gfo_cache_mgr_bry dir_cache = new Gfo_cache_mgr_bry();
|
||||
private Fsdb_dir_tbl tbl_dir; private Fsdb_fil_tbl tbl_fil; private Fsdb_xtn_thm_tbl tbl_thm; private Fsdb_xtn_img_tbl tbl_img; private Bool_obj_ref img_needs_create = Bool_obj_ref.n_();
|
||||
public Fsdb_db_atr_fil(Fsdb_db_abc_mgr abc_mgr, Io_url url, boolean create) {
|
||||
this.abc_mgr = abc_mgr;
|
||||
Db_connect connect = create ? Db_connect_sqlite.make_(url) : Db_connect_sqlite.load_(url);
|
||||
provider = Db_provider_.new_(connect);
|
||||
Sqlite_engine_.Pragma_page_size_4096(provider);
|
||||
tbl_dir = new Fsdb_dir_tbl(provider, create);
|
||||
tbl_fil = new Fsdb_fil_tbl(provider, create);
|
||||
tbl_thm = new Fsdb_xtn_thm_tbl(this, provider, create);
|
||||
tbl_img = new Fsdb_xtn_img_tbl(provider, create);
|
||||
}
|
||||
public Fsdb_db_abc_mgr Abc_mgr() {return abc_mgr;} private Fsdb_db_abc_mgr abc_mgr;
|
||||
public Db_provider Provider() {return provider;} private Db_provider provider;
|
||||
public int Id() {return id;} private int id;
|
||||
public Io_url Url() {return url;} private Io_url url;
|
||||
public String Path_bgn() {return path_bgn;} private String path_bgn;
|
||||
public byte Cmd_mode() {return cmd_mode;} public Fsdb_db_atr_fil Cmd_mode_(byte v) {cmd_mode = v; return this;} private byte cmd_mode;
|
||||
public void Rls() {
|
||||
tbl_dir.Rls();
|
||||
tbl_fil.Rls();
|
||||
tbl_img.Rls();
|
||||
tbl_thm.Rls();
|
||||
provider.Txn_mgr().Txn_end_all();
|
||||
provider.Rls();
|
||||
}
|
||||
public void Txn_open() {
|
||||
provider.Txn_mgr().Txn_bgn_if_none();
|
||||
}
|
||||
public void Txn_save() {
|
||||
provider.Txn_mgr().Txn_end_all();
|
||||
}
|
||||
public Fsdb_fil_itm Fil_select(byte[] dir, byte[] fil) {
|
||||
Int_obj_ref dir_id_obj = (Int_obj_ref)dir_cache.Get_or_null(dir);
|
||||
int dir_id = -1;
|
||||
if (dir_id_obj == null) {
|
||||
Fsdb_dir_itm dir_itm = tbl_dir.Select_itm(String_.new_utf8_(dir));
|
||||
dir_id = dir_itm == Fsdb_dir_itm.Null ? -1 : dir_itm.Id();
|
||||
dir_cache.Add(dir, Int_obj_ref.new_(dir_id));
|
||||
}
|
||||
else
|
||||
dir_id = dir_id_obj.Val();
|
||||
if (dir_id == Int_.Neg1) return Fsdb_fil_itm.Null;
|
||||
return tbl_fil.Select_itm_by_name(dir_id, String_.new_utf8_(fil));
|
||||
}
|
||||
public boolean Thm_select(int owner_id, Fsdb_xtn_thm_itm thm) {
|
||||
return tbl_thm.Select_itm_by_fil_width(owner_id, thm);
|
||||
}
|
||||
public int Fil_insert(Fsdb_fil_itm rv, String dir, String fil, int ext_id, DateAdp modified, String hash, int bin_db_id, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
int dir_id = Dir_id__get_or_insert(dir);
|
||||
int fil_id = Fil_id__get_or_insert(Fsdb_xtn_tid_.Tid_none, dir_id, fil, ext_id, modified, hash, bin_db_id, bin_len);
|
||||
rv.Id_(fil_id).Owner_(dir_id);
|
||||
return fil_id;
|
||||
}
|
||||
public int Img_insert(Fsdb_xtn_img_itm rv, String dir, String fil, int ext_id, int img_w, int img_h, DateAdp modified, String hash, int bin_db_id, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
int dir_id = Dir_id__get_or_insert(dir);
|
||||
img_needs_create.Val_(false);
|
||||
int fil_id = Fil_id__get_or_insert(Fsdb_xtn_tid_.Tid_img, dir_id, fil, ext_id, modified, hash, bin_db_id, bin_len);
|
||||
if (img_needs_create.Val()) // NOTE: fsdb_fil row can already exist; EX: thm gets inserted -> fsdb_fil row gets created with -1 bin_db_id; orig gets inserted -> fsdb_fil row already exists
|
||||
tbl_img.Insert(fil_id, img_w, img_h);
|
||||
rv.Id_(fil_id);
|
||||
return fil_id;
|
||||
}
|
||||
public int Thm_insert(Fsdb_xtn_thm_itm rv, String dir, String fil, int ext_id, int thm_w, int thm_h, double thumbtime, int page, DateAdp modified, String hash, int bin_db_id, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
int dir_id = Dir_id__get_or_insert(dir);
|
||||
int fil_id = Fil_id__get_or_insert(Fsdb_xtn_tid_.Tid_thm, dir_id, fil, ext_id, modified, hash, Fsdb_bin_tbl.Null_db_bin_id, Fsdb_bin_tbl.Null_size); // NOTE: bin_db_id must be set to NULL
|
||||
int thm_id = abc_mgr.Next_id();
|
||||
tbl_thm.Insert(thm_id, fil_id, thm_w, thm_h, thumbtime, page, bin_db_id, bin_len, modified, hash);
|
||||
rv.Id_(thm_id).Owner_id_(fil_id).Dir_id_(dir_id);
|
||||
return thm_id;
|
||||
}
|
||||
public static Fsdb_db_atr_fil load_(Fsdb_db_abc_mgr abc_mgr, DataRdr rdr, Io_url dir) {
|
||||
Io_url url = dir.GenSubFil(rdr.ReadStr(Fsdb_db_atr_tbl.Fld_url));
|
||||
Fsdb_db_atr_fil rv = new Fsdb_db_atr_fil(abc_mgr, url, false);
|
||||
rv.id = rdr.ReadInt(Fsdb_db_atr_tbl.Fld_uid);
|
||||
rv.url = url;
|
||||
rv.path_bgn = rdr.ReadStr(Fsdb_db_atr_tbl.Fld_path_bgn);
|
||||
rv.cmd_mode = Db_cmd_mode.Ignore;
|
||||
return rv;
|
||||
}
|
||||
public static Fsdb_db_atr_fil make_(Fsdb_db_abc_mgr abc_mgr, int id, Io_url url, String path_bgn) {
|
||||
Fsdb_db_atr_fil rv = new Fsdb_db_atr_fil(abc_mgr, url, true);
|
||||
rv.id = id;
|
||||
rv.url = url;
|
||||
rv.path_bgn = path_bgn;
|
||||
rv.cmd_mode = Db_cmd_mode.Create;
|
||||
return rv;
|
||||
}
|
||||
private int Dir_id__get_or_insert(String dir_str) {
|
||||
byte[] dir_bry = Bry_.new_utf8_(dir_str);
|
||||
Object rv_obj = dir_cache.Get_or_null(dir_bry);
|
||||
int rv = -1;
|
||||
if (rv_obj != null) { // item found
|
||||
rv = ((Int_obj_ref)rv_obj).Val();
|
||||
if (rv == -1) // dir was previously -1; occurs when doing select on empty db (no dir, so -1 added) and then doing insert (-1 now needs to be dropped)
|
||||
dir_cache.Del(dir_bry);
|
||||
}
|
||||
if (rv == -1) {
|
||||
Fsdb_dir_itm itm = tbl_dir.Select_itm(dir_str);
|
||||
if (itm == Fsdb_dir_itm.Null) {
|
||||
rv = abc_mgr.Next_id();
|
||||
tbl_dir.Insert(rv, dir_str, 0); // 0: always assume root owner
|
||||
}
|
||||
else {
|
||||
rv = itm.Id();
|
||||
}
|
||||
dir_cache.Add(dir_bry, Int_obj_ref.new_(rv));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
private int Fil_id__get_or_insert(int xtn_tid, int dir_id, String fil, int ext_id, DateAdp modified, String hash, int bin_db_id, long bin_len) {
|
||||
Fsdb_fil_itm fil_itm = tbl_fil.Select_itm_by_name(dir_id, fil);
|
||||
int fil_id = fil_itm.Id();
|
||||
if (fil_id == Fsdb_fil_itm.Null_id) { // new item
|
||||
fil_id = abc_mgr.Next_id();
|
||||
tbl_fil.Insert(fil_id, dir_id, fil, xtn_tid, ext_id, bin_len, modified, hash, bin_db_id);
|
||||
img_needs_create.Val_(true);
|
||||
}
|
||||
else { // existing item
|
||||
if ( fil_itm.Db_bin_id() == Fsdb_bin_tbl.Null_db_bin_id // prv row was previously inserted by thumb
|
||||
&& xtn_tid != Fsdb_xtn_tid_.Tid_thm // cur row is not thumb
|
||||
) {
|
||||
tbl_fil.Update(fil_id, dir_id, fil, xtn_tid, ext_id, bin_len, modified, hash, bin_db_id); // update props; note that thumb inserts null props, whereas file will insert real props (EX: bin_db_id)
|
||||
if (xtn_tid == Fsdb_xtn_tid_.Tid_img)
|
||||
img_needs_create.Val_(true);
|
||||
}
|
||||
}
|
||||
return fil_id;
|
||||
}
|
||||
}
|
||||
76
400_xowa/src/gplx/fsdb/Fsdb_db_atr_mgr.java
Normal file
76
400_xowa/src/gplx/fsdb/Fsdb_db_atr_mgr.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*; import gplx.cache.*;
|
||||
public class Fsdb_db_atr_mgr implements RlsAble {
|
||||
private Fsdb_db_atr_fil[] itms; private Fsdb_db_atr_fil itms_0;
|
||||
public int Len() {return itms.length;}
|
||||
public Fsdb_db_atr_fil Get_at(int i) {return i == Id_0 ? itms_0 : itms[i];}
|
||||
public Fsdb_fil_itm Fil_select(byte[] dir, byte[] fil) {return itms_0.Fil_select(dir, fil);}
|
||||
public boolean Thm_select(int owner_id, Fsdb_xtn_thm_itm thm) {return itms_0.Thm_select(owner_id, thm);}
|
||||
public int Fil_insert(Fsdb_fil_itm rv , byte[] dir, byte[] fil, int ext_id, DateAdp modified, String hash, int bin_db_id, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
return itms_0.Fil_insert(rv, String_.new_utf8_(dir), String_.new_utf8_(fil), ext_id, modified, hash, bin_db_id, bin_len, bin_rdr);
|
||||
}
|
||||
public int Img_insert(Fsdb_xtn_img_itm rv, String dir, String fil, int ext_id, int img_w, int img_h, DateAdp modified, String hash, int bin_db_id, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
return itms_0.Img_insert(rv, dir, fil, ext_id, img_w, img_h, modified, hash, bin_db_id, bin_len, bin_rdr);
|
||||
}
|
||||
public int Thm_insert(Fsdb_xtn_thm_itm rv, byte[] dir, byte[] fil, int ext_id, int width, int height, double thumbtime, int page, DateAdp modified, String hash, int bin_db_id, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
return itms_0.Thm_insert(rv, String_.new_utf8_(dir), String_.new_utf8_(fil), ext_id, width, height, thumbtime, page, modified, hash, bin_db_id, bin_len, bin_rdr);
|
||||
}
|
||||
public void Txn_open() {
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Fsdb_db_atr_fil itm = itms[i];
|
||||
itm.Txn_open();
|
||||
}
|
||||
}
|
||||
public void Txn_save(Db_provider provider) {
|
||||
Fsdb_db_atr_tbl.Commit_all(provider, itms);
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Fsdb_db_atr_fil itm = itms[i];
|
||||
itm.Txn_save();
|
||||
}
|
||||
}
|
||||
public void Rls() {
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Fsdb_db_atr_fil itm = itms[i];
|
||||
itm.Rls();
|
||||
}
|
||||
}
|
||||
public static Fsdb_db_atr_mgr load_(Fsdb_db_abc_mgr abc_mgr, Db_provider p, Io_url dir) {
|
||||
Fsdb_db_atr_mgr rv = new Fsdb_db_atr_mgr();
|
||||
rv.itms = Fsdb_db_atr_tbl.Select_all(abc_mgr, p, dir);
|
||||
rv.itms_0 = rv.itms[0];
|
||||
return rv;
|
||||
}
|
||||
public static Fsdb_db_atr_mgr make_(Fsdb_db_abc_mgr abc_mgr, Db_provider p, Io_url dir) {
|
||||
Fsdb_db_atr_tbl.Create_table(p);
|
||||
Fsdb_db_atr_mgr rv = new Fsdb_db_atr_mgr();
|
||||
Fsdb_db_atr_fil itm = Fsdb_db_atr_fil.make_(abc_mgr, Id_0, url_(dir, Id_0), Path_bgn_0);
|
||||
rv.itms_0 = itm;
|
||||
rv.itms = new Fsdb_db_atr_fil[] {itm};
|
||||
return rv;
|
||||
}
|
||||
private static Io_url url_(Io_url dir, int id) {
|
||||
return dir.GenSubFil_ary("fsdb.atr.", Int_.XtoStr_PadBgn(id, 2), ".sqlite3");
|
||||
}
|
||||
public static final int Id_0 = 0;
|
||||
public static final String Path_bgn_0 = "";
|
||||
}
|
||||
64
400_xowa/src/gplx/fsdb/Fsdb_db_atr_tbl.java
Normal file
64
400_xowa/src/gplx/fsdb/Fsdb_db_atr_tbl.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_db_atr_tbl {
|
||||
public static void Create_table(Db_provider p) {Sqlite_engine_.Tbl_create(p, Tbl_name, Tbl_sql);}
|
||||
public static Fsdb_db_atr_fil[] Select_all(Fsdb_db_abc_mgr abc_mgr, Db_provider p, Io_url dir) {
|
||||
ListAdp rv = ListAdp_.new_();
|
||||
Db_qry qry = Db_qry_select.new_().From_(Tbl_name).Cols_all_().OrderBy_asc_(Fld_uid);
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = p.Exec_qry_as_rdr(qry);
|
||||
while (rdr.MoveNextPeer()) {
|
||||
Fsdb_db_atr_fil itm = Fsdb_db_atr_fil.load_(abc_mgr, rdr, dir);
|
||||
rv.Add(itm);
|
||||
}
|
||||
} finally {rdr.Rls();}
|
||||
return (Fsdb_db_atr_fil[])rv.XtoAry(Fsdb_db_atr_fil.class);
|
||||
}
|
||||
public static void Commit_all(Db_provider provider, Fsdb_db_atr_fil[] ary) {
|
||||
stmt_bldr.Init(provider);
|
||||
try {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Commit_itm(ary[i]);
|
||||
stmt_bldr.Commit();
|
||||
} finally {stmt_bldr.Rls();}
|
||||
}
|
||||
private static void Commit_itm(Fsdb_db_atr_fil itm) {
|
||||
Db_stmt stmt = stmt_bldr.Get(itm.Cmd_mode());
|
||||
switch (itm.Cmd_mode()) {
|
||||
case Db_cmd_mode.Create: stmt.Clear().Val_int_(itm.Id()) .Val_str_(itm.Url().NameAndExt()).Val_str_(itm.Path_bgn()).Exec_insert(); break;
|
||||
case Db_cmd_mode.Update: stmt.Clear() .Val_str_(itm.Url().NameAndExt()).Val_str_(itm.Path_bgn()).Val_int_(itm.Id()).Exec_update(); break;
|
||||
case Db_cmd_mode.Delete: stmt.Clear().Val_int_(itm.Id()).Exec_delete(); break;
|
||||
case Db_cmd_mode.Ignore: break;
|
||||
default: throw Err_.unhandled(itm.Cmd_mode());
|
||||
}
|
||||
itm.Cmd_mode_(Db_cmd_mode.Ignore);
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_db_atr", Fld_uid = "uid", Fld_url = "url", Fld_path_bgn = "path_bgn";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_db_atr"
|
||||
, "( uid integer NOT NULL PRIMARY KEY"
|
||||
, ", url varchar(255) NOT NULL"
|
||||
, ", path_bgn varchar(255) NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
private static Db_stmt_bldr stmt_bldr = new Db_stmt_bldr(Tbl_name, String_.Ary(Fld_uid), Fld_url, Fld_path_bgn);
|
||||
}
|
||||
85
400_xowa/src/gplx/fsdb/Fsdb_db_bin_fil.java
Normal file
85
400_xowa/src/gplx/fsdb/Fsdb_db_bin_fil.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*; import gplx.ios.*;
|
||||
public class Fsdb_db_bin_fil implements RlsAble {
|
||||
public int Id() {return id;} private int id;
|
||||
public Io_url Url() {return url;} private Io_url url;
|
||||
public long Bin_max() {return bin_max;} private long bin_max;
|
||||
public void Bin_max_(long v) {
|
||||
bin_max = v;
|
||||
if (cmd_mode == Db_cmd_mode.Ignore) cmd_mode = Db_cmd_mode.Update;
|
||||
}
|
||||
public long Bin_len() {return bin_len;} private long bin_len;
|
||||
public void Bin_len_(long v) {
|
||||
bin_len = v;
|
||||
if (cmd_mode == Db_cmd_mode.Ignore) cmd_mode = Db_cmd_mode.Update;
|
||||
}
|
||||
public byte Cmd_mode() {return cmd_mode;} public Fsdb_db_bin_fil Cmd_mode_(byte v) {cmd_mode = v; return this;} private byte cmd_mode;
|
||||
public Db_provider Provider() {
|
||||
if (provider == null) {
|
||||
if (cmd_mode == Db_cmd_mode.Create) {
|
||||
provider = Db_provider_.new_(Db_connect_sqlite.make_(url));
|
||||
Sqlite_engine_.Pragma_page_size_4096(provider);
|
||||
Fsdb_bin_tbl.Create_table(provider);
|
||||
}
|
||||
else
|
||||
provider = Db_provider_.new_(Db_connect_sqlite.load_(url));
|
||||
}
|
||||
return provider;
|
||||
} private Db_provider provider;
|
||||
public void Rls() {if (provider != null) provider.Rls();}
|
||||
public long Insert(int bin_id, byte owner_tid, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
Db_stmt stmt = Db_stmt_.Null;
|
||||
try {
|
||||
stmt = Fsdb_bin_tbl.Insert_stmt(this.Provider());
|
||||
return Fsdb_bin_tbl.Insert_rdr(stmt, bin_id, owner_tid, bin_len, bin_rdr);
|
||||
}
|
||||
finally {stmt.Rls();}
|
||||
}
|
||||
public boolean Get_to_url(int id, Io_url url, byte[] bin_bfr, int bin_flush_when) {
|
||||
return Fsdb_bin_tbl.Select_to_url(this.Provider(), id, url, bin_bfr, bin_flush_when);
|
||||
}
|
||||
public Io_stream_rdr Get_as_rdr(int id) {
|
||||
return Fsdb_bin_tbl.Select_as_rdr(this.Provider(), id);
|
||||
}
|
||||
public static Fsdb_db_bin_fil load_(DataRdr rdr, Io_url dir) {
|
||||
return new_
|
||||
( rdr.ReadInt(Fsdb_db_bin_tbl.Fld_uid)
|
||||
, dir.GenSubFil(rdr.ReadStr(Fsdb_db_bin_tbl.Fld_url))
|
||||
, rdr.ReadLong(Fsdb_db_bin_tbl.Fld_bin_len)
|
||||
, rdr.ReadLong(Fsdb_db_bin_tbl.Fld_bin_max)
|
||||
, Db_cmd_mode.Ignore
|
||||
);
|
||||
}
|
||||
public static Fsdb_db_bin_fil make_(int id, Io_url url, long bin_len, long bin_max) {
|
||||
Fsdb_db_bin_fil rv = new_(id, url, bin_len, bin_max, Db_cmd_mode.Create);
|
||||
rv.Provider(); // force table create
|
||||
return rv;
|
||||
}
|
||||
private static Fsdb_db_bin_fil new_(int id, Io_url url, long bin_len, long bin_max, byte cmd_mode) {
|
||||
Fsdb_db_bin_fil rv = new Fsdb_db_bin_fil();
|
||||
rv.id = id;
|
||||
rv.url = url;
|
||||
rv.bin_len = bin_len;
|
||||
rv.bin_max = bin_max;
|
||||
rv.cmd_mode = cmd_mode;
|
||||
return rv;
|
||||
}
|
||||
public static final Fsdb_db_bin_fil[] Ary_empty = new Fsdb_db_bin_fil[0];
|
||||
}
|
||||
99
400_xowa/src/gplx/fsdb/Fsdb_db_bin_mgr.java
Normal file
99
400_xowa/src/gplx/fsdb/Fsdb_db_bin_mgr.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_db_bin_mgr implements RlsAble {
|
||||
private Io_url dir;
|
||||
private Fsdb_db_bin_fil[] itms = Fsdb_db_bin_fil.Ary_empty; private int itms_len = 0;
|
||||
private Fsdb_db_bin_fil itms_n;
|
||||
private Db_provider provider;
|
||||
private Fsdb_db_bin_mgr(Io_url dir) {this.dir = dir;}
|
||||
public int Len() {return itms.length;}
|
||||
public long Db_bin_max() {return db_bin_max;}
|
||||
public int Insert_to_bin() {return insert_to_bin;} public Fsdb_db_bin_mgr Insert_to_bin_(int v) {insert_to_bin = v; return this;} private int insert_to_bin = Fsdb_mnt_mgr.Insert_to_bin_null;
|
||||
public Fsdb_db_bin_mgr Db_bin_max_(long v) {
|
||||
db_bin_max = v;
|
||||
for (int i = 0; i < itms_len; i++)
|
||||
itms[i].Bin_max_(v);
|
||||
return this;
|
||||
} private long db_bin_max = Io_mgr.Len_mb * Long_.X_by_int(188);
|
||||
public Fsdb_db_bin_fil Get_at(int i) {return itms[i];}
|
||||
private Fsdb_db_bin_fil Get_cur() {return itms_len == 0 ? null : itms[itms_len - 1];}
|
||||
public void Txn_open() {
|
||||
Get_cur().Provider().Txn_mgr().Txn_bgn_if_none();
|
||||
}
|
||||
public void Txn_save() {
|
||||
Fsdb_db_bin_tbl.Commit_all(provider, itms);
|
||||
Get_cur().Provider().Txn_mgr().Txn_end_all();
|
||||
}
|
||||
public void Rls() {
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Fsdb_db_bin_fil itm = itms[i];
|
||||
itm.Rls();
|
||||
}
|
||||
}
|
||||
public int Get_id_for_insert(long bin_len) {
|
||||
if (insert_to_bin != Fsdb_mnt_mgr.Insert_to_bin_null) return insert_to_bin; // insert_to_bin specified; return it
|
||||
if (itms_n.Bin_len() > itms_n.Bin_max())
|
||||
Itms_add(0);
|
||||
return itms_n.Id();
|
||||
}
|
||||
public void Increment(long bin_len) {
|
||||
long new_bin_len = itms_n.Bin_len() + bin_len;
|
||||
itms_n.Bin_len_(new_bin_len);
|
||||
}
|
||||
public long Insert(int db_id, int bin_id, byte owner_tid, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
Fsdb_db_bin_fil bin_fil = itms[db_id];
|
||||
return bin_fil.Insert(bin_id, owner_tid, bin_len, bin_rdr);
|
||||
}
|
||||
public static Fsdb_db_bin_mgr load_(Db_provider p, Io_url dir) {
|
||||
Fsdb_db_bin_mgr rv = new Fsdb_db_bin_mgr(dir);
|
||||
rv.provider = p;
|
||||
rv.itms = Fsdb_db_bin_tbl.Select_all(p, dir);
|
||||
rv.itms_len = rv.itms.length;
|
||||
rv.itms_n = rv.itms[rv.itms_len - 1];
|
||||
return rv;
|
||||
}
|
||||
public static Fsdb_db_bin_mgr make_(Db_provider p, Io_url dir) {
|
||||
Fsdb_db_bin_tbl.Create_table(p);
|
||||
Fsdb_db_bin_mgr rv = new Fsdb_db_bin_mgr(dir);
|
||||
rv.provider = p;
|
||||
rv.Itms_add(0);
|
||||
return rv;
|
||||
}
|
||||
private void Itms_add(long bin_len) {
|
||||
Fsdb_db_bin_fil cur = Get_cur();
|
||||
if (cur != null) {
|
||||
cur.Provider().Txn_mgr().Txn_end_all();
|
||||
cur.Provider().Rls();
|
||||
}
|
||||
int new_itms_len = itms_len + 1;
|
||||
Fsdb_db_bin_fil[] new_itms = new Fsdb_db_bin_fil[new_itms_len];
|
||||
for (int i = 0; i < itms_len; i++)
|
||||
new_itms[i] = itms[i];
|
||||
itms_n = Fsdb_db_bin_fil.make_(itms_len, url_(dir, itms_len), bin_len, db_bin_max);
|
||||
itms = new_itms;
|
||||
itms_len = new_itms_len;
|
||||
itms[itms_len - 1] = itms_n;
|
||||
this.Txn_open();
|
||||
}
|
||||
private static Io_url url_(Io_url dir, int id) {
|
||||
return dir.GenSubFil_ary("fsdb.bin.", Int_.XtoStr_PadBgn(id, 4), ".sqlite3");
|
||||
}
|
||||
}
|
||||
65
400_xowa/src/gplx/fsdb/Fsdb_db_bin_tbl.java
Normal file
65
400_xowa/src/gplx/fsdb/Fsdb_db_bin_tbl.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_db_bin_tbl {
|
||||
public static void Create_table(Db_provider p) {Sqlite_engine_.Tbl_create(p, Tbl_name, Tbl_sql);}
|
||||
public static void Commit_all(Db_provider provider, Fsdb_db_bin_fil[] ary) {
|
||||
stmt_bldr.Init(provider);
|
||||
try {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Commit_itm(ary[i]);
|
||||
stmt_bldr.Commit();
|
||||
} finally {stmt_bldr.Rls();}
|
||||
}
|
||||
private static void Commit_itm(Fsdb_db_bin_fil itm) {
|
||||
Db_stmt stmt = stmt_bldr.Get(itm.Cmd_mode());
|
||||
switch (itm.Cmd_mode()) {
|
||||
case Db_cmd_mode.Create: stmt.Clear().Val_int_(itm.Id()) .Val_str_(itm.Url().NameAndExt()).Val_long_(itm.Bin_len()).Val_long_(itm.Bin_max()).Exec_insert(); break;
|
||||
case Db_cmd_mode.Update: stmt.Clear() .Val_str_(itm.Url().NameAndExt()).Val_long_(itm.Bin_len()).Val_long_(itm.Bin_max()).Val_int_(itm.Id()).Exec_update(); break;
|
||||
case Db_cmd_mode.Delete: stmt.Clear().Val_int_(itm.Id()).Exec_delete(); break;
|
||||
case Db_cmd_mode.Ignore: break;
|
||||
default: throw Err_.unhandled(itm.Cmd_mode());
|
||||
}
|
||||
itm.Cmd_mode_(Db_cmd_mode.Ignore);
|
||||
}
|
||||
public static Fsdb_db_bin_fil[] Select_all(Db_provider p, Io_url dir) {
|
||||
ListAdp rv = ListAdp_.new_();
|
||||
Db_qry qry = Db_qry_select.new_().From_(Tbl_name).Cols_all_().OrderBy_asc_(Fld_uid);
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = p.Exec_qry_as_rdr(qry);
|
||||
while (rdr.MoveNextPeer()) {
|
||||
Fsdb_db_bin_fil itm = Fsdb_db_bin_fil.load_(rdr, dir);
|
||||
rv.Add(itm);
|
||||
}
|
||||
} finally {rdr.Rls();}
|
||||
return (Fsdb_db_bin_fil[])rv.XtoAry(Fsdb_db_bin_fil.class);
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_db_bin", Fld_uid = "uid", Fld_url = "url", Fld_bin_len = "bin_len", Fld_bin_max = "bin_max";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_db_bin"
|
||||
, "( uid integer NOT NULL PRIMARY KEY"
|
||||
, ", url varchar(255) NOT NULL"
|
||||
, ", bin_len bigint NOT NULL"
|
||||
, ", bin_max bigint NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
private static Db_stmt_bldr stmt_bldr = new Db_stmt_bldr(Tbl_name, String_.Ary(Fld_uid), Fld_url, Fld_bin_len, Fld_bin_max);
|
||||
}
|
||||
25
400_xowa/src/gplx/fsdb/Fsdb_dir_itm.java
Normal file
25
400_xowa/src/gplx/fsdb/Fsdb_dir_itm.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_dir_itm {
|
||||
public Fsdb_dir_itm(int id, int owner, String name) {this.id = id; this.owner = owner; this.name = name;}
|
||||
public int Id() {return id;} public Fsdb_dir_itm Id_(int v) {id = v; return this;} private int id;
|
||||
public int Owner() {return owner;} public Fsdb_dir_itm Owner_(int v) {owner = v; return this;} private int owner;
|
||||
public String Name() {return name;} public Fsdb_dir_itm Name_(String v) {name = v; return this;} private String name;
|
||||
public static final Fsdb_dir_itm Null = new Fsdb_dir_itm(0, 0, "");
|
||||
}
|
||||
87
400_xowa/src/gplx/fsdb/Fsdb_dir_tbl.java
Normal file
87
400_xowa/src/gplx/fsdb/Fsdb_dir_tbl.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_dir_tbl {
|
||||
private Db_provider provider;
|
||||
private Db_stmt stmt_insert, stmt_update, stmt_select_by_name;
|
||||
public Fsdb_dir_tbl(Db_provider provider, boolean created) {
|
||||
this.provider = provider;
|
||||
if (created) Create_table();
|
||||
}
|
||||
public void Rls() {
|
||||
if (stmt_insert != null) {stmt_insert.Rls(); stmt_insert = null;}
|
||||
if (stmt_update != null) {stmt_update.Rls(); stmt_update = null;}
|
||||
if (stmt_select_by_name != null) {stmt_select_by_name.Rls(); stmt_select_by_name = null;}
|
||||
}
|
||||
public void Create_table() {
|
||||
Sqlite_engine_.Tbl_create(provider, Tbl_name, Tbl_sql);
|
||||
Sqlite_engine_.Idx_create(provider, Idx_name);
|
||||
}
|
||||
private Db_stmt Insert_stmt() {return Db_stmt_.new_insert_(provider, Tbl_name, Fld_dir_id, Fld_dir_owner_id, Fld_dir_name);}
|
||||
public void Insert(int id, String name, int owner_id) {
|
||||
if (stmt_insert == null) stmt_insert = Insert_stmt();
|
||||
try {
|
||||
stmt_insert.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_int_(owner_id)
|
||||
.Val_str_(name)
|
||||
.Exec_insert();
|
||||
} catch (Exception exc) {stmt_insert = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail
|
||||
}
|
||||
private Db_stmt Update_stmt() {return Db_stmt_.new_update_(provider, Tbl_name, String_.Ary(Fld_dir_id), Fld_dir_owner_id, Fld_dir_name);}
|
||||
public void Update(int id, String name, int owner_id) {
|
||||
if (stmt_update == null) stmt_update = Update_stmt();
|
||||
try {
|
||||
stmt_update.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_str_(name)
|
||||
.Val_int_(owner_id)
|
||||
.Exec_update();
|
||||
} catch (Exception exc) {stmt_update = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail
|
||||
}
|
||||
private Db_stmt Select_itm_stmt() {
|
||||
Db_qry qry = Db_qry_.select_().From_(Tbl_name).Cols_(Fld_dir_id, Fld_dir_owner_id).Where_(Db_crt_.eq_(Fld_dir_name, Bry_.Empty));
|
||||
return provider.Prepare(qry);
|
||||
}
|
||||
public Fsdb_dir_itm Select_itm(String dir_name) {
|
||||
if (stmt_select_by_name == null) stmt_select_by_name = Select_itm_stmt();
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = stmt_select_by_name.Clear()
|
||||
.Val_str_(dir_name)
|
||||
.Exec_select();
|
||||
while (rdr.MoveNextPeer()) {
|
||||
return new Fsdb_dir_itm(rdr.ReadInt(Fld_dir_id), rdr.ReadInt(Fld_dir_owner_id), dir_name);
|
||||
}
|
||||
return Fsdb_dir_itm.Null;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_dir", Fld_dir_id = "dir_id", Fld_dir_owner_id = "dir_owner_id", Fld_dir_name = "dir_name";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_dir"
|
||||
, "( dir_id integer NOT NULL PRIMARY KEY"
|
||||
, ", dir_owner_id integer NOT NULL"
|
||||
, ", dir_name varchar(255) NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
public static final Db_idx_itm
|
||||
Idx_name = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS fsdb_dir__name ON fsdb_dir (dir_name, dir_owner_id, dir_id);")
|
||||
;
|
||||
}
|
||||
29
400_xowa/src/gplx/fsdb/Fsdb_fil_itm.java
Normal file
29
400_xowa/src/gplx/fsdb/Fsdb_fil_itm.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_fil_itm {
|
||||
public int Id() {return id;} public Fsdb_fil_itm Id_(int v) {id = v; return this;} private int id;
|
||||
public int Owner() {return owner;} public Fsdb_fil_itm Owner_(int v) {owner = v; return this;} private int owner;
|
||||
public int Ext_id() {return ext_id;} public Fsdb_fil_itm Ext_id_(int v) {ext_id = v; return this;} private int ext_id;
|
||||
public String Name() {return name;} public Fsdb_fil_itm Name_(String v) {name = v; return this;} private String name;
|
||||
public int Db_bin_id() {return bin_db_id;} public Fsdb_fil_itm Db_bin_id_(int v) {bin_db_id = v; return this;} private int bin_db_id;
|
||||
public int Mnt_id() {return mnt_id;} public Fsdb_fil_itm Mnt_id_(int v) {mnt_id = v; return this;} private int mnt_id;
|
||||
public Fsdb_fil_itm Init(int id, int owner, int ext_id, String name, int bin_db_id) {this.id = id; this.owner = owner; this.ext_id = ext_id; this.name = name; this.bin_db_id = bin_db_id; return this;}
|
||||
public static final int Null_id = 0;
|
||||
public static final Fsdb_fil_itm Null = new Fsdb_fil_itm().Init(Null_id, 0, 0, "", Fsdb_bin_tbl.Null_db_bin_id);
|
||||
}
|
||||
134
400_xowa/src/gplx/fsdb/Fsdb_fil_tbl.java
Normal file
134
400_xowa/src/gplx/fsdb/Fsdb_fil_tbl.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_fil_tbl {
|
||||
private Db_provider provider;
|
||||
private Db_stmt stmt_insert, stmt_update, stmt_select_by_name, stmt_select_by_id;
|
||||
public Fsdb_fil_tbl(Db_provider provider, boolean created) {
|
||||
this.provider = provider;
|
||||
if (created) Create_table();
|
||||
}
|
||||
private void Create_table() {
|
||||
Sqlite_engine_.Tbl_create(provider, Tbl_name, Tbl_sql);
|
||||
Sqlite_engine_.Idx_create(provider, Idx_owner);
|
||||
}
|
||||
public void Rls() {
|
||||
if (stmt_insert != null) {stmt_insert.Rls(); stmt_insert = null;}
|
||||
if (stmt_update != null) {stmt_update.Rls(); stmt_update = null;}
|
||||
if (stmt_select_by_name != null) {stmt_select_by_name.Rls(); stmt_select_by_name = null;}
|
||||
if (stmt_select_by_id != null) {stmt_select_by_id.Rls(); stmt_select_by_id = null;}
|
||||
}
|
||||
private Db_stmt Insert_stmt() {return Db_stmt_.new_insert_(provider, Tbl_name, Fld_fil_id, Fld_fil_owner_id, Fld_fil_name, Fld_fil_xtn_id, Fld_fil_ext_id, Fld_fil_bin_db_id, Fld_fil_size, Fld_fil_modified, Fld_fil_hash);}
|
||||
public void Insert(int id, int owner_id, String name, int xtn_id, int ext_id, long size, DateAdp modified, String hash, int bin_db_id) {
|
||||
if (stmt_insert == null) stmt_insert = Insert_stmt();
|
||||
try {
|
||||
stmt_insert.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_int_(owner_id)
|
||||
.Val_str_(name)
|
||||
.Val_int_(xtn_id)
|
||||
.Val_int_(ext_id)
|
||||
.Val_int_(bin_db_id)
|
||||
.Val_long_(size)
|
||||
.Val_str_(Sqlite_engine_.X_date_to_str(modified))
|
||||
.Val_str_(hash)
|
||||
.Exec_insert();
|
||||
} catch (Exception exc) {stmt_insert = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail
|
||||
}
|
||||
private Db_stmt Update_stmt() {return Db_stmt_.new_update_(provider, Tbl_name, String_.Ary(Fld_fil_id), Fld_fil_owner_id, Fld_fil_name, Fld_fil_xtn_id, Fld_fil_ext_id, Fld_fil_bin_db_id, Fld_fil_size, Fld_fil_modified, Fld_fil_hash);}
|
||||
public void Update(int id, int owner_id, String name, int xtn_id, int ext_id, long size, DateAdp modified, String hash, int bin_db_id) {
|
||||
if (stmt_update == null) stmt_update = Update_stmt();
|
||||
try {
|
||||
stmt_update.Clear()
|
||||
.Val_int_(owner_id)
|
||||
.Val_str_(name)
|
||||
.Val_int_(xtn_id)
|
||||
.Val_int_(ext_id)
|
||||
.Val_int_(bin_db_id)
|
||||
.Val_long_(size)
|
||||
.Val_str_(Sqlite_engine_.X_date_to_str(modified))
|
||||
.Val_str_(hash)
|
||||
.Val_int_(id)
|
||||
.Exec_update();
|
||||
} catch (Exception exc) {stmt_update = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail
|
||||
}
|
||||
private Db_stmt Select_by_name_stmt() {
|
||||
Db_qry qry = Sqlite_engine_.Supports_indexed_by
|
||||
? (Db_qry)Db_qry_sql.rdr_("SELECT * FROM fsdb_fil INDEXED BY fsdb_fil__owner WHERE fil_owner_id = ? AND fil_name = ?;")
|
||||
: Db_qry_.select_().From_(Tbl_name).Cols_all_().Where_(gplx.criterias.Criteria_.And_many(Db_crt_.eq_(Fld_fil_owner_id, Int_.MinValue), Db_crt_.eq_(Fld_fil_name, "")))
|
||||
;
|
||||
return provider.Prepare(qry);
|
||||
}
|
||||
public Fsdb_fil_itm Select_itm_by_name(int dir_id, String fil_name) {
|
||||
if (stmt_select_by_name == null) stmt_select_by_name = Select_by_name_stmt();
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = stmt_select_by_name.Clear()
|
||||
.Val_int_(dir_id)
|
||||
.Val_str_(fil_name)
|
||||
.Exec_select();
|
||||
if (rdr.MoveNextPeer())
|
||||
return load_(rdr);
|
||||
else
|
||||
return Fsdb_fil_itm.Null;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
private Db_stmt Select_by_id_stmt() {
|
||||
Db_qry qry = Db_qry_.select_().From_(Tbl_name).Cols_all_().Where_(Db_crt_.eq_(Fld_fil_id, 0));
|
||||
return provider.Prepare(qry);
|
||||
}
|
||||
public Fsdb_fil_itm Select_itm_by_id(int fil_id) {
|
||||
if (stmt_select_by_id == null) stmt_select_by_id = Select_by_id_stmt();
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = stmt_select_by_name.Clear()
|
||||
.Val_int_(fil_id)
|
||||
.Exec_select();
|
||||
if (rdr.MoveNextPeer())
|
||||
return load_(rdr);
|
||||
else
|
||||
return Fsdb_fil_itm.Null;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
private Fsdb_fil_itm load_(DataRdr rdr) {
|
||||
return new Fsdb_fil_itm().Init(rdr.ReadInt(Fld_fil_id), rdr.ReadInt(Fld_fil_owner_id), rdr.ReadInt(Fld_fil_ext_id), rdr.ReadStr(Fld_fil_name), rdr.ReadInt(Fld_fil_bin_db_id));
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_fil", Fld_fil_id = "fil_id", Fld_fil_owner_id = "fil_owner_id", Fld_fil_name = "fil_name", Fld_fil_xtn_id = "fil_xtn_id", Fld_fil_ext_id = "fil_ext_id"
|
||||
, Fld_fil_size = "fil_size", Fld_fil_modified = "fil_modified", Fld_fil_hash = "fil_hash", Fld_fil_bin_db_id = "fil_bin_db_id"
|
||||
;
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_fil"
|
||||
, "( fil_id integer NOT NULL PRIMARY KEY"
|
||||
, ", fil_owner_id integer NOT NULL"
|
||||
, ", fil_xtn_id integer NOT NULL"
|
||||
, ", fil_ext_id integer NOT NULL"
|
||||
, ", fil_bin_db_id integer NOT NULL" // group ints at beginning of table
|
||||
, ", fil_name varchar(255) NOT NULL"
|
||||
, ", fil_size bigint NOT NULL"
|
||||
, ", fil_modified varchar(14) NOT NULL" // stored as yyyyMMddHHmmss
|
||||
, ", fil_hash varchar(40) NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
public static final Db_idx_itm
|
||||
// Idx_name = Db_idx_itm.sql_ ("CREATE INDEX IF NOT EXISTS fsdb_fil__name ON fsdb_fil (fil_name, fil_owner_id, fil_id, fil_ext_id);")
|
||||
Idx_owner = Db_idx_itm.sql_ ("CREATE INDEX IF NOT EXISTS fsdb_fil__owner ON fsdb_fil (fil_owner_id, fil_name, fil_id);")
|
||||
;
|
||||
}
|
||||
26
400_xowa/src/gplx/fsdb/Fsdb_mnt_itm.java
Normal file
26
400_xowa/src/gplx/fsdb/Fsdb_mnt_itm.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_mnt_itm {
|
||||
public Fsdb_mnt_itm(int id, String name, String url) {this.id = id; this.name = name; this.url = url;}
|
||||
public int Id() {return id;} public Fsdb_mnt_itm Id_(int v) {id = v; return this;} private int id;
|
||||
public String Name() {return name;} public Fsdb_mnt_itm Name_(String v) {name = v; return this;} private String name;
|
||||
public String Url() {return url;} public Fsdb_mnt_itm Url_(String v) {url = v; return this;} private String url;
|
||||
public static final Fsdb_mnt_itm Null = new Fsdb_mnt_itm(0, "", "");
|
||||
public static final Fsdb_mnt_itm[] Ary_empty = new Fsdb_mnt_itm[0];
|
||||
}
|
||||
119
400_xowa/src/gplx/fsdb/Fsdb_mnt_mgr.java
Normal file
119
400_xowa/src/gplx/fsdb/Fsdb_mnt_mgr.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*; import gplx.xowa.files.fsdb.*;
|
||||
public class Fsdb_mnt_mgr implements GfoInvkAble {
|
||||
private Db_provider provider;
|
||||
private Fsdb_cfg_tbl tbl_cfg;
|
||||
private Fsdb_db_abc_mgr[] ary; int ary_len = 0;
|
||||
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public Fsdb_mnt_mgr Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v; return this;} private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_.Null;
|
||||
public void Init(Io_url cur_dir) {
|
||||
Fsdb_mnt_itm[] mnts = Db_load_or_make(cur_dir);
|
||||
ary_len = mnts.length;
|
||||
ary = new Fsdb_db_abc_mgr[ary_len];
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
Fsdb_mnt_itm itm = mnts[i];
|
||||
Io_url abc_url = cur_dir.GenSubFil_nest(itm.Url(), "fsdb.abc.sqlite3");
|
||||
ary[i] = new Fsdb_db_abc_mgr(this).Init(abc_url.OwnerDir());
|
||||
}
|
||||
insert_to_mnt = tbl_cfg.Select_as_int_or_fail("core", "mnt.insert_idx");
|
||||
}
|
||||
public int Insert_to_mnt() {return insert_to_mnt;} public Fsdb_mnt_mgr Insert_to_mnt_(int v) {insert_to_mnt = v; return this;} private int insert_to_mnt = Mnt_idx_user;
|
||||
public int Abc_mgr_len() {return ary == null ? 0 : ary.length;}
|
||||
public Fsdb_db_abc_mgr Abc_mgr_at(int i) {return ary[i];}
|
||||
private Fsdb_mnt_itm[] Db_load_or_make(Io_url cur_dir) {
|
||||
Bool_obj_ref created = Bool_obj_ref.n_();
|
||||
provider = Sqlite_engine_.Provider_load_or_make_(cur_dir.GenSubFil("wiki.mnt.sqlite3"), created);
|
||||
tbl_cfg = new Fsdb_cfg_tbl_sql().Ctor(provider, created.Val());
|
||||
if (created.Val()) {
|
||||
Fsdb_mnt_tbl.Create_table(provider);
|
||||
Fsdb_mnt_tbl.Insert(provider, Mnt_idx_main, "fsdb.main", "fsdb.main");
|
||||
Fsdb_mnt_tbl.Insert(provider, Mnt_idx_user, "fsdb.user", "fsdb.user");
|
||||
tbl_cfg.Insert("core", "mnt.insert_idx", Int_.XtoStr(Mnt_idx_user));
|
||||
}
|
||||
return Fsdb_mnt_tbl.Select_all(provider);
|
||||
}
|
||||
public Fsdb_db_bin_fil Bin_db_get(int mnt_id, int bin_db_id) {
|
||||
return ary[mnt_id].Bin_mgr().Get_at(bin_db_id);
|
||||
}
|
||||
public Fsdb_fil_itm Fil_select_bin(byte[] dir, byte[] fil, boolean is_thumb, int width, double thumbtime) {
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
Fsdb_fil_itm rv = ary[i].Fil_select_bin(dir, fil, is_thumb, width, thumbtime);
|
||||
if (rv != Fsdb_fil_itm.Null && rv.Db_bin_id() != Fsdb_bin_tbl.Null_db_bin_id) { // NOTE: mnt_0 can have thumb, but mnt_1 can have itm; check for itm with Db_bin_id; DATE:2013-11-16
|
||||
rv.Mnt_id_(i);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return Fsdb_fil_itm.Null;
|
||||
}
|
||||
public boolean Thm_select_bin(byte[] dir, byte[] fil, Fsdb_xtn_thm_itm thm) {
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
boolean rv = ary[i].Thm_select_bin(dir, fil, thm);
|
||||
if (rv) {
|
||||
thm.Mnt_id_(i);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void Fil_insert(Fsdb_fil_itm rv , byte[] dir, byte[] fil, int ext_id, DateAdp modified, String hash, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
ary[insert_to_mnt].Fil_insert(rv, dir, fil, ext_id, modified, hash, bin_len, bin_rdr);
|
||||
}
|
||||
public void Thm_insert(Fsdb_xtn_thm_itm rv, byte[] dir, byte[] fil, int ext_id, int w, int h, double thumbtime, int page, DateAdp modified, String hash, long bin_len, gplx.ios.Io_stream_rdr bin_rdr) {
|
||||
ary[insert_to_mnt].Thm_insert(rv, dir, fil, ext_id, w, h, thumbtime, page, modified, hash, bin_len, bin_rdr);
|
||||
}
|
||||
public void Img_insert(Fsdb_xtn_img_itm rv, byte[] dir, byte[] fil, int ext_id, DateAdp modified, String hash, long bin_len, gplx.ios.Io_stream_rdr bin_rdr, int img_w, int img_h) {
|
||||
ary[insert_to_mnt].Img_insert(rv, dir, fil, ext_id, modified, hash, bin_len, bin_rdr, img_w, img_h);
|
||||
}
|
||||
public void Bin_db_max_(long v) {
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i].Bin_mgr().Db_bin_max_(v);
|
||||
}
|
||||
public void Insert_to_bin_(int v) {
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i].Bin_mgr().Insert_to_bin_(v);
|
||||
}
|
||||
public void Txn_open() {
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i].Txn_open();
|
||||
}
|
||||
public void Txn_save() {
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i].Txn_save();
|
||||
}
|
||||
public void Rls() {
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i].Rls();
|
||||
tbl_cfg.Rls();
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_bin_db_max_in_mb_)) this.Bin_db_max_(m.ReadLong("v") * Io_mgr.Len_mb);
|
||||
else if (ctx.Match(k, Invk_insert_to_mnt_)) insert_to_mnt = m.ReadInt("v");
|
||||
else if (ctx.Match(k, Invk_insert_to_bin_)) this.Insert_to_bin_(m.ReadInt("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_bin_db_max_in_mb_ = "bin_db_max_in_mb_", Invk_insert_to_mnt_ = "insert_to_mnt_", Invk_insert_to_bin_ = "insert_to_bin_";
|
||||
public static final int Mnt_idx_main = 0, Mnt_idx_user = 1, Insert_to_bin_null = -1;
|
||||
public static void Patch(Fsdb_mnt_mgr mnt_mgr) {
|
||||
mnt_mgr.Abc_mgr_at(Fsdb_mnt_mgr.Mnt_idx_main).Cfg_mgr()
|
||||
.Update(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_gallery_fix_defaults, "y")
|
||||
.Update(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_gallery_packed, "y")
|
||||
.Update(Xof_fsdb_mgr_cfg.Grp_xowa, Xof_fsdb_mgr_cfg.Key_upright_patch, "y")
|
||||
;
|
||||
}
|
||||
}
|
||||
67
400_xowa/src/gplx/fsdb/Fsdb_mnt_tbl.java
Normal file
67
400_xowa/src/gplx/fsdb/Fsdb_mnt_tbl.java
Normal file
@@ -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.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_mnt_tbl {
|
||||
public static void Create_table(Db_provider p) {
|
||||
Sqlite_engine_.Tbl_create(p, Tbl_name, Tbl_sql);
|
||||
}
|
||||
public static void Insert(Db_provider p, int id, String name, String url) {
|
||||
Db_stmt stmt = Insert_stmt(p);
|
||||
try {Insert(stmt, id, name, url);}
|
||||
finally {stmt.Rls();}
|
||||
}
|
||||
private static Db_stmt Insert_stmt(Db_provider p) {return Db_stmt_.new_insert_(p, Tbl_name, Fld_mnt_id, Fld_mnt_name, Fld_mnt_url);}
|
||||
private static void Insert(Db_stmt stmt, int id, String name, String url) {
|
||||
stmt.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_str_(name)
|
||||
.Val_str_(url)
|
||||
.Exec_insert();
|
||||
}
|
||||
public static Db_stmt Update_stmt(Db_provider p) {return Db_stmt_.new_update_(p, Tbl_name, String_.Ary(Fld_mnt_id), Fld_mnt_name, Fld_mnt_url);}
|
||||
public static void Update(Db_stmt stmt, int id, String name, String url) {
|
||||
stmt.Clear()
|
||||
.Val_str_(name)
|
||||
.Val_str_(url)
|
||||
.Val_int_(id)
|
||||
.Exec_update();
|
||||
}
|
||||
public static Fsdb_mnt_itm[] Select_all(Db_provider p) {
|
||||
Db_qry qry = Db_qry_.select_().From_(Tbl_name);
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
ListAdp list = ListAdp_.new_();
|
||||
try {
|
||||
rdr = p.Exec_qry_as_rdr(qry);
|
||||
while (rdr.MoveNextPeer()) {
|
||||
Fsdb_mnt_itm itm = new Fsdb_mnt_itm(rdr.ReadInt(Fld_mnt_id), rdr.ReadStr(Fld_mnt_name), rdr.ReadStr(Fld_mnt_url));
|
||||
list.Add(itm);
|
||||
}
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
return (Fsdb_mnt_itm[])list.XtoAryAndClear(Fsdb_mnt_itm.class);
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_mnt", Fld_mnt_id = "mnt_id", Fld_mnt_name = "mnt_name", Fld_mnt_url = "mnt_url";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_mnt"
|
||||
, "( mnt_id integer NOT NULL PRIMARY KEY"
|
||||
, ", mnt_name varchar(255) NOT NULL"
|
||||
, ", mnt_url varchar(255) NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
}
|
||||
27
400_xowa/src/gplx/fsdb/Fsdb_xtn_img_itm.java
Normal file
27
400_xowa/src/gplx/fsdb/Fsdb_xtn_img_itm.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_xtn_img_itm {
|
||||
public int Id() {return id;} public void Id_(int v) {this.id = v;} private int id;
|
||||
public int W() {return w;} public void W_(int v) {this.w = v;} private int w;
|
||||
public int H() {return h;} public void H_(int v) {this.h = v;} private int h;
|
||||
public int Db_bin_id() {return bin_db_id;} public Fsdb_xtn_img_itm Db_bin_id_(int v) {bin_db_id = v; return this;} private int bin_db_id;
|
||||
public Fsdb_xtn_img_itm Init_by_load(int id, int w, int h) {this.id = id; this.w = w; this.h = h; return this;}
|
||||
public static final Fsdb_xtn_img_itm Null = new Fsdb_xtn_img_itm();
|
||||
public static final int Bits_default = 8;
|
||||
}
|
||||
68
400_xowa/src/gplx/fsdb/Fsdb_xtn_img_tbl.java
Normal file
68
400_xowa/src/gplx/fsdb/Fsdb_xtn_img_tbl.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_xtn_img_tbl {
|
||||
private Db_provider provider;
|
||||
private Db_stmt stmt_insert, stmt_select_by_id;
|
||||
public Fsdb_xtn_img_tbl(Db_provider provider, boolean created) {
|
||||
this.provider = provider;
|
||||
if (created) Create_table();
|
||||
}
|
||||
public void Rls() {
|
||||
if (stmt_insert != null) {stmt_insert.Rls(); stmt_insert = null;}
|
||||
if (stmt_select_by_id != null) {stmt_select_by_id.Rls(); stmt_select_by_id = null;}
|
||||
}
|
||||
public void Create_table() {
|
||||
Sqlite_engine_.Tbl_create(provider, Tbl_name, Tbl_sql);
|
||||
}
|
||||
public Db_stmt Insert_stmt() {return Db_stmt_.new_insert_(provider, Tbl_name, Fld_img_id, Fld_img_w, Fld_img_h);}
|
||||
public void Insert(int id, int w, int h) {
|
||||
if (stmt_insert == null) stmt_insert = Insert_stmt();
|
||||
try {
|
||||
stmt_insert.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_int_(w)
|
||||
.Val_int_(h)
|
||||
.Exec_insert();
|
||||
} catch (Exception exc) {stmt_insert = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail
|
||||
}
|
||||
public Db_stmt Select_itm_by_id_stmt() {return Db_stmt_.new_select_(provider, Tbl_name, String_.Ary(Fld_img_id), Fld_img_w, Fld_img_h); }
|
||||
public Fsdb_xtn_img_itm Select_itm_by_id(int id) {
|
||||
if (stmt_select_by_id == null) stmt_select_by_id = this.Select_itm_by_id_stmt();
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
rdr = stmt_select_by_id.Clear()
|
||||
.Val_int_(id)
|
||||
.Exec_select();
|
||||
if (rdr.MoveNextPeer())
|
||||
return new Fsdb_xtn_img_itm().Init_by_load(id, rdr.ReadInt(Fld_img_w), rdr.ReadInt(Fld_img_h));
|
||||
else
|
||||
return Fsdb_xtn_img_itm.Null;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_xtn_img", Fld_img_id = "img_id", Fld_img_w = "img_w", Fld_img_h = "img_h";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_xtn_img"
|
||||
, "( img_id integer NOT NULL PRIMARY KEY"
|
||||
, ", img_w integer NOT NULL"
|
||||
, ", img_h integer NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
}
|
||||
56
400_xowa/src/gplx/fsdb/Fsdb_xtn_thm_itm.java
Normal file
56
400_xowa/src/gplx/fsdb/Fsdb_xtn_thm_itm.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_xtn_thm_itm {
|
||||
protected Fsdb_xtn_thm_itm() {}
|
||||
public int Id() {return id;} public Fsdb_xtn_thm_itm Id_(int v) {id = v; return this;} private int id;
|
||||
public Fsdb_fil_itm Owner() {return owner;} public Fsdb_xtn_thm_itm Owner_(Fsdb_fil_itm v) {owner = v; return this;} private Fsdb_fil_itm owner = Fsdb_fil_itm.Null;
|
||||
public int Owner_id() {return owner_id;} public Fsdb_xtn_thm_itm Owner_id_(int v) {owner_id = v; return this;} private int owner_id;
|
||||
public int Width() {return width;} public Fsdb_xtn_thm_itm Width_(int v) {width = v; return this;} private int width;
|
||||
public double Thumbtime() {return thumbtime;} public Fsdb_xtn_thm_itm Thumbtime_(double v) {thumbtime = v; return this;} private double thumbtime;
|
||||
public int Page() {return page;} public Fsdb_xtn_thm_itm Page_(int v) {page = v; return this;} private int page;
|
||||
public int Height() {return height;} public Fsdb_xtn_thm_itm Height_(int v) {height = v; return this;} private int height;
|
||||
public long Size() {return size;} public Fsdb_xtn_thm_itm Size_(long v) {size = v; return this;} private long size;
|
||||
public String Modified() {return modified;} public Fsdb_xtn_thm_itm Modified_(String v) {modified = v; return this;} private String modified;
|
||||
public String Hash() {return hash;} public Fsdb_xtn_thm_itm Hash_(String v) {hash = v; return this;} private String hash;
|
||||
public int Dir_id() {return dir_id;} public Fsdb_xtn_thm_itm Dir_id_(int v) {dir_id = v; return this;} private int dir_id;
|
||||
public int Db_bin_id() {return bin_db_id;} public Fsdb_xtn_thm_itm Db_bin_id_(int v) {bin_db_id = v; return this;} private int bin_db_id;
|
||||
public int Mnt_id() {return mnt_id;} public Fsdb_xtn_thm_itm Mnt_id_(int v) {mnt_id = v; return this;} private int mnt_id;
|
||||
public void Init_by_load(DataRdr rdr, boolean schema_thm_page) {
|
||||
this.id = rdr.ReadInt(Fsdb_xtn_thm_tbl.Fld_thm_id);
|
||||
this.owner_id = rdr.ReadInt(Fsdb_xtn_thm_tbl.Fld_thm_owner_id);
|
||||
this.width = rdr.ReadInt(Fsdb_xtn_thm_tbl.Fld_thm_w);
|
||||
this.height = rdr.ReadInt(Fsdb_xtn_thm_tbl.Fld_thm_h);
|
||||
this.size = rdr.ReadLong(Fsdb_xtn_thm_tbl.Fld_thm_size);
|
||||
this.modified = rdr.ReadStr(Fsdb_xtn_thm_tbl.Fld_thm_modified);
|
||||
this.hash = rdr.ReadStr(Fsdb_xtn_thm_tbl.Fld_thm_hash);
|
||||
this.bin_db_id = rdr.ReadInt(Fsdb_xtn_thm_tbl.Fld_thm_bin_db_id);
|
||||
if (schema_thm_page) {
|
||||
this.thumbtime = gplx.xowa.files.Xof_doc_thumb.Db_load_double(rdr, Fsdb_xtn_thm_tbl.Fld_thm_time);
|
||||
this.page = gplx.xowa.files.Xof_doc_page.Db_load_int(rdr, Fsdb_xtn_thm_tbl.Fld_thm_page);
|
||||
}
|
||||
else {
|
||||
this.thumbtime = gplx.xowa.files.Xof_doc_thumb.Db_load_int(rdr, Fsdb_xtn_thm_tbl.Fld_thm_thumbtime);
|
||||
this.page = gplx.xowa.files.Xof_doc_page.Null;
|
||||
}
|
||||
}
|
||||
public static Fsdb_xtn_thm_itm new_() {return new Fsdb_xtn_thm_itm();} // NOTE: Owner is null by default
|
||||
public static Fsdb_xtn_thm_itm load_() {return new Fsdb_xtn_thm_itm().Owner_(new Fsdb_fil_itm());} // NOTE: Owner is new'd b/c load will use owner.Ext_id
|
||||
public static final Fsdb_xtn_thm_itm Null = new Fsdb_xtn_thm_itm();
|
||||
public static final Fsdb_xtn_thm_itm[] Ary_empty = new Fsdb_xtn_thm_itm[0];
|
||||
}
|
||||
128
400_xowa/src/gplx/fsdb/Fsdb_xtn_thm_tbl.java
Normal file
128
400_xowa/src/gplx/fsdb/Fsdb_xtn_thm_tbl.java
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
import gplx.dbs.*;
|
||||
public class Fsdb_xtn_thm_tbl {
|
||||
private Fsdb_db_atr_fil atr_fil; private Db_provider provider;
|
||||
private Db_stmt stmt_insert, stmt_select_by_fil_w;
|
||||
public Fsdb_xtn_thm_tbl(Fsdb_db_atr_fil atr_fil, Db_provider provider, boolean created) {
|
||||
this.atr_fil = atr_fil; this.provider = provider;
|
||||
if (created) Create_table();
|
||||
}
|
||||
private void Create_table() {
|
||||
Sqlite_engine_.Tbl_create(provider, Tbl_name, Tbl_sql);
|
||||
Sqlite_engine_.Idx_create(provider, Idx_name);
|
||||
}
|
||||
public void Rls() {
|
||||
if (stmt_insert != null) {stmt_insert.Rls(); stmt_insert = null;}
|
||||
if (stmt_select_by_fil_w != null) {stmt_select_by_fil_w.Rls(); stmt_select_by_fil_w = null;}
|
||||
}
|
||||
private boolean Schema_thm_page() {
|
||||
if (schema_thm_page_init) {
|
||||
schema_thm_page = atr_fil.Abc_mgr().Cfg_mgr().Schema_thm_page();
|
||||
schema_thm_page_init = false;
|
||||
}
|
||||
return schema_thm_page;
|
||||
} private boolean schema_thm_page, schema_thm_page_init = true;
|
||||
private Db_stmt Make_stmt_insert() {
|
||||
return this.Schema_thm_page()
|
||||
? Db_stmt_.new_insert_(provider, Tbl_name, Fld_thm_id, Fld_thm_owner_id, Fld_thm_w, Fld_thm_h, Fld_thm_bin_db_id, Fld_thm_size, Fld_thm_modified, Fld_thm_hash, Fld_thm_time, Fld_thm_page)
|
||||
: Db_stmt_.new_insert_(provider, Tbl_name, Fld_thm_id, Fld_thm_owner_id, Fld_thm_w, Fld_thm_h, Fld_thm_bin_db_id, Fld_thm_size, Fld_thm_modified, Fld_thm_hash, Fld_thm_thumbtime)
|
||||
;
|
||||
}
|
||||
public void Insert(int id, int thm_owner_id, int width, int height, double thumbtime, int page, int bin_db_id, long size, DateAdp modified, String hash) {
|
||||
if (stmt_insert == null) stmt_insert = Make_stmt_insert();
|
||||
try {
|
||||
stmt_insert.Clear()
|
||||
.Val_int_(id)
|
||||
.Val_int_(thm_owner_id)
|
||||
.Val_int_(width)
|
||||
.Val_int_(height)
|
||||
.Val_int_(bin_db_id)
|
||||
.Val_long_(size)
|
||||
.Val_str_(Sqlite_engine_.X_date_to_str(modified))
|
||||
.Val_str_(hash);
|
||||
if (this.Schema_thm_page()) {
|
||||
stmt_insert.Val_double_ (gplx.xowa.files.Xof_doc_thumb.Db_save_double(thumbtime));
|
||||
stmt_insert.Val_int_ (gplx.xowa.files.Xof_doc_page.Db_save_int(page));
|
||||
}
|
||||
else
|
||||
stmt_insert.Val_int_(gplx.xowa.files.Xof_doc_thumb.Db_save_int(thumbtime));
|
||||
stmt_insert.Exec_insert();
|
||||
} catch (Exception exc) {stmt_insert = null; throw Err_.err_(exc, "stmt failed");} // must reset stmt, else next call will fail
|
||||
}
|
||||
private Db_stmt Select_by_fil_w_stmt() {
|
||||
Db_qry_select qry = Db_qry_.select_().From_(Tbl_name).Cols_all_();
|
||||
gplx.criterias.Criteria crt
|
||||
= this.Schema_thm_page()
|
||||
? gplx.criterias.Criteria_.And_many(Db_crt_.eq_(Fld_thm_owner_id, Int_.MinValue), Db_crt_.eq_(Fld_thm_w, Int_.MinValue), Db_crt_.eq_(Fld_thm_time, Int_.MinValue), Db_crt_.eq_(Fld_thm_page, Int_.MinValue))
|
||||
: gplx.criterias.Criteria_.And_many(Db_crt_.eq_(Fld_thm_owner_id, Int_.MinValue), Db_crt_.eq_(Fld_thm_w, Int_.MinValue), Db_crt_.eq_(Fld_thm_thumbtime, Int_.MinValue))
|
||||
;
|
||||
qry.Where_(crt);
|
||||
return provider.Prepare(qry);
|
||||
}
|
||||
public boolean Select_itm_by_fil_width(int owner_id, Fsdb_xtn_thm_itm thm) {
|
||||
if (stmt_select_by_fil_w == null) stmt_select_by_fil_w = Select_by_fil_w_stmt();
|
||||
DataRdr rdr = DataRdr_.Null;
|
||||
try {
|
||||
stmt_select_by_fil_w.Clear()
|
||||
.Val_int_(owner_id)
|
||||
.Val_int_(thm.Width())
|
||||
;
|
||||
if (this.Schema_thm_page()) {
|
||||
stmt_select_by_fil_w.Val_double_(gplx.xowa.files.Xof_doc_thumb.Db_save_double(thm.Thumbtime()));
|
||||
stmt_select_by_fil_w.Val_int_(gplx.xowa.files.Xof_doc_page.Db_save_int(thm.Page()));
|
||||
}
|
||||
else {
|
||||
stmt_select_by_fil_w.Val_int_(gplx.xowa.files.Xof_doc_thumb.Db_save_int(thm.Thumbtime()));
|
||||
}
|
||||
rdr = stmt_select_by_fil_w.Exec_select();
|
||||
if (rdr.MoveNextPeer()) {
|
||||
thm.Init_by_load(rdr, this.Schema_thm_page());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
finally {rdr.Rls();}
|
||||
}
|
||||
public static final String Tbl_name = "fsdb_xtn_thm"
|
||||
, Fld_thm_id = "thm_id", Fld_thm_owner_id = "thm_owner_id", Fld_thm_w = "thm_w", Fld_thm_h = "thm_h"
|
||||
, Fld_thm_thumbtime = "thm_thumbtime", Fld_thm_time = "thm_time", Fld_thm_page = "thm_page"
|
||||
, Fld_thm_bin_db_id = "thm_bin_db_id", Fld_thm_size = "thm_size", Fld_thm_modified = "thm_modified", Fld_thm_hash = "thm_hash";
|
||||
private static final String Tbl_sql = String_.Concat_lines_nl
|
||||
( "CREATE TABLE IF NOT EXISTS fsdb_xtn_thm"
|
||||
, "( thm_id integer NOT NULL PRIMARY KEY"
|
||||
, ", thm_owner_id integer NOT NULL"
|
||||
, ", thm_w integer NOT NULL"
|
||||
, ", thm_h integer NOT NULL"
|
||||
//, ", thm_thumbtime integer NOT NULL" // removed; DATE:2014-01-23
|
||||
, ", thm_time double NOT NULL" // replacement for thm_time
|
||||
, ", thm_page integer NOT NULL"
|
||||
, ", thm_bin_db_id integer NOT NULL"
|
||||
, ", thm_size bigint NOT NULL"
|
||||
, ", thm_modified varchar(14) NOT NULL" // stored as yyyyMMddHHmmss
|
||||
, ", thm_hash varchar(40) NOT NULL"
|
||||
, ");"
|
||||
);
|
||||
public static final Db_idx_itm
|
||||
Idx_name = Db_idx_itm.sql_("CREATE INDEX IF NOT EXISTS fsdb_xtn_thm__owner ON fsdb_xtn_thm (thm_owner_id, thm_id, thm_w, thm_time, thm_page);")
|
||||
;
|
||||
public static final DateAdp Modified_null = null;
|
||||
public static final String Hash_null = "";
|
||||
}
|
||||
21
400_xowa/src/gplx/fsdb/Fsdb_xtn_tid_.java
Normal file
21
400_xowa/src/gplx/fsdb/Fsdb_xtn_tid_.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.fsdb; import gplx.*;
|
||||
public class Fsdb_xtn_tid_ {
|
||||
public static final int Tid_none = 0, Tid_thm = 1, Tid_img = 2;
|
||||
}
|
||||
214
400_xowa/src/gplx/gfs/Gfs_lxr.java
Normal file
214
400_xowa/src/gplx/gfs/Gfs_lxr.java
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
interface Gfs_lxr {
|
||||
byte Lxr_tid();
|
||||
int Process(Gfs_parser_ctx ctx, int bgn, int end);
|
||||
}
|
||||
class Gfs_lxr_whitespace implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_whitespace;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
byte[] src = ctx.Src(); int src_len = ctx.Src_len();
|
||||
int rv = Gfs_lxr_.Rv_eos, cur_pos;
|
||||
for (cur_pos = end; cur_pos < src_len; cur_pos++) {
|
||||
byte b = src[cur_pos];
|
||||
Object o = ctx.Trie().Match(b, src, cur_pos, src_len);
|
||||
if (o == null) {
|
||||
rv = Gfs_lxr_.Rv_null;
|
||||
ctx.Process_null(cur_pos);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Gfs_lxr lxr = (Gfs_lxr)o;
|
||||
if (lxr.Lxr_tid() == Gfs_lxr_.Tid_whitespace) {}
|
||||
else {
|
||||
rv = Gfs_lxr_.Rv_lxr;
|
||||
ctx.Process_lxr(cur_pos, lxr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static final Gfs_lxr_whitespace _ = new Gfs_lxr_whitespace(); Gfs_lxr_whitespace() {}
|
||||
}
|
||||
class Gfs_lxr_comment_flat implements Gfs_lxr {
|
||||
public Gfs_lxr_comment_flat(byte[] bgn_bry, byte[] end_bry) {
|
||||
this.bgn_bry = bgn_bry; this.bgn_bry_len = bgn_bry.length;
|
||||
this.end_bry = end_bry; this.end_bry_len = end_bry.length;
|
||||
} byte[] bgn_bry, end_bry; int bgn_bry_len, end_bry_len;
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_comment;}
|
||||
public int Process(Gfs_parser_ctx ctx, int lxr_bgn, int lxr_end) {
|
||||
byte[] src = ctx.Src(); int src_len = ctx.Src_len();
|
||||
int end_pos = Bry_finder.Find_fwd(src, end_bry, lxr_end, src_len);
|
||||
// if (end_pos == Bry_.NotFound) throw Err_.new_fmt_("comment is not closed: {0}", String_.new_utf8_(end_bry));
|
||||
return (end_pos == Bry_.NotFound)
|
||||
? src_len // allow eos to terminate flat comment; needed for "tidy-always-adds-nl-in-textarea" fix; NOTE: DATE:2014-06-21
|
||||
: end_pos + end_bry_len; // position after end_bry
|
||||
}
|
||||
}
|
||||
class Gfs_lxr_identifier implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_identifier;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
byte[] src = ctx.Src(); int src_len = ctx.Src_len();
|
||||
int pos, rv = Gfs_lxr_.Rv_eos;
|
||||
for (pos = end; pos < src_len; pos++) {
|
||||
byte b = src[pos];
|
||||
Object o = ctx.Trie().Match(b, src, pos, src_len);
|
||||
if (o == null) { // invalid char; stop;
|
||||
rv = Gfs_lxr_.Rv_null;
|
||||
ctx.Process_null(pos);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Gfs_lxr lxr = (Gfs_lxr)o;
|
||||
if (lxr.Lxr_tid() == Gfs_lxr_.Tid_identifier) {} // still an identifier; continue
|
||||
else { // new lxr (EX: "." in "abc."); (a) hold word of "abc"; mark "." as new lxr;
|
||||
ctx.Hold_word(bgn, pos);
|
||||
rv = Gfs_lxr_.Rv_lxr;
|
||||
ctx.Process_lxr(pos, lxr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rv == Gfs_lxr_.Rv_eos) ctx.Process_eos(); // eos
|
||||
return rv;
|
||||
}
|
||||
public static final Gfs_lxr_identifier _ = new Gfs_lxr_identifier(); Gfs_lxr_identifier() {}
|
||||
}
|
||||
class Gfs_lxr_semic implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_semic;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_identifier: ctx.Make_nde(bgn, end); ctx.Cur_nde_from_stack(); break; // a;
|
||||
case Gfs_lxr_.Tid_quote:
|
||||
case Gfs_lxr_.Tid_paren_end: ctx.Cur_nde_from_stack(); break; // a();
|
||||
case Gfs_lxr_.Tid_semic: break; // a;; ignore;
|
||||
default: ctx.Err_mgr().Fail_invalid_lxr(ctx, bgn, this.Lxr_tid(), Byte_ascii.Semic); break;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_semic _ = new Gfs_lxr_semic(); Gfs_lxr_semic() {}
|
||||
}
|
||||
class Gfs_lxr_dot implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_dot;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_identifier: ctx.Make_nde(bgn, end); break; // a.
|
||||
case Gfs_lxr_.Tid_paren_end: break; // a().
|
||||
default: ctx.Err_mgr().Fail_invalid_lxr(ctx, bgn, this.Lxr_tid(), Byte_ascii.Dot); break;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_dot _ = new Gfs_lxr_dot(); Gfs_lxr_dot() {}
|
||||
}
|
||||
class Gfs_lxr_paren_bgn implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_paren_bgn;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_identifier: ctx.Make_nde(bgn, end); break; // a(;
|
||||
default: ctx.Err_mgr().Fail_invalid_lxr(ctx, bgn, this.Lxr_tid(), Byte_ascii.Paren_bgn); break;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_paren_bgn _ = new Gfs_lxr_paren_bgn(); Gfs_lxr_paren_bgn() {}
|
||||
}
|
||||
class Gfs_lxr_paren_end implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_paren_end;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_paren_bgn:
|
||||
case Gfs_lxr_.Tid_quote: break; // "))", "abc)", "'abc')"
|
||||
case Gfs_lxr_.Tid_identifier: ctx.Make_atr_by_idf(); break; // 123)
|
||||
default: ctx.Err_mgr().Fail_invalid_lxr(ctx, bgn, this.Lxr_tid(), Byte_ascii.Paren_end); break;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_paren_end _ = new Gfs_lxr_paren_end(); Gfs_lxr_paren_end() {}
|
||||
}
|
||||
class Gfs_lxr_quote implements Gfs_lxr {
|
||||
public Gfs_lxr_quote(byte[] bgn_bry, byte[] end_bry) {
|
||||
this.bgn_bry_len = bgn_bry.length;
|
||||
this.end_bry = end_bry; this.end_bry_len = end_bry.length;
|
||||
} private byte[] end_bry; private int bgn_bry_len, end_bry_len;
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_quote;}
|
||||
public int Process(Gfs_parser_ctx ctx, int lxr_bgn, int lxr_end) {
|
||||
byte[] src = ctx.Src(); int src_len = ctx.Src_len();
|
||||
int end_pos = Bry_finder.Find_fwd(src, end_bry, lxr_end, src_len);
|
||||
if (end_pos == Bry_.NotFound) throw Err_.new_fmt_("quote is not closed: {0}", String_.new_utf8_(end_bry));
|
||||
Bry_bfr bfr = ctx.Tmp_bfr().Clear();
|
||||
int prv_pos = lxr_end;
|
||||
int nxt_pos = end_pos + end_bry_len;
|
||||
if (Bry_.Match(src, nxt_pos, nxt_pos + end_bry_len, end_bry)) { // end_bry is doubled; EX: end_bry = ' and raw = a''
|
||||
while (true) {
|
||||
bfr.Add_mid(src, prv_pos, end_pos); // add everything up to end_bry
|
||||
bfr.Add(end_bry); // add end_bry
|
||||
prv_pos = nxt_pos + end_bry_len; // set prv_pos to after doubled end_bry
|
||||
end_pos = Bry_finder.Find_fwd(src, end_bry, prv_pos, src_len);
|
||||
if (end_pos == Bry_.NotFound) throw Err_.new_fmt_("quote is not closed: {0}", String_.new_utf8_(end_bry));
|
||||
nxt_pos = end_pos + end_bry_len;
|
||||
if (!Bry_.Match(src, nxt_pos, nxt_pos + end_bry_len, end_bry)) {
|
||||
bfr.Add_mid(src, prv_pos, end_pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctx.Make_atr_by_bry(lxr_bgn + bgn_bry_len, end_pos, bfr.XtoAryAndClear());
|
||||
}
|
||||
else
|
||||
ctx.Make_atr(lxr_bgn + bgn_bry_len, end_pos);
|
||||
return end_pos + end_bry_len; // position after quote
|
||||
}
|
||||
}
|
||||
class Gfs_lxr_curly_bgn implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_curly_bgn;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_identifier: ctx.Make_nde(bgn, end); ctx.Stack_add(); break; // a{;
|
||||
case Gfs_lxr_.Tid_paren_end: ctx.Stack_add(); break; // a(){; NOTE: node exists but needs to be pushed onto stack
|
||||
default: ctx.Err_mgr().Fail_invalid_lxr(ctx, bgn, this.Lxr_tid(), Byte_ascii.Curly_bgn); break;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_curly_bgn _ = new Gfs_lxr_curly_bgn(); Gfs_lxr_curly_bgn() {}
|
||||
}
|
||||
class Gfs_lxr_curly_end implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_curly_end;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
ctx.Stack_pop(bgn);
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_curly_end _ = new Gfs_lxr_curly_end(); Gfs_lxr_curly_end() {}
|
||||
}
|
||||
class Gfs_lxr_equal implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_eq;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
ctx.Make_nde(bgn, end).Op_tid_(Gfs_nde.Op_tid_assign);
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_equal _ = new Gfs_lxr_equal(); Gfs_lxr_equal() {}
|
||||
}
|
||||
class Gfs_lxr_comma implements Gfs_lxr {
|
||||
public byte Lxr_tid() {return Gfs_lxr_.Tid_comma;}
|
||||
public int Process(Gfs_parser_ctx ctx, int bgn, int end) {
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_identifier: ctx.Make_atr_by_idf(); break; // 123,
|
||||
}
|
||||
return end;
|
||||
}
|
||||
public static final Gfs_lxr_comma _ = new Gfs_lxr_comma(); Gfs_lxr_comma() {}
|
||||
}
|
||||
39
400_xowa/src/gplx/gfs/Gfs_lxr_.java
Normal file
39
400_xowa/src/gplx/gfs/Gfs_lxr_.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
class Gfs_lxr_ {
|
||||
public static final int Rv_init = -1, Rv_null = -2, Rv_eos = -3, Rv_lxr = -4;
|
||||
public static final byte Tid_identifier = 1, Tid_dot = 2, Tid_semic = 3, Tid_paren_bgn = 4, Tid_paren_end = 5, Tid_curly_bgn = 6, Tid_curly_end = 7, Tid_quote = 8, Tid_comma = 9, Tid_whitespace = 10, Tid_comment = 11, Tid_eq = 12;
|
||||
public static String Tid__name(byte tid) {
|
||||
switch (tid) {
|
||||
case Tid_identifier: return "identifier";
|
||||
case Tid_dot: return "dot";
|
||||
case Tid_semic: return "semic";
|
||||
case Tid_paren_bgn: return "paren_bgn";
|
||||
case Tid_paren_end: return "paren_end";
|
||||
case Tid_curly_bgn: return "curly_bgn";
|
||||
case Tid_curly_end: return "curly_end";
|
||||
case Tid_quote: return "quote";
|
||||
case Tid_comma: return "comma";
|
||||
case Tid_whitespace: return "whitespace";
|
||||
case Tid_comment: return "comment";
|
||||
case Tid_eq: return "eq";
|
||||
default: throw Err_.unhandled(tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
400_xowa/src/gplx/gfs/Gfs_msg_bldr.java
Normal file
49
400_xowa/src/gplx/gfs/Gfs_msg_bldr.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
public class Gfs_msg_bldr implements GfoMsgParser {
|
||||
Gfs_parser parser = new Gfs_parser();
|
||||
public GfoMsg ParseToMsg(String s) {return Bld(s);}
|
||||
public GfoMsg Bld(String src) {return Bld(Bry_.new_utf8_(src));}
|
||||
public GfoMsg Bld(byte[] src) {
|
||||
Gfs_nde nde = parser.Parse(src);
|
||||
return Bld_msg(src, nde);
|
||||
}
|
||||
GfoMsg Bld_msg(byte[] src, Gfs_nde nde) {
|
||||
boolean op_is_assign = (nde.Op_tid() == Gfs_nde.Op_tid_assign);
|
||||
String name = String_.new_utf8_(nde.Name_bry(src));
|
||||
if (op_is_assign) name += Tkn_mutator;
|
||||
GfoMsg rv = GfoMsg_.new_parse_(name);
|
||||
int len = nde.Atrs_len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfs_nde atr = nde.Atrs_get_at(i);
|
||||
rv.Add("", String_.new_utf8_(atr.Name_bry(src)));
|
||||
}
|
||||
len = nde.Subs_len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfs_nde sub = nde.Subs_get_at(i);
|
||||
if (op_is_assign) // NOTE: for now (a) assignss cannot be nested; EX: "a.b = c;" is okay but "a.b = c.d;" is not
|
||||
rv.Add("", Bld_msg(src, sub).Key());
|
||||
else
|
||||
rv.Subs_add(Bld_msg(src, sub));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static final Gfs_msg_bldr _ = new Gfs_msg_bldr(); Gfs_msg_bldr() {}
|
||||
public static final String Tkn_mutator = "_";
|
||||
}
|
||||
76
400_xowa/src/gplx/gfs/Gfs_msg_bldr_tst.java
Normal file
76
400_xowa/src/gplx/gfs/Gfs_msg_bldr_tst.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Gfs_msg_bldr_tst {
|
||||
@Before public void init() {fxt.Clear();} Gfs_msg_bldr_fxt fxt = new Gfs_msg_bldr_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test_build("a;", fxt.msg_("a"));
|
||||
}
|
||||
@Test public void Dot() {
|
||||
fxt.Test_build("a.b.c;"
|
||||
, fxt.msg_("a").Subs_
|
||||
( fxt.msg_("b").Subs_
|
||||
( fxt.msg_("c")
|
||||
)));
|
||||
}
|
||||
@Test public void Args() {
|
||||
fxt.Test_build("a('b', 'c');", fxt.msg_("a", fxt.kv_("", "b"), fxt.kv_("", "c")));
|
||||
}
|
||||
@Test public void Args_num() {
|
||||
fxt.Test_build("a(1);", fxt.msg_("a", fxt.kv_("", "1")));
|
||||
}
|
||||
@Test public void Assign() {
|
||||
fxt.Test_build("a = 'b';", fxt.msg_("a_", fxt.kv_("", "b")));
|
||||
}
|
||||
@Test public void Assign_num() {
|
||||
fxt.Test_build("a = 1;", fxt.msg_("a_", fxt.kv_("", "1")));
|
||||
}
|
||||
}
|
||||
class Gfs_msg_bldr_fxt {
|
||||
public void Clear() {} String_bldr sb = String_bldr_.new_(); Gfs_msg_bldr msg_bldr = Gfs_msg_bldr._;
|
||||
public KeyVal kv_(String key, String val) {return KeyVal_.new_(key, val);}
|
||||
public GfoMsg msg_(String key, KeyVal... args) {
|
||||
GfoMsg rv = GfoMsg_.new_parse_(key);
|
||||
int len = args.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
KeyVal kv = args[i];
|
||||
rv.Add(kv.Key(), kv.Val());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public void Test_build(String raw, GfoMsg... expd) {
|
||||
GfoMsg root = msg_bldr.Bld(raw);
|
||||
Tfds.Eq_str_lines(Xto_str(expd), Xto_str(Xto_ary(root)));
|
||||
}
|
||||
GfoMsg[] Xto_ary(GfoMsg msg) {
|
||||
int len = msg.Subs_count();
|
||||
GfoMsg[] rv = new GfoMsg[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
rv[i] = msg.Subs_getAt(i);
|
||||
return rv;
|
||||
}
|
||||
String Xto_str(GfoMsg[] ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i != 0) sb.Add_char_crlf();
|
||||
sb.Add(ary[i].XtoStr());
|
||||
}
|
||||
return sb.XtoStrAndClear();
|
||||
}
|
||||
}
|
||||
85
400_xowa/src/gplx/gfs/Gfs_nde.java
Normal file
85
400_xowa/src/gplx/gfs/Gfs_nde.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
public class Gfs_nde {
|
||||
public byte[] Name_bry(byte[] src) {return name == null ? Bry_.Mid(src, name_bgn, name_end) : name;}
|
||||
public byte[] Name() {return name;} public Gfs_nde Name_(byte[] v) {name = v; return this;} private byte[] name;
|
||||
public int Name_bgn() {return name_bgn;} private int name_bgn = -1;
|
||||
public int Name_end() {return name_end;} private int name_end = -1;
|
||||
public Gfs_nde Name_rng_(int name_bgn, int name_end) {this.name_bgn = name_bgn; this.name_end = name_end; return this;}
|
||||
public byte Op_tid() {return op_tid;} public Gfs_nde Op_tid_(byte v) {op_tid = v; return this;} private byte op_tid;
|
||||
public void Subs_clear() {
|
||||
for (int i = 0; i < subs_len; i++)
|
||||
subs[i] = null;
|
||||
subs_len = 0;
|
||||
}
|
||||
public int Subs_len() {return subs_len;} private int subs_len;
|
||||
public Gfs_nde Subs_add_many(Gfs_nde... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Subs_add(ary[i]);
|
||||
return this;
|
||||
}
|
||||
public Gfs_nde Subs_add(Gfs_nde nde) {
|
||||
int new_len = subs_len + 1;
|
||||
if (new_len > subs_max) { // ary too small >>> expand
|
||||
subs_max = new_len * 2;
|
||||
Gfs_nde[] new_subs = new Gfs_nde[subs_max];
|
||||
Array_.CopyTo(subs, 0, new_subs, 0, subs_len);
|
||||
subs = new_subs;
|
||||
}
|
||||
subs[subs_len] = nde;
|
||||
subs_len = new_len;
|
||||
return this;
|
||||
} Gfs_nde[] subs = Gfs_nde.Ary_empty; int subs_max; int[] subs_pos_ary = Int_.Ary_empty;
|
||||
public Gfs_nde Subs_get_at(int i) {return subs[i];}
|
||||
public Gfs_nde[] Subs_to_ary() {
|
||||
Gfs_nde[] rv = new Gfs_nde[subs_len];
|
||||
for (int i = 0; i < subs_len; i++)
|
||||
rv[i] = subs[i];
|
||||
return rv;
|
||||
}
|
||||
public int Atrs_len() {return args_len;} private int args_len;
|
||||
public Gfs_nde Atrs_get_at(int i) {return args[i];}
|
||||
public Gfs_nde Atrs_add_many(Gfs_nde... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Atrs_add(ary[i]);
|
||||
return this;
|
||||
}
|
||||
public Gfs_nde Atrs_add(Gfs_nde nde) {
|
||||
int new_len = args_len + 1;
|
||||
if (new_len > args_max) { // ary too small >>> expand
|
||||
args_max = new_len * 2;
|
||||
Gfs_nde[] new_args = new Gfs_nde[args_max];
|
||||
Array_.CopyTo(args, 0, new_args, 0, args_len);
|
||||
args = new_args;
|
||||
}
|
||||
args[args_len] = nde;
|
||||
args_len = new_len;
|
||||
return this;
|
||||
} Gfs_nde[] args = Gfs_nde.Ary_empty; int args_max; int[] args_pos_ary = Int_.Ary_empty;
|
||||
public Gfs_nde[] Atrs_to_ary() {
|
||||
Gfs_nde[] rv = new Gfs_nde[args_len];
|
||||
for (int i = 0; i < args_len; i++)
|
||||
rv[i] = args[i];
|
||||
return rv;
|
||||
}
|
||||
public static final Gfs_nde[] Ary_empty = new Gfs_nde[0];
|
||||
public static final byte Op_tid_null = 0, Op_tid_assign = 1;
|
||||
}
|
||||
103
400_xowa/src/gplx/gfs/Gfs_parser.java
Normal file
103
400_xowa/src/gplx/gfs/Gfs_parser.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
public class Gfs_parser {
|
||||
ByteTrieMgr_fast trie = Gfs_parser_.trie_();
|
||||
Gfs_parser_ctx ctx = new Gfs_parser_ctx();
|
||||
public Gfs_nde Parse(byte[] src) {
|
||||
ctx.Root().Subs_clear();
|
||||
int src_len = src.length; if (src_len == 0) return ctx.Root();
|
||||
ctx.Init(trie, src, src_len);
|
||||
int pos = 0;
|
||||
while (pos < src_len) {
|
||||
byte b = src[pos];
|
||||
Object o = trie.Match(b, src, pos, src_len);
|
||||
if (o == null)
|
||||
ctx.Err_mgr().Fail_unknown_char(ctx, pos, b);
|
||||
else {
|
||||
Gfs_lxr lxr = (Gfs_lxr)o;
|
||||
while (lxr != null) {
|
||||
int rslt = lxr.Process(ctx, pos, trie.Match_pos());
|
||||
switch (lxr.Lxr_tid()) {
|
||||
case Gfs_lxr_.Tid_whitespace: break;
|
||||
case Gfs_lxr_.Tid_comment: break;
|
||||
default: ctx.Prv_lxr_(lxr.Lxr_tid()); break;
|
||||
}
|
||||
switch (rslt) {
|
||||
case Gfs_lxr_.Rv_lxr:
|
||||
pos = ctx.Nxt_pos();
|
||||
lxr = ctx.Nxt_lxr();
|
||||
break;
|
||||
case Gfs_lxr_.Rv_eos:
|
||||
pos = src_len;
|
||||
lxr = null;
|
||||
break;
|
||||
default:
|
||||
pos = rslt;
|
||||
lxr = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (ctx.Prv_lxr()) {
|
||||
case Gfs_lxr_.Tid_curly_end:
|
||||
case Gfs_lxr_.Tid_semic: break;
|
||||
default: ctx.Err_mgr().Fail_eos(ctx); break;
|
||||
}
|
||||
return ctx.Root();
|
||||
}
|
||||
}
|
||||
class Gfs_parser_ {
|
||||
public static ByteTrieMgr_fast trie_() {
|
||||
ByteTrieMgr_fast rv = ByteTrieMgr_fast.ci_ascii_(); // NOTE:ci.ascii:gfs;letters/symbols only;
|
||||
Gfs_lxr_identifier word_lxr = Gfs_lxr_identifier._;
|
||||
trie_add_rng(rv, word_lxr, Byte_ascii.Ltr_a, Byte_ascii.Ltr_z);
|
||||
trie_add_rng(rv, word_lxr, Byte_ascii.Ltr_A, Byte_ascii.Ltr_Z);
|
||||
trie_add_rng(rv, word_lxr, Byte_ascii.Num_0, Byte_ascii.Num_9);
|
||||
rv.Add(Byte_ascii.Underline, word_lxr);
|
||||
trie_add_many(rv, Gfs_lxr_whitespace._, Byte_ascii.Space, Byte_ascii.NewLine, Byte_ascii.CarriageReturn, Byte_ascii.Tab);
|
||||
trie_add_quote(rv, new byte[] {Byte_ascii.Apos});
|
||||
trie_add_quote(rv, new byte[] {Byte_ascii.Quote});
|
||||
trie_add_quote(rv, Bry_.new_ascii_("<:[\"\n"), Bry_.new_ascii_("\n\"]:>"));
|
||||
trie_add_quote(rv, Bry_.new_ascii_("<:['\n"), Bry_.new_ascii_("\n']:>"));
|
||||
trie_add_comment(rv, new byte[] {Byte_ascii.Slash, Byte_ascii.Slash}, new byte[] {Byte_ascii.NewLine});
|
||||
trie_add_comment(rv, new byte[] {Byte_ascii.Slash, Byte_ascii.Asterisk}, new byte[] {Byte_ascii.Asterisk, Byte_ascii.Slash});
|
||||
rv.Add(Byte_ascii.Semic, Gfs_lxr_semic._);
|
||||
rv.Add(Byte_ascii.Paren_bgn, Gfs_lxr_paren_bgn._);
|
||||
rv.Add(Byte_ascii.Paren_end, Gfs_lxr_paren_end._);
|
||||
rv.Add(Byte_ascii.Curly_bgn, Gfs_lxr_curly_bgn._);
|
||||
rv.Add(Byte_ascii.Curly_end, Gfs_lxr_curly_end._);
|
||||
rv.Add(Byte_ascii.Dot, Gfs_lxr_dot._);
|
||||
rv.Add(Byte_ascii.Comma, Gfs_lxr_comma._);
|
||||
rv.Add(Byte_ascii.Eq, Gfs_lxr_equal._);
|
||||
return rv;
|
||||
}
|
||||
private static void trie_add_rng(ByteTrieMgr_fast trie, Gfs_lxr lxr, byte bgn, byte end) {
|
||||
for (byte b = bgn; b <= end; b++)
|
||||
trie.Add(b, lxr);
|
||||
}
|
||||
private static void trie_add_many(ByteTrieMgr_fast trie, Gfs_lxr lxr, byte... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
trie.Add(ary[i], lxr);
|
||||
}
|
||||
private static void trie_add_quote(ByteTrieMgr_fast trie, byte[] bgn) {trie_add_quote(trie, bgn, bgn);}
|
||||
private static void trie_add_quote(ByteTrieMgr_fast trie, byte[] bgn, byte[] end) {trie.Add(bgn, new Gfs_lxr_quote(bgn, end));}
|
||||
private static void trie_add_comment(ByteTrieMgr_fast trie, byte[] bgn, byte[] end) {trie.Add(bgn, new Gfs_lxr_comment_flat(bgn, end));}
|
||||
}
|
||||
125
400_xowa/src/gplx/gfs/Gfs_parser_ctx.java
Normal file
125
400_xowa/src/gplx/gfs/Gfs_parser_ctx.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
class Gfs_parser_ctx {
|
||||
public ByteTrieMgr_fast Trie() {return trie;} ByteTrieMgr_fast trie;
|
||||
public Gfs_nde Root() {return root;} Gfs_nde root = new Gfs_nde();
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public int Src_len() {return src_len;} private int src_len;
|
||||
public byte Prv_lxr() {return prv_lxr;} public Gfs_parser_ctx Prv_lxr_(byte v) {prv_lxr = v; return this;} private byte prv_lxr;
|
||||
public Gfs_nde Cur_nde() {return cur_nde;} Gfs_nde cur_nde;
|
||||
public int Nxt_pos() {return nxt_pos;} private int nxt_pos;
|
||||
public Gfs_lxr Nxt_lxr() {return nxt_lxr;} Gfs_lxr nxt_lxr;
|
||||
public Bry_bfr Tmp_bfr() {return tmp_bfr;} private Bry_bfr tmp_bfr = Bry_bfr.new_();
|
||||
public void Process_eos() {}
|
||||
public void Process_lxr(int nxt_pos, Gfs_lxr nxt_lxr) {this.nxt_pos = nxt_pos; this.nxt_lxr = nxt_lxr;}
|
||||
public void Process_null(int cur_pos) {this.nxt_pos = cur_pos; this.nxt_lxr = null;}
|
||||
public void Init(ByteTrieMgr_fast trie, byte[] src, int src_len) {
|
||||
this.trie = trie; this.src = src; this.src_len = src_len;
|
||||
cur_nde = root;
|
||||
Stack_add();
|
||||
}
|
||||
public void Hold_word(int bgn, int end) {
|
||||
cur_idf_bgn = bgn;
|
||||
cur_idf_end = end;
|
||||
} int cur_idf_bgn = -1, cur_idf_end = -1;
|
||||
private void Held_word_clear() {cur_idf_bgn = -1; cur_idf_end = -1;}
|
||||
|
||||
public Gfs_nde Make_nde(int tkn_bgn, int tkn_end) { // "abc."; "abc("; "abc;"; "abc{"
|
||||
Gfs_nde nde = new Gfs_nde().Name_rng_(cur_idf_bgn, cur_idf_end);
|
||||
this.Held_word_clear();
|
||||
cur_nde.Subs_add(nde);
|
||||
cur_nde = nde;
|
||||
return nde;
|
||||
}
|
||||
public void Make_atr_by_idf() {Make_atr(cur_idf_bgn, cur_idf_end); Held_word_clear();}
|
||||
public void Make_atr_by_bry(int bgn, int end, byte[] bry) {Make_atr(bgn, end).Name_(bry);}
|
||||
public Gfs_nde Make_atr(int bgn, int end) {
|
||||
Gfs_nde nde = new Gfs_nde().Name_rng_(bgn, end);
|
||||
cur_nde.Atrs_add(nde);
|
||||
return nde;
|
||||
}
|
||||
public void Cur_nde_from_stack() {cur_nde = (Gfs_nde)nodes.FetchAtLast();}
|
||||
public void Stack_add() {nodes.Add(cur_nde);} ListAdp nodes = ListAdp_.new_();
|
||||
public void Stack_pop(int pos) {
|
||||
if (nodes.Count() < 2) err_mgr.Fail_nde_stack_empty(this, pos); // NOTE: need at least 2 items; 1 to pop and 1 to set as current
|
||||
ListAdp_.DelAt_last(nodes);
|
||||
Cur_nde_from_stack();
|
||||
}
|
||||
public Gfs_err_mgr Err_mgr() {return err_mgr;} Gfs_err_mgr err_mgr = new Gfs_err_mgr();
|
||||
}
|
||||
class Gfs_err_mgr {
|
||||
public void Fail_eos(Gfs_parser_ctx ctx) {Fail(ctx, Fail_msg_eos, ctx.Src_len());}
|
||||
public void Fail_unknown_char(Gfs_parser_ctx ctx, int pos, byte c) {Fail(ctx, Fail_msg_unknown_char, pos, KeyVal_.new_("char", Char_.XtoStr((char)c)));}
|
||||
public void Fail_nde_stack_empty(Gfs_parser_ctx ctx, int pos) {Fail(ctx, Fail_msg_nde_stack_empty, pos);}
|
||||
public void Fail_invalid_lxr(Gfs_parser_ctx ctx, int pos, byte cur_lxr, byte c) {
|
||||
Fail(ctx, Fail_msg_invalid_lxr, pos, KeyVal_.new_("char", Char_.XtoStr((char)c)), KeyVal_.new_("cur_lxr", Gfs_lxr_.Tid__name(cur_lxr)), KeyVal_.new_("prv_lxr", Gfs_lxr_.Tid__name(ctx.Prv_lxr())));
|
||||
}
|
||||
private void Fail(Gfs_parser_ctx ctx, String msg, int pos, KeyVal... args) {
|
||||
byte[] src = ctx.Src(); int src_len = ctx.Src_len();
|
||||
Fail_args_standard(src, src_len, pos);
|
||||
int len = args.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
KeyVal arg = args[i];
|
||||
tmp_fail_args.Add(arg.Key(), arg.Val_to_str_or_empty());
|
||||
}
|
||||
throw Err_.new_(Fail_msg(msg, tmp_fail_args));
|
||||
}
|
||||
private void Fail_args_standard(byte[] src, int src_len, int pos) {
|
||||
tmp_fail_args.Add("excerpt_bgn", Fail_excerpt_bgn(src, src_len, pos));
|
||||
tmp_fail_args.Add("excerpt_end", Fail_excerpt_end(src, src_len, pos));
|
||||
tmp_fail_args.Add("pos" , pos);
|
||||
}
|
||||
public static final String Fail_msg_invalid_lxr = "invalid character", Fail_msg_unknown_char = "unknown char", Fail_msg_eos = "end of stream", Fail_msg_nde_stack_empty = "node stack empty";
|
||||
String Fail_msg(String type, KeyValList fail_args) {
|
||||
tmp_fail_bfr.Add_str(type).Add_byte(Byte_ascii.Colon);
|
||||
int len = fail_args.Count();
|
||||
for (int i = 0; i < len; i++) {
|
||||
tmp_fail_bfr.Add_byte(Byte_ascii.Space);
|
||||
KeyVal kv = fail_args.GetAt(i);
|
||||
tmp_fail_bfr.Add_str(kv.Key());
|
||||
tmp_fail_bfr.Add_byte(Byte_ascii.Eq).Add_byte(Byte_ascii.Apos);
|
||||
tmp_fail_bfr.Add_str(kv.Val_to_str_or_empty()).Add_byte(Byte_ascii.Apos);
|
||||
}
|
||||
return tmp_fail_bfr.XtoStrAndClear();
|
||||
}
|
||||
Bry_bfr tmp_fail_bfr = Bry_bfr.reset_(255);
|
||||
KeyValList tmp_fail_args = new KeyValList();
|
||||
private static int excerpt_len = 50;
|
||||
String Fail_excerpt_bgn(byte[] src, int src_len, int pos) {
|
||||
int bgn = pos - excerpt_len; if (bgn < 0) bgn = 0;
|
||||
Fail_excerpt_rng(tmp_fail_bfr, src, bgn, pos);
|
||||
return tmp_fail_bfr.XtoStrAndClear();
|
||||
}
|
||||
String Fail_excerpt_end(byte[] src, int src_len, int pos) {
|
||||
int end = pos + excerpt_len; if (end > src_len) end = src_len;
|
||||
Fail_excerpt_rng(tmp_fail_bfr, src, pos, end);
|
||||
return tmp_fail_bfr.XtoStrAndClear();
|
||||
}
|
||||
private static void Fail_excerpt_rng(Bry_bfr bfr, byte[] src, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Tab: bfr.Add(Esc_tab); break;
|
||||
case Byte_ascii.NewLine: bfr.Add(Esc_nl); break;
|
||||
case Byte_ascii.CarriageReturn: bfr.Add(Esc_cr); break;
|
||||
default: bfr.Add_byte(b); break;
|
||||
}
|
||||
}
|
||||
} static final byte[] Esc_nl = Bry_.new_ascii_("\\n"), Esc_cr = Bry_.new_ascii_("\\r"), Esc_tab = Bry_.new_ascii_("\\t");
|
||||
}
|
||||
196
400_xowa/src/gplx/gfs/Gfs_parser_tst.java
Normal file
196
400_xowa/src/gplx/gfs/Gfs_parser_tst.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Gfs_parser_tst {
|
||||
@Before public void init() {fxt.Clear();} Gfs_parser_fxt fxt = new Gfs_parser_fxt();
|
||||
@Test public void Semicolon() {
|
||||
fxt .Test_parse("a;", fxt.nde_("a"));
|
||||
fxt .Test_parse("a;b;c;", fxt.nde_("a"), fxt.nde_("b"), fxt.nde_("c"));
|
||||
fxt .Test_parse("a_0;", fxt.nde_("a_0"));
|
||||
}
|
||||
@Test public void Dot() {
|
||||
fxt .Test_parse("a.b;", fxt.nde_("a").Subs_add(fxt.nde_("b")));
|
||||
fxt .Test_parse("a.b;c.d;", fxt.nde_("a").Subs_add(fxt.nde_("b")), fxt.nde_("c").Subs_add(fxt.nde_("d")));
|
||||
}
|
||||
@Test public void Parens() {
|
||||
fxt .Test_parse("a();b();", fxt.nde_("a"), fxt.nde_("b"));
|
||||
fxt .Test_parse("a().b();c().d();", fxt.nde_("a").Subs_add(fxt.nde_("b")), fxt.nde_("c").Subs_add(fxt.nde_("d")));
|
||||
}
|
||||
@Test public void Num() {
|
||||
fxt .Test_parse("a(1,2);", fxt.nde_("a").Atrs_add_many(fxt.val_("1"), fxt.val_("2")));
|
||||
}
|
||||
@Test public void Quote() {
|
||||
fxt .Test_parse("a('b');", fxt.nde_("a").Atrs_add(fxt.val_("b")));
|
||||
}
|
||||
@Test public void Quote_escaped() {
|
||||
fxt .Test_parse("a('b''c''d');", fxt.nde_("a").Atrs_add(fxt.val_("b'c'd")));
|
||||
}
|
||||
@Test public void Quote_escaped_2() {
|
||||
fxt .Test_parse("a('a''''b');", fxt.nde_("a").Atrs_add(fxt.val_("a''b")));
|
||||
}
|
||||
@Test public void Quote_mixed() {
|
||||
fxt .Test_parse("a('b\"c');", fxt.nde_("a").Atrs_add(fxt.val_("b\"c")));
|
||||
}
|
||||
@Test public void Comma() {
|
||||
fxt .Test_parse("a('b','c','d');", fxt.nde_("a").Atrs_add_many(fxt.val_("b"), fxt.val_("c"), fxt.val_("d")));
|
||||
}
|
||||
@Test public void Ws() {
|
||||
fxt .Test_parse(" a ( 'b' , 'c' ) ; ", fxt.nde_("a").Atrs_add_many(fxt.val_("b"), fxt.val_("c")));
|
||||
}
|
||||
@Test public void Comment_slash_slash() {
|
||||
fxt .Test_parse("//z\na;//y\n", fxt.nde_("a"));
|
||||
}
|
||||
@Test public void Comment_slash_star() {
|
||||
fxt .Test_parse("/*z*/a;/*y*/", fxt.nde_("a"));
|
||||
}
|
||||
@Test public void Curly() {
|
||||
fxt .Test_parse("a{b;}", fxt.nde_("a").Subs_add(fxt.nde_("b")));
|
||||
}
|
||||
@Test public void Curly_nest() {
|
||||
fxt .Test_parse("a{b{c{d;}}}"
|
||||
, fxt.nde_("a").Subs_add
|
||||
( fxt.nde_("b").Subs_add
|
||||
( fxt.nde_("c").Subs_add
|
||||
( fxt.nde_("d")
|
||||
))));
|
||||
}
|
||||
@Test public void Curly_nest_peers() {
|
||||
fxt .Test_parse(String_.Concat_lines_nl
|
||||
( "a{"
|
||||
, " a0{"
|
||||
, " a00{"
|
||||
, " a000;"
|
||||
, " }"
|
||||
, " a01;"
|
||||
, " }"
|
||||
, " a1;"
|
||||
, "}"
|
||||
)
|
||||
, fxt.nde_("a").Subs_add_many
|
||||
( fxt.nde_("a0").Subs_add_many
|
||||
( fxt.nde_("a00").Subs_add
|
||||
( fxt.nde_("a000")
|
||||
)
|
||||
, fxt.nde_("a01")
|
||||
)
|
||||
, fxt.nde_("a1")
|
||||
));
|
||||
}
|
||||
@Test public void Curly_dot() {
|
||||
fxt .Test_parse("a{a0.a00;a1.a10;}"
|
||||
, fxt.nde_("a").Subs_add_many
|
||||
( fxt.nde_("a0").Subs_add_many(fxt.nde_("a00"))
|
||||
, fxt.nde_("a1").Subs_add_many(fxt.nde_("a10"))
|
||||
));
|
||||
}
|
||||
@Test public void Eq() {
|
||||
fxt .Test_parse("a='b';", fxt.nde_("a").Atrs_add(fxt.val_("b")));
|
||||
fxt .Test_parse("a.b.c='d';"
|
||||
, fxt.nde_("a").Subs_add
|
||||
( fxt.nde_("b").Subs_add_many
|
||||
( fxt.nde_("c").Atrs_add(fxt.val_("d"))
|
||||
)));
|
||||
fxt .Test_parse("a.b{c='d'; e='f'}"
|
||||
, fxt.nde_("a").Subs_add
|
||||
( fxt.nde_("b").Subs_add_many
|
||||
( fxt.nde_("c").Atrs_add(fxt.val_("d"))
|
||||
, fxt.nde_("e").Atrs_add(fxt.val_("f"))
|
||||
)));
|
||||
}
|
||||
@Test public void Curly_nest_peers2() {
|
||||
fxt .Test_parse(String_.Concat_lines_nl
|
||||
( "a() {"
|
||||
, " k1 = 'v1';"
|
||||
, "}"
|
||||
)
|
||||
, fxt.nde_("a").Subs_add_many
|
||||
( fxt.nde_("k1").Atrs_add(fxt.val_("v1"))
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Fail() {
|
||||
fxt .Test_parse_fail("a(.);", Gfs_err_mgr.Fail_msg_invalid_lxr); // (.)
|
||||
fxt .Test_parse_fail("a..b;", Gfs_err_mgr.Fail_msg_invalid_lxr); // ..
|
||||
fxt .Test_parse_fail("a.;", Gfs_err_mgr.Fail_msg_invalid_lxr); // .;
|
||||
fxt .Test_parse_fail("a", Gfs_err_mgr.Fail_msg_eos); // eos
|
||||
fxt .Test_parse_fail("a;~;", Gfs_err_mgr.Fail_msg_unknown_char); // ~
|
||||
}
|
||||
}
|
||||
class Gfs_parser_fxt {
|
||||
public void Clear() {}
|
||||
public Gfs_nde nde_(String v) {return new Gfs_nde().Name_(Bry_.new_ascii_(v));}
|
||||
public Gfs_nde val_(String v) {return new Gfs_nde().Name_(Bry_.new_ascii_(v));}
|
||||
public void Test_parse(String src_str, Gfs_nde... expd) {
|
||||
byte[] src_bry = Bry_.new_utf8_(src_str);
|
||||
Gfs_nde root = parser.Parse(src_bry);
|
||||
Tfds.Eq_str_lines(To_str(null, expd), To_str(src_bry, root.Subs_to_ary()));
|
||||
} private Bry_bfr tmp_bfr = Bry_bfr.new_(), path_bfr = Bry_bfr.new_(); Gfs_parser parser = new Gfs_parser();
|
||||
public void Test_parse_fail(String src_str, String expd_err) {
|
||||
byte[] src_bry = Bry_.new_utf8_(src_str);
|
||||
try {parser.Parse(src_bry);}
|
||||
catch (Exception e) {
|
||||
String actl_err = Err_.Message_gplx_brief(e);
|
||||
actl_err = String_.GetStrBefore(actl_err, ":");
|
||||
boolean match = String_.HasAtBgn(actl_err, expd_err);
|
||||
if (!match) Tfds.Fail("expecting '" + expd_err + "' got '" + actl_err + "'");
|
||||
return;
|
||||
}
|
||||
Tfds.Fail("expected to fail with " + expd_err);
|
||||
}
|
||||
public String To_str(byte[] src, Gfs_nde[] expd) {
|
||||
int subs_len = expd.length;
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
path_bfr.Clear().Add_int_variable(i);
|
||||
To_str(tmp_bfr, path_bfr, src, expd[i]);
|
||||
}
|
||||
return tmp_bfr.XtoStrAndClear();
|
||||
}
|
||||
public void To_str(Bry_bfr bfr, Bry_bfr path, byte[] src, Gfs_nde nde) {
|
||||
To_str_atr(bfr, path, src, Atr_name, nde.Name(), nde.Name_bgn(), nde.Name_end());
|
||||
int atrs_len = nde.Atrs_len();
|
||||
for (int i = 0; i < atrs_len; i++) {
|
||||
Gfs_nde atr = nde.Atrs_get_at(i);
|
||||
int path_len_old = path.Len();
|
||||
path.Add_byte(Byte_ascii.Dot).Add_byte((byte)(Byte_ascii.Ltr_a + i));
|
||||
int path_len_new = path.Len();
|
||||
To_str(bfr, path, src, atr);
|
||||
path.Del_by(path_len_new - path_len_old);
|
||||
}
|
||||
int subs_len = nde.Subs_len();
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Gfs_nde sub = nde.Subs_get_at(i);
|
||||
int path_len_old = path.Len();
|
||||
path.Add_byte(Byte_ascii.Dot).Add_int_variable(i);
|
||||
int path_len_new = path.Len();
|
||||
To_str(bfr, path, src, sub);
|
||||
path.Del_by(path_len_new - path_len_old);
|
||||
}
|
||||
}
|
||||
private void To_str_atr(Bry_bfr bfr, Bry_bfr path_bfr, byte[] src, byte[] name, byte[] val, int val_bgn, int val_end) {
|
||||
if (val == null && val_bgn == -1 && val_end == -1) return;
|
||||
bfr.Add_bfr(path_bfr).Add_byte(Byte_ascii.Colon);
|
||||
bfr.Add(name);
|
||||
if (val == null)
|
||||
bfr.Add_mid(src, val_bgn, val_end);
|
||||
else
|
||||
bfr.Add(val);
|
||||
bfr.Add_byte_nl();
|
||||
}
|
||||
private static final byte[] Atr_name = Bry_.new_ascii_("name=");
|
||||
}
|
||||
46
400_xowa/src/gplx/gfs/Gfs_wtr.java
Normal file
46
400_xowa/src/gplx/gfs/Gfs_wtr.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfs; import gplx.*;
|
||||
public class Gfs_wtr {
|
||||
public byte Quote_char() {return quote_char;} public Gfs_wtr Quote_char_(byte v) {quote_char = v; return this;} private byte quote_char = Byte_ascii.Apos;
|
||||
public Bry_bfr Bfr() {return bfr;} private Bry_bfr bfr = Bry_bfr.reset_(255);
|
||||
public void Add_grp_bgn(byte[] key) {
|
||||
bfr.Add(key); // key
|
||||
bfr.Add_byte(Byte_ascii.Curly_bgn); // {
|
||||
}
|
||||
public void Add_grp_end(byte[] key) {
|
||||
bfr.Add_byte(Byte_ascii.Curly_end); // }
|
||||
}
|
||||
public void Add_set_eq(byte[] key, byte[] val) {
|
||||
bfr.Add(key); // key
|
||||
bfr.Add_byte_eq(); // =
|
||||
bfr.Add_byte(quote_char); // '
|
||||
Write_val(val);
|
||||
bfr.Add_byte(quote_char); // '
|
||||
bfr.Add_byte(Byte_ascii.Semic); // ;
|
||||
}
|
||||
private void Write_val(byte[] bry) {
|
||||
int bry_len = bry.length;
|
||||
for (int i = 0; i < bry_len; i++) {
|
||||
byte b = bry[i];
|
||||
if (b == quote_char) // byte is quote
|
||||
bfr.Add_byte(b); // double up
|
||||
bfr.Add_byte(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
286
400_xowa/src/gplx/gfui/Gfui_bnd_parser.java
Normal file
286
400_xowa/src/gplx/gfui/Gfui_bnd_parser.java
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfui; import gplx.*;
|
||||
public class Gfui_bnd_parser {
|
||||
private Bry_bfr tmp_bfr = Bry_bfr.reset_(32);
|
||||
private Hash_adp_bry
|
||||
gfui_regy = Hash_adp_bry.ci_ascii_()
|
||||
, norm_regy = Hash_adp_bry.ci_ascii_()
|
||||
;
|
||||
private static final Gfui_bnd_tkn
|
||||
Itm_sym_plus = new_sym_(Gfui_bnd_tkn.Tid_sym_plus , new byte[] {Byte_ascii.Plus})
|
||||
, Itm_sym_pipe = new_sym_(Gfui_bnd_tkn.Tid_sym_pipe , new byte[] {Byte_ascii.Pipe})
|
||||
, Itm_sym_comma = new_sym_(Gfui_bnd_tkn.Tid_sym_comma , new byte[] {Byte_ascii.Comma})
|
||||
// , Itm_sym_ws = new_sym_(Gfui_bnd_tkn.Tid_sym_ws , Bry_.Empty)
|
||||
, Itm_sym_eos = new_sym_(Gfui_bnd_tkn.Tid_sym_eos , Bry_.Empty)
|
||||
;
|
||||
private static final Gfui_bnd_tkn[] Mod_ary = new Gfui_bnd_tkn[]
|
||||
{ null
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_c , "mod.c" , "Ctrl")
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_a , "mod.a" , "Alt")
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_ca , "mod.ca" , "Ctrl + Alt")
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_s , "mod.s" , "Shift")
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_cs , "mod.cs" , "Ctrl + Shift")
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_as , "mod.as" , "Alt + Shift")
|
||||
, new_mod_(Gfui_bnd_tkn.Tid_mod_cas , "mod.cas" , "Ctrl + Alt + Shift")
|
||||
};
|
||||
private byte[] src; private int src_len;
|
||||
private ListAdp tkns = ListAdp_.new_(); private int mod_val = Mod_val_null;
|
||||
public String X_to_norm(String src_str) {return Convert(Bool_.Y, src_str);}
|
||||
public String X_to_gfui(String src_str) {return Convert(Bool_.N, src_str);}
|
||||
private String Convert(boolean src_is_gfui, String src_str) {
|
||||
this.src = Bry_.new_utf8_(src_str); this.src_len = src.length;
|
||||
tkns.Clear(); mod_val = Mod_val_null;
|
||||
int pos = 0; int itm_bgn = -1, itm_end = -1;
|
||||
while (pos <= src_len) { // loop over bytes and break up tkns by symbols
|
||||
byte b = pos == src_len ? Byte_ascii.NewLine: src[pos]; // treat eos as "\n" for purpose of separating tokens
|
||||
Gfui_bnd_tkn sym_tkn = null;
|
||||
switch (b) {
|
||||
case Byte_ascii.Plus: // simultaneous; EX: Ctrl + S
|
||||
sym_tkn = Itm_sym_plus;
|
||||
break;
|
||||
case Byte_ascii.Pipe: // alternate; EX: Ctrl + S | Ctrl + Alt + s
|
||||
sym_tkn = Itm_sym_pipe;
|
||||
break;
|
||||
case Byte_ascii.Comma: // chorded; EX: Ctrl + S, Ctrl + T
|
||||
sym_tkn = Itm_sym_comma;
|
||||
break;
|
||||
case Byte_ascii.NewLine: // eos: process anything in bfr
|
||||
sym_tkn = Itm_sym_eos;
|
||||
break;
|
||||
case Byte_ascii.Space:
|
||||
if (itm_bgn != -1) // if word started, " " ends word; EX: "Ctrl + A"; " +" ends "Ctrl"
|
||||
itm_end = pos;
|
||||
++pos;
|
||||
continue;
|
||||
default: // letter / number; continue
|
||||
if (itm_bgn == -1) // no word started; start it
|
||||
itm_bgn = pos;
|
||||
++pos;
|
||||
continue;
|
||||
}
|
||||
if (itm_end == -1) // end not set by space; char before symbol is end
|
||||
itm_end = pos;
|
||||
Process_sym(src_is_gfui, sym_tkn, itm_bgn, itm_end);
|
||||
if (sym_tkn.Tid() == Gfui_bnd_tkn.Tid_sym_eos)
|
||||
break;
|
||||
else
|
||||
++pos;
|
||||
itm_bgn = itm_end = -1;
|
||||
}
|
||||
int tkns_len = tkns.Count();
|
||||
for (int i = 0; i < tkns_len; i++) {
|
||||
Gfui_bnd_tkn tkn = (Gfui_bnd_tkn)tkns.FetchAt(i);
|
||||
tkn.Write(tmp_bfr, !src_is_gfui);
|
||||
}
|
||||
return tmp_bfr.XtoStrAndClear();
|
||||
}
|
||||
private void Process_sym(boolean src_is_gfui, Gfui_bnd_tkn sym_tkn, int itm_bgn, int itm_end) {
|
||||
Hash_adp_bry regy = src_is_gfui ? gfui_regy : norm_regy;
|
||||
Gfui_bnd_tkn tkn = (Gfui_bnd_tkn)regy.Get_by_mid(src, itm_bgn, itm_end);
|
||||
if (tkn == null) throw Err_.new_fmt_("unknown key: key={0}", String_.new_utf8_(src, itm_bgn, itm_end));
|
||||
int mod_adj = Mod_val_null;
|
||||
switch (tkn.Tid()) {
|
||||
case Gfui_bnd_tkn.Tid_mod_c: mod_adj = Gfui_bnd_tkn.Tid_mod_c; break;
|
||||
case Gfui_bnd_tkn.Tid_mod_a: mod_adj = Gfui_bnd_tkn.Tid_mod_a; break;
|
||||
case Gfui_bnd_tkn.Tid_mod_s: mod_adj = Gfui_bnd_tkn.Tid_mod_s; break;
|
||||
case Gfui_bnd_tkn.Tid_mod_cs: mod_adj = Gfui_bnd_tkn.Tid_mod_cs; break;
|
||||
case Gfui_bnd_tkn.Tid_mod_as: mod_adj = Gfui_bnd_tkn.Tid_mod_as; break;
|
||||
case Gfui_bnd_tkn.Tid_mod_ca: mod_adj = Gfui_bnd_tkn.Tid_mod_ca; break;
|
||||
case Gfui_bnd_tkn.Tid_mod_cas: mod_adj = Gfui_bnd_tkn.Tid_mod_cas; break;
|
||||
case Gfui_bnd_tkn.Tid_key: break;
|
||||
default: throw Err_.unhandled(tkn.Tid());
|
||||
}
|
||||
switch (sym_tkn.Tid()) {
|
||||
case Gfui_bnd_tkn.Tid_sym_plus: // EX: Ctrl + A
|
||||
if (mod_adj != Mod_val_null) { // if mod, just update mod_val and exit
|
||||
mod_val = Enm_.FlipInt(true, mod_val, mod_adj);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (mod_val != Mod_val_null) { // modifier exists; add tkn
|
||||
tkns.Add(Mod_ary[mod_val]);
|
||||
tkns.Add(Itm_sym_plus);
|
||||
mod_val = Mod_val_null;
|
||||
}
|
||||
tkns.Add(tkn); // add word
|
||||
if (sym_tkn.Tid() != Gfui_bnd_tkn.Tid_sym_eos)
|
||||
tkns.Add(sym_tkn);
|
||||
}
|
||||
private Gfui_bnd_parser Init_en() {
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_c);
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_a);
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_s);
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_ca);
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_cs);
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_as);
|
||||
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_cas);
|
||||
Init_itm(Gfui_bnd_tkn.Tid_mod_c, "key.ctrl", "Ctrl");
|
||||
Init_itm(Gfui_bnd_tkn.Tid_mod_a, "key.alt", "Atl");
|
||||
Init_itm(Gfui_bnd_tkn.Tid_mod_s, "key.shift", "Shift");
|
||||
Init_itm("key.a", "A");
|
||||
Init_itm("key.b", "B");
|
||||
Init_itm("key.c", "C");
|
||||
Init_itm("key.d", "D");
|
||||
Init_itm("key.e", "E");
|
||||
Init_itm("key.f", "F");
|
||||
Init_itm("key.g", "G");
|
||||
Init_itm("key.h", "H");
|
||||
Init_itm("key.i", "I");
|
||||
Init_itm("key.j", "J");
|
||||
Init_itm("key.k", "K");
|
||||
Init_itm("key.l", "L");
|
||||
Init_itm("key.m", "M");
|
||||
Init_itm("key.n", "N");
|
||||
Init_itm("key.o", "O");
|
||||
Init_itm("key.p", "P");
|
||||
Init_itm("key.q", "Q");
|
||||
Init_itm("key.r", "R");
|
||||
Init_itm("key.s", "S");
|
||||
Init_itm("key.t", "T");
|
||||
Init_itm("key.u", "U");
|
||||
Init_itm("key.v", "V");
|
||||
Init_itm("key.w", "W");
|
||||
Init_itm("key.x", "X");
|
||||
Init_itm("key.y", "Y");
|
||||
Init_itm("key.z", "Z");
|
||||
Init_itm("key.d0", "0");
|
||||
Init_itm("key.d1", "1");
|
||||
Init_itm("key.d2", "2");
|
||||
Init_itm("key.d3", "3");
|
||||
Init_itm("key.d4", "4");
|
||||
Init_itm("key.d5", "5");
|
||||
Init_itm("key.d6", "6");
|
||||
Init_itm("key.d7", "7");
|
||||
Init_itm("key.d8", "8");
|
||||
Init_itm("key.d9", "9");
|
||||
Init_itm("key.f1", "F1");
|
||||
Init_itm("key.f2", "F2");
|
||||
Init_itm("key.f3", "F3");
|
||||
Init_itm("key.f4", "F4");
|
||||
Init_itm("key.f5", "F5");
|
||||
Init_itm("key.f6", "F6");
|
||||
Init_itm("key.f7", "F7");
|
||||
Init_itm("key.f8", "F8");
|
||||
Init_itm("key.f9", "F9");
|
||||
Init_itm("key.f10", "F10");
|
||||
Init_itm("key.f11", "F11");
|
||||
Init_itm("key.f12", "F12");
|
||||
Init_itm("key.none", "None");
|
||||
Init_itm("key.back", "Backspace");
|
||||
Init_itm("key.tab", "Tab");
|
||||
Init_itm("key.clear", "Clear");
|
||||
Init_itm("key.enter", "Enter");
|
||||
Init_itm("key.shiftKey", "ShiftKey");
|
||||
Init_itm("key.ctrlKey", "CtrlKey");
|
||||
Init_itm("key.altKey", "AltKey");
|
||||
Init_itm("key.pause", "Pause");
|
||||
Init_itm("key.capsLock", "CapsLock");
|
||||
Init_itm("key.escape", "Escape");
|
||||
Init_itm("key.space", "Space");
|
||||
Init_itm("key.pageUp", "PageUp");
|
||||
Init_itm("key.pageDown", "PageDown");
|
||||
Init_itm("key.end", "End");
|
||||
Init_itm("key.home", "Home");
|
||||
Init_itm("key.left", "Left");
|
||||
Init_itm("key.up", "Up");
|
||||
Init_itm("key.right", "Right");
|
||||
Init_itm("key.down", "Down");
|
||||
Init_itm("key.printScreen", "PrintScreen");
|
||||
Init_itm("key.insert", "Insert");
|
||||
Init_itm("key.delete", "Delete");
|
||||
Init_itm("key.numLock", "NumLock");
|
||||
Init_itm("key.scrollLock", "ScrollLock");
|
||||
Init_itm("key.semicolon", "Semicolon");
|
||||
Init_itm("key.equal", "Equal");
|
||||
Init_itm("key.comma", "Comma");
|
||||
Init_itm("key.minus", "Minus");
|
||||
Init_itm("key.period", "Period");
|
||||
Init_itm("key.slash", "Slash");
|
||||
Init_itm("key.tick", "Tick");
|
||||
Init_itm("key.openBracket", "OpenBracket");
|
||||
Init_itm("key.backslash", "Backslash");
|
||||
Init_itm("key.closeBracket", "CloseBracket");
|
||||
Init_itm("key.quote", "Quote");
|
||||
Init_itm("mouse.middle", "Middle Click");
|
||||
Init_itm("mouse.left", "Left Click");
|
||||
Init_itm("mouse.right", "Right Click");
|
||||
return this;
|
||||
}
|
||||
private void Init_itm(String gfui, String norm) {Init_itm(Gfui_bnd_tkn.Tid_key, gfui, norm);}
|
||||
private void Init_itm_mod(int tid) {
|
||||
Gfui_bnd_tkn itm = Mod_ary[tid];
|
||||
gfui_regy.Add(itm.Bry_gfui(), itm);
|
||||
norm_regy.Add(itm.Bry_norm(), itm);
|
||||
}
|
||||
private void Init_itm(byte tid, String gfui, String norm) {
|
||||
byte[] gfui_bry = Bry_.new_utf8_(gfui);
|
||||
byte[] norm_bry = Bry_.new_utf8_(norm);
|
||||
Gfui_bnd_tkn itm = new Gfui_bnd_tkn(tid, gfui_bry, norm_bry);
|
||||
gfui_regy.Add(gfui_bry, itm);
|
||||
norm_regy.Add_if_new(norm_bry, itm);
|
||||
}
|
||||
private static final int Mod_val_null = 0;
|
||||
public static Gfui_bnd_parser new_en_() {return new Gfui_bnd_parser().Init_en();} Gfui_bnd_parser() {}
|
||||
private static Gfui_bnd_tkn new_sym_(byte tid, byte[] bry) {return new Gfui_bnd_tkn(tid, bry, bry);}
|
||||
private static Gfui_bnd_tkn new_mod_(byte tid, String gfui, String norm) {return new Gfui_bnd_tkn(tid, Bry_.new_ascii_(gfui), Bry_.new_ascii_(norm));}
|
||||
}
|
||||
class Gfui_bnd_tkn {
|
||||
public Gfui_bnd_tkn(byte tid, byte[] gfui, byte[] norm) {this.tid = tid; this.bry_gfui = gfui; this.bry_norm = norm;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Bry_gfui() {return bry_gfui;} private byte[] bry_gfui;
|
||||
public byte[] Bry_norm() {return bry_norm;} private byte[] bry_norm;
|
||||
public void Write(Bry_bfr bfr, boolean src_is_gfui) {
|
||||
byte[] bry = src_is_gfui ? bry_gfui : bry_norm;
|
||||
switch (tid) {
|
||||
case Tid_mod_c: case Tid_mod_a: case Tid_mod_s:
|
||||
case Tid_mod_ca: case Tid_mod_cs: case Tid_mod_as: case Tid_mod_cas:
|
||||
bfr.Add(bry);
|
||||
break;
|
||||
case Tid_sym_plus:
|
||||
if (!src_is_gfui)
|
||||
bfr.Add_byte_space();
|
||||
bfr.Add(bry);
|
||||
if (!src_is_gfui)
|
||||
bfr.Add_byte_space();
|
||||
break;
|
||||
case Tid_sym_pipe:
|
||||
if (!src_is_gfui)
|
||||
bfr.Add_byte_space();
|
||||
bfr.Add(bry);
|
||||
if (!src_is_gfui)
|
||||
bfr.Add_byte_space();
|
||||
break;
|
||||
case Tid_sym_comma:
|
||||
bfr.Add(bry);
|
||||
if (!src_is_gfui)
|
||||
bfr.Add_byte_space();
|
||||
break;
|
||||
case Tid_key:
|
||||
bfr.Add(bry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public static final byte
|
||||
Tid_mod_c = 1 , Tid_mod_a = 2 , Tid_mod_s = 4
|
||||
, Tid_mod_ca = 3 , Tid_mod_cs = 5 , Tid_mod_as = 6, Tid_mod_cas = 7
|
||||
, Tid_sym_plus = 8 , Tid_sym_pipe = 9 , Tid_sym_comma = 10, Tid_sym_eos = 11
|
||||
, Tid_key = 12
|
||||
;
|
||||
}
|
||||
56
400_xowa/src/gplx/gfui/Gfui_bnd_parser_tst.java
Normal file
56
400_xowa/src/gplx/gfui/Gfui_bnd_parser_tst.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.gfui; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Gfui_bnd_parser_tst {
|
||||
@Before public void init() {fxt.Clear();} private Gfui_bnd_parser_fxt fxt = new Gfui_bnd_parser_fxt();
|
||||
@Test public void Norm_one() {
|
||||
fxt.Test_x_to_norm("mod.c" , "Ctrl");
|
||||
fxt.Test_x_to_norm("key.ctrl" , "Ctrl");
|
||||
fxt.Test_x_to_norm("key.a" , "A");
|
||||
fxt.Test_x_to_norm("key.left" , "Left");
|
||||
}
|
||||
@Test public void Norm_add() {
|
||||
fxt.Test_x_to_norm("mod.c+key.a" , "Ctrl + A");
|
||||
fxt.Test_x_to_norm("mod.ca+key.a" , "Ctrl + Alt + A");
|
||||
fxt.Test_x_to_norm("mod.cas+key.a" , "Ctrl + Alt + Shift + A");
|
||||
}
|
||||
@Test public void Norm_chord() {
|
||||
fxt.Test_x_to_norm("key.a,key.b" , "A, B");
|
||||
}
|
||||
@Test public void Norm_add_and_chord() {
|
||||
fxt.Test_x_to_norm("mod.c+key.a,mod.a+key.b" , "Ctrl + A, Alt + B");
|
||||
}
|
||||
@Test public void Gfui_add() {
|
||||
fxt.Test_x_to_gfui("Ctrl + A" , "mod.c+key.a");
|
||||
fxt.Test_x_to_gfui("Ctrl + Shift + A" , "mod.cs+key.a");
|
||||
fxt.Test_x_to_gfui("Ctrl + Alt + Shift + A" , "mod.cas+key.a");
|
||||
}
|
||||
}
|
||||
class Gfui_bnd_parser_fxt {
|
||||
private Gfui_bnd_parser parser;
|
||||
public void Clear() {
|
||||
parser = Gfui_bnd_parser.new_en_();
|
||||
}
|
||||
public void Test_x_to_norm(String key, String expd) {
|
||||
Tfds.Eq(expd, parser.X_to_norm(key));
|
||||
}
|
||||
public void Test_x_to_gfui(String key, String expd) {
|
||||
Tfds.Eq(expd, parser.X_to_gfui(key));
|
||||
}
|
||||
}
|
||||
28
400_xowa/src/gplx/html/Html_atrs.java
Normal file
28
400_xowa/src/gplx/html/Html_atrs.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_atrs {
|
||||
public static final String
|
||||
Src_str = "src"
|
||||
;
|
||||
public static final byte[]
|
||||
Id_bry = Bry_.new_ascii_("id")
|
||||
, Cls_bry = Bry_.new_ascii_("class")
|
||||
, Style_bry = Bry_.new_ascii_("style")
|
||||
;
|
||||
}
|
||||
42
400_xowa/src/gplx/html/Html_consts.java
Normal file
42
400_xowa/src/gplx/html/Html_consts.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_consts {
|
||||
public static final String Nl_str = " ";
|
||||
public static final String
|
||||
Comm_bgn_str = "<!--"
|
||||
, Comm_end_str = "-->"
|
||||
, Img_str = "img"
|
||||
;
|
||||
public static final byte[]
|
||||
Lt = Bry_.new_ascii_("<"), Gt = Bry_.new_ascii_(">")
|
||||
, Amp = Bry_.new_ascii_("&"), Quote = Bry_.new_ascii_("""), Apos = Bry_.new_ascii_("'")
|
||||
, Eq = Bry_.new_ascii_("=")
|
||||
, Nl_bry = Bry_.new_ascii_(Nl_str), Space_bry = Bry_.new_ascii_(" ")
|
||||
, Comm_bgn = Bry_.new_ascii_(Comm_bgn_str), Comm_end = Bry_.new_ascii_(Comm_end_str)
|
||||
, Hr_bry = Bry_.new_ascii_("<hr/>")
|
||||
, Br_bry = Bry_.new_ascii_("<br/>")
|
||||
, Td_bgn_bry = Bry_.new_ascii_("<td>")
|
||||
, Td_end_bry = Bry_.new_ascii_("</td>")
|
||||
, Ul_tag_bry = Bry_.new_ascii_("ul")
|
||||
;
|
||||
public static final int
|
||||
Comm_bgn_len = Comm_bgn.length
|
||||
, Comm_end_len = Comm_end.length
|
||||
;
|
||||
}
|
||||
94
400_xowa/src/gplx/html/Html_nde.java
Normal file
94
400_xowa/src/gplx/html/Html_nde.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_nde {
|
||||
public Html_nde(byte[] src, boolean tag_tid_is_inline, int tag_lhs_bgn, int tag_lhs_end, int tag_rhs_bgn, int tag_rhs_end, int name_bgn, int name_end, int[] cur_atrs, int atrs_idx) {
|
||||
this.src = src;
|
||||
this.tag_tid_is_inline = tag_tid_is_inline;
|
||||
this.tag_lhs_bgn = tag_lhs_bgn; this.tag_lhs_end = tag_lhs_end; this.tag_rhs_bgn = tag_rhs_bgn; this.tag_rhs_end = tag_rhs_end; this.name_bgn = name_bgn; this.name_end = name_end;
|
||||
if (atrs_idx > 0) {
|
||||
atrs = new int[atrs_idx];
|
||||
for (int i = 0; i < atrs_idx; i++)
|
||||
atrs[i] = cur_atrs[i];
|
||||
atrs_len = atrs_idx / 5;
|
||||
}
|
||||
}
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public int[] Atrs() {return atrs;} private int[] atrs = Int_.Ary_empty;
|
||||
public int Atrs_len() {return atrs_len;} private int atrs_len;
|
||||
public boolean Tag_tid_is_inline() {return tag_tid_is_inline;} private boolean tag_tid_is_inline;
|
||||
public int Tag_lhs_bgn() {return tag_lhs_bgn;} public Html_nde Tag_lhs_bgn_(int v) {tag_lhs_bgn = v; return this;} private int tag_lhs_bgn;
|
||||
public int Tag_lhs_end() {return tag_lhs_end;} public Html_nde Tag_lhs_end_(int v) {tag_lhs_end = v; return this;} private int tag_lhs_end;
|
||||
public int Tag_rhs_bgn() {return tag_rhs_bgn;} public Html_nde Tag_rhs_bgn_(int v) {tag_rhs_bgn = v; return this;} private int tag_rhs_bgn;
|
||||
public int Tag_rhs_end() {return tag_rhs_end;} public Html_nde Tag_rhs_end_(int v) {tag_rhs_end = v; return this;} private int tag_rhs_end;
|
||||
public int Name_bgn() {return name_bgn;} public Html_nde Name_bgn_(int v) {name_bgn = v; return this;} private int name_bgn;
|
||||
public int Name_end() {return name_end;} public Html_nde Name_end_(int v) {name_end = v; return this;} private int name_end;
|
||||
public void Clear() {tag_lhs_bgn = tag_rhs_bgn = -1;}
|
||||
public String Atrs_val_by_key_str(String find_key_str) {return String_.new_utf8_(Atrs_val_by_key_bry(Bry_.new_utf8_(find_key_str)));}
|
||||
public byte[] Atrs_val_by_key_bry(byte[] find_key_bry) {
|
||||
for (int i = 0; i < atrs_len; i ++) {
|
||||
int atrs_idx = i * 5;
|
||||
int atr_key_bgn = atrs[atrs_idx + 1];
|
||||
int atr_key_end = atrs[atrs_idx + 2];
|
||||
if (Bry_.Match(src, atr_key_bgn, atr_key_end, find_key_bry))
|
||||
return Atrs_vals_by_pos(src, atrs[atrs_idx + 0], atrs[atrs_idx + 3], atrs[atrs_idx + 4]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
byte[] Atrs_vals_by_pos(byte[] src, int quote_byte, int bgn, int end) {
|
||||
Bry_bfr tmp_bfr = Bry_bfr.new_();
|
||||
boolean dirty = false;
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Backslash:
|
||||
if (!dirty) {dirty = true; tmp_bfr.Add_mid(src, bgn, i);}
|
||||
++i;
|
||||
tmp_bfr.Add_byte(src[i]);
|
||||
break;
|
||||
default:
|
||||
if (b == quote_byte) {
|
||||
byte next_byte = src[i + 1];
|
||||
if (next_byte == b) {
|
||||
if (!dirty) {dirty = true; tmp_bfr.Add_mid(src, bgn, i);}
|
||||
++i;
|
||||
tmp_bfr.Add_byte(src[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dirty)
|
||||
tmp_bfr.Add_byte(b);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dirty ? tmp_bfr.XtoAryAndClear() : Bry_.Mid(src, bgn, end);
|
||||
}
|
||||
public byte[] Data(byte[] src) {
|
||||
return Bry_.Mid(src, tag_lhs_end, tag_rhs_bgn);
|
||||
}
|
||||
}
|
||||
// class Xoh_atr {
|
||||
// public byte[] Key_bry() {return key_bry;} private byte[] key_bry;
|
||||
// public byte[] Val_bry() {return val_bry;} private byte[] val_bry;
|
||||
// public int Key_bgn() {return key_bgn;} private int key_bgn;
|
||||
// public int Key_end() {return key_end;} private int key_end;
|
||||
// public int Val_bgn() {return val_bgn;} private int val_bgn;
|
||||
// public int Val_end() {return val_end;} private int val_end;
|
||||
// public byte Val_quote_tid() {return val_quote_tid;} private byte val_quote_tid;
|
||||
// }
|
||||
165
400_xowa/src/gplx/html/Html_parser.java
Normal file
165
400_xowa/src/gplx/html/Html_parser.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
import gplx.core.bytes.*;
|
||||
public class Html_parser {
|
||||
public Html_parser() {
|
||||
Bry_bldr bry_bldr = new Bry_bldr();
|
||||
bry_xnde_name = bry_bldr.New_256().Set_rng_xml_identifier(Scan_valid).Set_rng_ws(Scan_stop).Val();
|
||||
bry_atr_key = bry_bldr.New_256().Set_rng_xml_identifier(Scan_valid).Set_rng_ws(Scan_stop).Set_many(Scan_stop, Byte_ascii.Eq).Val();
|
||||
}
|
||||
byte[] src; int pos, end; byte[] bry_xnde_name, bry_atr_key;
|
||||
int cur_atrs_idx = 0; int[] cur_atrs = new int[250];// define max of 50 atrs;
|
||||
public Html_nde[] Parse_as_ary(byte[] src) {return Parse_as_ary(src, 0, src.length, Wildcard, Wildcard);}
|
||||
public Html_nde[] Parse_as_ary(byte[] src, int bgn, int end) {return Parse_as_ary(src, bgn, end, Wildcard, Wildcard);}
|
||||
public Html_nde[] Parse_as_ary(byte[] src, int bgn, int end, byte[] find_key, byte[] find_val) { // flattens html into a list of hndes; only used for Options
|
||||
this.src = src; pos = bgn; this.end = end;
|
||||
ListAdp rv = ListAdp_.new_();
|
||||
while (pos < end) {
|
||||
byte b = src[pos++];
|
||||
switch (b) {
|
||||
case Byte_ascii.Lt:
|
||||
if (xnde_init) {
|
||||
if (Parse_xnde_lhs()) {
|
||||
if (tag_tid_is_inline)
|
||||
rv.Add(new Html_nde(src, tag_tid_is_inline, cur_lhs_bgn, cur_lhs_end, cur_rhs_bgn, pos, cur_name_bgn, cur_name_end, cur_atrs, cur_atrs_idx));
|
||||
else
|
||||
xnde_init = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Parse_xnde_rhs()) {
|
||||
rv.Add(new Html_nde(src, tag_tid_is_inline, cur_lhs_bgn, cur_lhs_end, cur_rhs_bgn, pos, cur_name_bgn, cur_name_end, cur_atrs, cur_atrs_idx));
|
||||
}
|
||||
xnde_init = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (Html_nde[])rv.XtoAry(Html_nde.class);
|
||||
}
|
||||
int cur_lhs_bgn, cur_lhs_end, cur_name_bgn, cur_name_end, cur_rhs_bgn; boolean xnde_init = true, tag_tid_is_inline = false;
|
||||
private boolean Parse_xnde_rhs() {
|
||||
cur_rhs_bgn = pos - 1; // -1 b/c "<" is already read
|
||||
byte b = src[pos];
|
||||
if (b != Byte_ascii.Slash) return false;
|
||||
++pos;
|
||||
int name_len = cur_name_end - cur_name_bgn;
|
||||
if (pos + name_len >= end) return false;
|
||||
if (!Bry_.Match(src, pos, pos + name_len, src, cur_name_bgn, cur_name_end)) return false;
|
||||
pos += name_len;
|
||||
if (src[pos] != Byte_ascii.Gt) return false;
|
||||
++pos;
|
||||
return true;
|
||||
}
|
||||
private boolean Parse_xnde_lhs() {
|
||||
cur_atrs_idx = 0;
|
||||
cur_lhs_bgn = pos - 1;
|
||||
cur_name_bgn = pos;
|
||||
tag_tid_is_inline = false;
|
||||
byte rslt = Skip_while_valid(this.bry_atr_key);
|
||||
if (rslt == Scan_invalid) return false;
|
||||
cur_name_end = pos;
|
||||
int key_bgn, key_end, val_bgn, quote_type;
|
||||
while (true) {
|
||||
if (pos >= end) return false;
|
||||
key_bgn = key_end = val_bgn = quote_type = -1;
|
||||
Skip_ws();
|
||||
byte b = src[pos];
|
||||
if (b == Byte_ascii.Slash) {
|
||||
++pos;
|
||||
if (pos == end) return false;
|
||||
byte next = src[pos];
|
||||
if (next == Byte_ascii.Gt) {
|
||||
tag_tid_is_inline = true;
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
else return false; // NOTE: don't consume byte b/c false
|
||||
}
|
||||
else if (b == Byte_ascii.Gt) {
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
key_bgn = pos;
|
||||
rslt = Skip_while_valid(this.bry_atr_key);
|
||||
if (rslt == Scan_invalid) return false;
|
||||
key_end = pos;
|
||||
Skip_ws();
|
||||
if (src[pos++] != Byte_ascii.Eq) return false;
|
||||
Skip_ws();
|
||||
byte quote_byte = src[pos];
|
||||
switch (quote_byte) {
|
||||
case Byte_ascii.Quote: quote_type = quote_byte; break;
|
||||
case Byte_ascii.Apos: quote_type = quote_byte; break;
|
||||
default: return false;
|
||||
}
|
||||
val_bgn = ++pos; // ++pos: start val after quote
|
||||
if (!Skip_to_quote_end(quote_byte)) return false;
|
||||
cur_atrs[cur_atrs_idx + 0] = quote_type;
|
||||
cur_atrs[cur_atrs_idx + 1] = key_bgn;
|
||||
cur_atrs[cur_atrs_idx + 2] = key_end;
|
||||
cur_atrs[cur_atrs_idx + 3] = val_bgn;
|
||||
cur_atrs[cur_atrs_idx + 4] = pos - 1; // NOTE: Skip_to_quote_end positions after quote
|
||||
cur_atrs_idx += 5;
|
||||
}
|
||||
cur_lhs_end = pos;
|
||||
return true;
|
||||
}
|
||||
private void Skip_ws() {
|
||||
while (pos < end) {
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn:
|
||||
++pos;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean Skip_to_quote_end(byte v) {
|
||||
while (pos < end) {
|
||||
byte b = src[pos++];
|
||||
if (b == v) {
|
||||
if (pos == end) return false;
|
||||
byte next = src[pos];
|
||||
if (next != v) return true;
|
||||
else ++pos;
|
||||
}
|
||||
else if (b == Byte_ascii.Backslash) {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
byte Skip_while_valid(byte[] comp) {
|
||||
while (pos < end) {
|
||||
byte rv = comp[src[pos]];
|
||||
if (rv == Scan_valid)
|
||||
++pos;
|
||||
else
|
||||
return rv;
|
||||
}
|
||||
return Scan_invalid;
|
||||
}
|
||||
private static final byte Scan_invalid = 0, Scan_valid = 1, Scan_stop = 2;
|
||||
public static final byte[] Wildcard = null;
|
||||
public static final String Wildcard_str = null;
|
||||
}
|
||||
53
400_xowa/src/gplx/html/Html_parser_tst.java
Normal file
53
400_xowa/src/gplx/html/Html_parser_tst.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Html_parser_tst {
|
||||
@Before public void init() {fxt.Clear();} private Xoh_parser_fxt fxt = new Xoh_parser_fxt();
|
||||
@Test public void One() {fxt.Test_parse_find_all("<a id='id0'></a>", "id0");}
|
||||
@Test public void Many() {fxt.Test_parse_find_all("<a id='id0'></a><a id='id1'></a><a id='id2'></a>", "id0", "id1", "id2");}
|
||||
@Test public void Inline() {fxt.Test_parse_find_all("<a id='id0'/>", "id0");}
|
||||
@Test public void Mix() {fxt.Test_parse_find_all("012<a id='id0'></a>id=id2<a id='id1'/>345<a id='id2'></a>abc", "id0", "id1", "id2");}
|
||||
@Test public void Quote_double() {fxt.Test_parse_find_all("<a id='id''0'/>", "id'0");}
|
||||
@Test public void Quote_escape() {fxt.Test_parse_find_all("<a id='id\\'0'/>", "id'0");}
|
||||
}
|
||||
class Xoh_parser_fxt {
|
||||
public void Clear() {
|
||||
if (parser == null) {
|
||||
parser = new Html_parser();
|
||||
}
|
||||
} private Html_parser parser;
|
||||
public Xoh_parser_fxt Test_parse_find_all(String raw_str, String... expd) {return Test_parse_find(raw_str, Html_parser.Wildcard_str, Html_parser.Wildcard_str, expd);}
|
||||
public Xoh_parser_fxt Test_parse_find(String raw_str, String find_key, String find_val, String... expd) {
|
||||
byte[] raw = Bry_.new_ascii_(raw_str);
|
||||
Html_nde[] actl_ndes = parser.Parse_as_ary(raw, 0, raw.length, Bry_.new_ascii_(find_key), Bry_.new_ascii_(find_val));
|
||||
String[] actl = Xto_ids(raw, actl_ndes);
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
return this;
|
||||
}
|
||||
private String[] Xto_ids(byte[] src, Html_nde[] ary) {
|
||||
int len = ary.length;
|
||||
String[] rv = new String[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
Html_nde itm = ary[i];
|
||||
String atr_val = itm.Atrs_val_by_key_str("id");
|
||||
rv[i] = atr_val;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
40
400_xowa/src/gplx/html/Html_selecter.java
Normal file
40
400_xowa/src/gplx/html/Html_selecter.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_selecter {
|
||||
public static Html_nde[] Select(byte[] src, Html_nde[] ary, Hash_adp_bry hash) {
|
||||
ListAdp list = ListAdp_.new_();
|
||||
int xndes_len = ary.length;
|
||||
for (int i = 0; i < xndes_len; i++) {
|
||||
Html_nde hnde = ary[i];
|
||||
int[] atrs = hnde.Atrs();
|
||||
int atrs_len = atrs.length;
|
||||
for (int j = 0; j < atrs_len; j += 5) {
|
||||
int atr_key_bgn = atrs[j + 1];
|
||||
int atr_key_end = atrs[j + 2];
|
||||
if (hash.Get_by_mid(src, atr_key_bgn, atr_key_end) != null) {
|
||||
list.Add(hnde);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Html_nde[] rv = (Html_nde[])list.XtoAry(Html_nde.class);
|
||||
list.Clear();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
36
400_xowa/src/gplx/html/Html_tags.java
Normal file
36
400_xowa/src/gplx/html/Html_tags.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_tags {
|
||||
public static final String
|
||||
A_str = "a"
|
||||
, Img_str = "img"
|
||||
;
|
||||
public static final byte[]
|
||||
Body_lhs = Bry_.new_ascii_("<body>")
|
||||
, Body_rhs = Bry_.new_ascii_("</body>")
|
||||
, Html_rhs = Bry_.new_ascii_("</html>")
|
||||
, Head_lhs_bgn = Bry_.new_ascii_("<head")
|
||||
, Head_rhs = Bry_.new_ascii_("</head>")
|
||||
, Style_lhs_w_type = Bry_.new_ascii_("<style type=\"text/css\">")
|
||||
, Style_rhs = Bry_.new_ascii_("</style>")
|
||||
, Script_lhs = Bry_.new_ascii_("<script>")
|
||||
, Script_lhs_w_type = Bry_.new_ascii_("<script type='text/javascript'>")
|
||||
, Script_rhs = Bry_.new_ascii_("</script>")
|
||||
;
|
||||
}
|
||||
167
400_xowa/src/gplx/html/Html_utl.java
Normal file
167
400_xowa/src/gplx/html/Html_utl.java
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_utl {
|
||||
public static byte[] Escape_for_atr_val_as_bry(String s, byte quote_byte) {
|
||||
Bry_bfr tmp_bfr = null;
|
||||
if (s == null) return null;
|
||||
byte[] bry = Bry_.new_utf8_(s);
|
||||
boolean dirty = false;
|
||||
int len = bry.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
byte b = bry[i];
|
||||
if (b == quote_byte) {
|
||||
if (!dirty) {
|
||||
tmp_bfr = Bry_bfr.reset_(256);
|
||||
tmp_bfr.Add_mid(bry, 0, i);
|
||||
dirty = true;
|
||||
}
|
||||
switch (quote_byte) {
|
||||
case Byte_ascii.Apos: tmp_bfr.Add(Html_consts.Apos); break;
|
||||
case Byte_ascii.Quote: tmp_bfr.Add(Html_consts.Quote); break;
|
||||
default: throw Err_.unhandled(quote_byte);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dirty)
|
||||
tmp_bfr.Add_byte(b);
|
||||
}
|
||||
}
|
||||
return dirty ? tmp_bfr.XtoAryAndClear() : bry;
|
||||
}
|
||||
public static String Escape_html_as_str(String v) {return String_.new_utf8_(Escape_html_as_bry(Bry_.new_utf8_(v)));}
|
||||
public static byte[] Escape_html_as_bry(Bry_bfr tmp, byte[] bry) {return Escape_html(false, tmp, bry, 0, bry.length, true, true, true, true, true);}
|
||||
public static byte[] Escape_html_as_bry(byte[] bry) {return Escape_html(false, Bry_bfr.new_(), bry, 0, bry.length, true, true, true, true, true);}
|
||||
public static byte[] Escape_html_as_bry(byte[] bry, boolean lt, boolean gt, boolean amp, boolean quote, boolean apos)
|
||||
{return Escape_html(false, Bry_bfr.new_(), bry, 0, bry.length, lt, gt, amp, quote, apos);}
|
||||
|
||||
public static void Escape_html_to_bfr(Bry_bfr bfr, byte[] bry, int bgn, int end, boolean escape_lt, boolean escape_gt, boolean escape_amp, boolean escape_quote, boolean escape_apos) {
|
||||
Escape_html(true, bfr, bry, bgn, end, escape_lt, escape_gt, escape_amp, escape_quote, escape_apos);
|
||||
}
|
||||
private static byte[] Escape_html(boolean write_to_bfr, Bry_bfr bfr, byte[] bry, int bgn, int end, boolean escape_lt, boolean escape_gt, boolean escape_amp, boolean escape_quote, boolean escape_apos) {
|
||||
if (bry == null) return null;
|
||||
boolean dirty = write_to_bfr ? true : false; // if write_to_bfr, then mark true, else bfr.Add_mid(bry, 0, i); will write whole bry again
|
||||
byte[] escaped = null;
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = bry[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Lt: if (escape_lt) escaped = Html_consts.Lt; break;
|
||||
case Byte_ascii.Gt: if (escape_gt) escaped = Html_consts.Gt; break;
|
||||
case Byte_ascii.Amp: if (escape_amp) escaped = Html_consts.Amp; break;
|
||||
case Byte_ascii.Quote: if (escape_quote) escaped = Html_consts.Quote; break;
|
||||
case Byte_ascii.Apos: if (escape_apos) escaped = Html_consts.Apos; break;
|
||||
default:
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
continue;
|
||||
}
|
||||
// handle lt, gt, amp, quote; everything else handled by default: continue above
|
||||
if (escaped == null) { // handle do-not-escape calls; EX: Escape(y, y, n, y);
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
}
|
||||
else {
|
||||
if (!dirty) {
|
||||
bfr.Add_mid(bry, bgn, i);
|
||||
dirty = true;
|
||||
}
|
||||
bfr.Add(escaped);
|
||||
escaped = null;
|
||||
}
|
||||
}
|
||||
if (write_to_bfr)
|
||||
return null;
|
||||
else
|
||||
return dirty ? bfr.XtoAryAndClear() : bry;
|
||||
}
|
||||
|
||||
private static final ByteTrieMgr_slim unescape_trie = ByteTrieMgr_slim.ci_ascii_()
|
||||
.Add_bry_bval(Html_consts.Lt , Byte_ascii.Lt)
|
||||
.Add_bry_bval(Html_consts.Gt , Byte_ascii.Gt)
|
||||
.Add_bry_bval(Html_consts.Amp , Byte_ascii.Amp)
|
||||
.Add_bry_bval(Html_consts.Quote , Byte_ascii.Quote)
|
||||
.Add_bry_bval(Html_consts.Apos , Byte_ascii.Apos)
|
||||
;
|
||||
public static String Unescape_as_str(String src) {
|
||||
Bry_bfr bfr = Bry_bfr.reset_(255);
|
||||
byte[] bry = Bry_.new_utf8_(src);
|
||||
Unescape(Bool_.Y, bfr, bry, 0, bry.length, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y);
|
||||
return bfr.XtoStrAndClear();
|
||||
}
|
||||
public static byte[] Unescape(boolean write_to_bfr, Bry_bfr bfr, byte[] bry, int bgn, int end, boolean escape_lt, boolean escape_gt, boolean escape_amp, boolean escape_quote, boolean escape_apos) {
|
||||
if (bry == null) return null;
|
||||
boolean dirty = write_to_bfr ? true : false; // if write_to_bfr, then mark true, else bfr.Add_mid(bry, 0, i); will write whole bry again
|
||||
int pos = bgn;
|
||||
while (pos < end) {
|
||||
byte b = bry[pos];
|
||||
Object o = unescape_trie.Match(b, bry, pos, end);
|
||||
if (o == null) {
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
++pos;
|
||||
}
|
||||
else {
|
||||
Byte_obj_val unescaped_bval = (Byte_obj_val)o;
|
||||
byte unescaped_byte = unescaped_bval.Val();
|
||||
boolean unescape = false;
|
||||
switch (unescaped_byte) {
|
||||
case Byte_ascii.Lt: if (escape_lt) unescape = true; break;
|
||||
case Byte_ascii.Gt: if (escape_gt) unescape = true; break;
|
||||
case Byte_ascii.Amp: if (escape_amp) unescape = true; break;
|
||||
case Byte_ascii.Quote: if (escape_quote) unescape = true; break;
|
||||
case Byte_ascii.Apos: if (escape_apos) unescape = true; break;
|
||||
}
|
||||
if (unescape) {
|
||||
if (!dirty) {
|
||||
bfr.Add_mid(bry, bgn, pos);
|
||||
dirty = true;
|
||||
}
|
||||
bfr.Add_byte(unescaped_byte);
|
||||
}
|
||||
else {
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
}
|
||||
pos = unescape_trie.Match_pos();
|
||||
}
|
||||
}
|
||||
if (write_to_bfr)
|
||||
return null;
|
||||
else
|
||||
return dirty ? bfr.XtoAryAndClear() : bry;
|
||||
}
|
||||
public static byte[] Del_comments(Bry_bfr bfr, byte[] src) {return Del_comments(bfr, src, 0, src.length);}
|
||||
public static byte[] Del_comments(Bry_bfr bfr, byte[] src, int pos, int end) {
|
||||
while (true) {
|
||||
if (pos >= end) break;
|
||||
int comm_bgn = Bry_finder.Find_fwd(src, Html_consts.Comm_bgn, pos); // look for <!--
|
||||
if (comm_bgn == Bry_finder.Not_found) { // not found; consume rest
|
||||
bfr.Add_mid(src, pos, end);
|
||||
break;
|
||||
}
|
||||
int comm_end = Bry_finder.Find_fwd(src, Html_consts.Comm_end, comm_bgn + Html_consts.Comm_bgn_len); // look for -->
|
||||
if (comm_end == Bry_finder.Not_found) { // not found; consume rest
|
||||
bfr.Add_mid(src, pos, end);
|
||||
break;
|
||||
}
|
||||
bfr.Add_mid(src, pos, comm_bgn); // add everything between pos and comm_bgn
|
||||
pos = comm_end + Html_consts.Comm_end_len; // reposition pos after comm_end
|
||||
}
|
||||
return bfr.XtoAryAndClear();
|
||||
}
|
||||
}
|
||||
62
400_xowa/src/gplx/html/Html_utl_tst.java
Normal file
62
400_xowa/src/gplx/html/Html_utl_tst.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Html_utl_tst {
|
||||
@Before public void init() {fxt.Clear();} private Html_utl_fxt fxt = new Html_utl_fxt();
|
||||
@Test public void Basic() {fxt.Test_del_comments("a<!-- b -->c" , "ac");}
|
||||
@Test public void Bgn_missing() {fxt.Test_del_comments("a b c" , "a b c");}
|
||||
@Test public void End_missing() {fxt.Test_del_comments("a<!-- b c" , "a<!-- b c");}
|
||||
@Test public void Multiple() {fxt.Test_del_comments("a<!--b-->c<!--d-->e" , "ace");}
|
||||
@Test public void Escape() {
|
||||
fxt.Test_escape_html(Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, "a<b" , "a<b"); // basic
|
||||
fxt.Test_escape_html(Bool_.Y, Bool_.Y, Bool_.N, Bool_.Y, Bool_.Y, "a<&b" , "a<&b"); // fix: & not escaped when <> present
|
||||
fxt.Test_escape_html(Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, "a<>'&\"b" , "a<>'&"b");
|
||||
}
|
||||
@Test public void Escape_for_atr_val() {
|
||||
fxt.Test_escape_for_atr("abc" , Bool_.N, "abc"); // basic
|
||||
fxt.Test_escape_for_atr("a'\"b" , Bool_.Y, "a'\"b"); // quote is '
|
||||
fxt.Test_escape_for_atr("a'\"b" , Bool_.N, "a'"b"); // quote is "
|
||||
}
|
||||
@Test public void Unescape() {
|
||||
fxt.Test_unescape_html(Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, Bool_.Y, "a<>'&"b" , "a<>'&\"b"); // basic
|
||||
}
|
||||
}
|
||||
class Html_utl_fxt {
|
||||
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
|
||||
public void Clear() {
|
||||
tmp_bfr.Clear();
|
||||
}
|
||||
public void Test_del_comments(String src, String expd) {
|
||||
byte[] actl = Html_utl.Del_comments(tmp_bfr, Bry_.new_utf8_(src));
|
||||
Tfds.Eq(expd, String_.new_ascii_(actl));
|
||||
}
|
||||
public void Test_escape_html(boolean lt, boolean gt, boolean amp, boolean quote, boolean apos, String src, String expd) {
|
||||
byte[] actl = Html_utl.Escape_html_as_bry(Bry_.new_ascii_(src), lt, gt, amp, quote, apos);
|
||||
Tfds.Eq(expd, String_.new_ascii_(actl));
|
||||
}
|
||||
public void Test_escape_for_atr(String src, boolean quote_is_apos, String expd) {
|
||||
byte[] actl = Html_utl.Escape_for_atr_val_as_bry(src, quote_is_apos ? Byte_ascii.Apos : Byte_ascii.Quote);
|
||||
Tfds.Eq(expd, String_.new_utf8_(actl));
|
||||
}
|
||||
public void Test_unescape_html(boolean lt, boolean gt, boolean amp, boolean quote, boolean apos, String src, String expd) {
|
||||
byte[] bry = Bry_.new_utf8_(src);
|
||||
byte[] actl = Html_utl.Unescape(false, tmp_bfr, bry, 0, bry.length, lt, gt, amp, quote, apos);
|
||||
Tfds.Eq(expd, String_.new_ascii_(actl));
|
||||
}
|
||||
}
|
||||
98
400_xowa/src/gplx/html/Html_wtr.java
Normal file
98
400_xowa/src/gplx/html/Html_wtr.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.html; import gplx.*;
|
||||
public class Html_wtr {
|
||||
private Bry_bfr bfr = Bry_bfr.reset_(255);
|
||||
private ListAdp nde_stack = ListAdp_.new_();
|
||||
public byte Atr_quote() {return atr_quote;} public Html_wtr Atr_quote_(byte v) {atr_quote = v; return this;} private byte atr_quote = Byte_ascii.Quote;
|
||||
public Html_wtr Nde_full_atrs(byte[] tag, byte[] text, boolean text_escape, byte[]... atrs) {
|
||||
Nde_bgn(tag);
|
||||
int atrs_len = atrs.length;
|
||||
for (int i = 0; i < atrs_len; i += 2) {
|
||||
byte[] key = atrs[i];
|
||||
byte[] val = atrs[i + 1];
|
||||
Atr(key, val);
|
||||
}
|
||||
Nde_end_hdr();
|
||||
if (text_escape)
|
||||
Txt(text);
|
||||
else
|
||||
bfr.Add(text);
|
||||
Nde_end();
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Nde_full(byte[] tag, byte[] text) {
|
||||
Nde_bgn_hdr(tag);
|
||||
Txt(text);
|
||||
Nde_end();
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Txt_mid(byte[] src, int bgn, int end) {bfr.Add_mid(src, bgn, end); return this;}
|
||||
public Html_wtr Txt_byte(byte v) {bfr.Add_byte(v); return this;}
|
||||
public Html_wtr Txt_raw(byte[] v) {bfr.Add(v); return this;}
|
||||
public Html_wtr Txt(byte[] v) {
|
||||
if (v != null) {
|
||||
bfr.Add(Html_utl.Escape_html_as_bry(v));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Nde_bgn_hdr(byte[] name) {
|
||||
this.Nde_bgn(name);
|
||||
this.Nde_end_hdr();
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Nde_bgn(byte[] name) {
|
||||
bfr.Add_byte(Byte_ascii.Lt);
|
||||
bfr.Add(name);
|
||||
nde_stack.Add(name);
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Atr(byte[] key, byte[] val) {
|
||||
Write_atr(bfr, atr_quote, key, val);
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Nde_end_inline() {
|
||||
bfr.Add_byte(Byte_ascii.Slash).Add_byte(Byte_ascii.Gt);
|
||||
nde_stack.PopLast();
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Nde_end_hdr() {
|
||||
bfr.Add_byte(Byte_ascii.Gt);
|
||||
return this;
|
||||
}
|
||||
public Html_wtr Nde_end() {
|
||||
byte[] name = (byte[])nde_stack.PopLast();
|
||||
bfr.Add_byte(Byte_ascii.Lt).Add_byte(Byte_ascii.Slash);
|
||||
bfr.Add(name);
|
||||
bfr.Add_byte(Byte_ascii.Gt);
|
||||
return this;
|
||||
}
|
||||
public byte[] X_to_bry_and_clear() {return bfr.XtoAryAndClear();}
|
||||
public byte[] X_to_bry() {return bfr.XtoAry();}
|
||||
public String X_to_str() {return bfr.XtoStr();}
|
||||
public static void Write_atr(Bry_bfr bfr, byte[] key, byte[] val) {Write_atr(bfr, Byte_ascii.Quote, key, val);}
|
||||
public static void Write_atr(Bry_bfr bfr, byte atr_quote, byte[] key, byte[] val) {
|
||||
if (Bry_.Len_eq_0(val)) return; // don't write empty
|
||||
bfr.Add_byte_space();
|
||||
bfr.Add(key);
|
||||
bfr.Add_byte(Byte_ascii.Eq);
|
||||
bfr.Add_byte(atr_quote);
|
||||
Html_utl.Escape_html_to_bfr(bfr, val, 0, val.length, false, false, false, true, true);
|
||||
bfr.Add_byte(atr_quote);
|
||||
}
|
||||
}
|
||||
66
400_xowa/src/gplx/ios/Io_stream_rdr_process.java
Normal file
66
400_xowa/src/gplx/ios/Io_stream_rdr_process.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.ios; import gplx.*;
|
||||
import java.io.InputStream;
|
||||
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_bzip2;} // for now, classify as bzip2; not sure if separate tid is necessary
|
||||
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_.err_(e, "process init failed: {0} {1}", String_.AryXtoStr(process_args), Err_.Message_gplx_brief(e));}
|
||||
stream_read = process.getInputStream();
|
||||
return this;
|
||||
}
|
||||
public void Open_mem(byte[] v) {throw Err_.not_implemented_();}
|
||||
public Object Under() {throw Err_.not_implemented_();}
|
||||
|
||||
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_.err_(e, "process read failed: bgn={0} len={1} err={2}", bgn, len, Err_.Message_gplx_brief(e));}
|
||||
}
|
||||
public long Skip(long len) {
|
||||
try {return stream_read.skip(len);}
|
||||
catch (Exception e) {throw Err_.err_(e, "process skip failed: len={0} err={1}", len, Err_.Message_gplx_brief(e));}
|
||||
}
|
||||
public void Rls() {
|
||||
try {stream_read.close();}
|
||||
catch (Exception e) {throw Err_.err_(e, "process rls failed: err={0}", Err_.Message_gplx_brief(e));}
|
||||
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);}
|
||||
}
|
||||
54
400_xowa/src/gplx/ios/Io_stream_zip_mgr.java
Normal file
54
400_xowa/src/gplx/ios/Io_stream_zip_mgr.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.ios; import gplx.*;
|
||||
public class Io_stream_zip_mgr {
|
||||
private Bry_bfr bfr = Bry_bfr.reset_(256);
|
||||
private Io_stream_wtr wtr_gzip, wtr_zip, wtr_bzip2;
|
||||
private Io_stream_rdr rdr_gzip, rdr_zip, rdr_bzip2;
|
||||
public byte[] Zip(byte type, byte[] val) {
|
||||
if (type == Io_stream_.Tid_file) return val;
|
||||
Io_stream_wtr wtr = Wtr(type);
|
||||
wtr.Write(val, 0, val.length);
|
||||
wtr.Flush();
|
||||
return wtr.Xto_ary_and_clear();
|
||||
}
|
||||
public byte[] Unzip(byte type, byte[] val) {
|
||||
if (type == Io_stream_.Tid_file) return val;
|
||||
Io_stream_rdr rdr = Rdr(type);
|
||||
rdr.Open_mem(val);
|
||||
return Io_stream_rdr_.Load_all_as_bry(bfr, rdr);
|
||||
}
|
||||
private Io_stream_wtr Wtr(byte type) {
|
||||
switch (type) {
|
||||
case Io_stream_.Tid_gzip : if (wtr_gzip == null) wtr_gzip = Io_stream_wtr_.new_by_mem(bfr, Io_stream_.Tid_gzip) ; return wtr_gzip.Open();
|
||||
case Io_stream_.Tid_zip : if (wtr_zip == null) wtr_zip = Io_stream_wtr_.new_by_mem(bfr, Io_stream_.Tid_zip) ; return wtr_zip.Open();
|
||||
case Io_stream_.Tid_bzip2 : if (wtr_bzip2 == null) wtr_bzip2 = Io_stream_wtr_.new_by_mem(bfr, Io_stream_.Tid_bzip2) ; return wtr_bzip2.Open();
|
||||
case Io_stream_.Tid_file :
|
||||
default : throw Err_.unhandled(type);
|
||||
}
|
||||
}
|
||||
private Io_stream_rdr Rdr(byte type) {
|
||||
switch (type) {
|
||||
case Io_stream_.Tid_gzip : if (rdr_gzip == null) rdr_gzip = Io_stream_rdr_.new_by_tid_(Io_stream_.Tid_gzip) ; return rdr_gzip;
|
||||
case Io_stream_.Tid_zip : if (rdr_zip == null) rdr_zip = Io_stream_rdr_.new_by_tid_(Io_stream_.Tid_zip) ; return rdr_zip;
|
||||
case Io_stream_.Tid_bzip2 : if (rdr_bzip2 == null) rdr_bzip2 = Io_stream_rdr_.new_by_tid_(Io_stream_.Tid_bzip2) ; return rdr_bzip2;
|
||||
case Io_stream_.Tid_file :
|
||||
default : throw Err_.unhandled(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
400_xowa/src/gplx/json/Json_doc.java
Normal file
65
400_xowa/src/gplx/json/Json_doc.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_doc {
|
||||
public void Ctor(byte[] src, Json_itm_nde root) {this.src = src; this.root = root;}
|
||||
public Bry_bfr Bfr() {return bfr;} Bry_bfr bfr = Bry_bfr.new_();
|
||||
public NumberParser Utl_num_parser() {return utl_num_parser;} NumberParser utl_num_parser = new NumberParser();
|
||||
public byte[] Str_utf8_bry() {return str_utf8_bry;} private byte[] str_utf8_bry = new byte[6];
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public Json_itm_nde Root() {return root;} Json_itm_nde root;
|
||||
public byte[] Get_val_as_bry_or(byte[] qry_bry, byte[] or) {tmp_qry_bry[0] = qry_bry; return Get_val_as_bry_or(tmp_qry_bry, or);}
|
||||
public byte[] Get_val_as_bry_or(byte[][] qry_bry, byte[] or) {
|
||||
Json_itm nde = Find_nde(root, qry_bry, qry_bry.length - 1, 0);
|
||||
return nde == null || nde.Tid() != Json_itm_.Tid_string ? or : nde.Data_bry();
|
||||
}
|
||||
public String Get_val_as_str_or(byte[] qry_bry, String or) {tmp_qry_bry[0] = qry_bry; return Get_val_as_str_or(tmp_qry_bry, or);}
|
||||
public String Get_val_as_str_or(byte[][] qry_bry, String or) {
|
||||
Json_itm nde = Find_nde(root, qry_bry, qry_bry.length - 1, 0);
|
||||
return nde == null || nde.Tid() != Json_itm_.Tid_string ? or : (String)nde.Data();
|
||||
}
|
||||
public Json_grp Get_grp(byte[] qry_bry) {
|
||||
tmp_qry_bry[0] = qry_bry;
|
||||
Json_itm rv = Find_nde(root, tmp_qry_bry, 0, 0); if (rv == null) return null;
|
||||
return (Json_grp)rv;
|
||||
} byte[][] tmp_qry_bry = new byte[1][];
|
||||
public Json_grp Get_grp(byte[][] qry_bry) {
|
||||
Json_itm rv = Find_nde(root, qry_bry, qry_bry.length - 1, 0); if (rv == null) return null;
|
||||
return (Json_grp)rv;
|
||||
}
|
||||
public Json_itm Find_nde(byte[] key) {
|
||||
tmp_qry_bry[0] = key;
|
||||
return Find_nde(root, tmp_qry_bry, 0, 0);
|
||||
}
|
||||
private Json_itm Find_nde(Json_itm_nde owner, byte[][] paths, int paths_last, int paths_idx) {
|
||||
byte[] path = paths[paths_idx];
|
||||
int subs_len = owner.Subs_len();
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Json_itm_kv itm = Json_itm_kv.cast_(owner.Subs_get_at(i)); if (itm == null) continue; // ignore simple props, arrays, ndes
|
||||
if (!itm.Key_eq(path)) continue;
|
||||
if (paths_idx == paths_last) return itm.Val();
|
||||
Json_itm_nde sub_nde = Json_itm_nde.cast_(itm.Val()); if (sub_nde == null) return null; // match, but has not a nde; exit
|
||||
return Find_nde(sub_nde, paths, paths_last, paths_idx + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static Json_doc new_apos_concat_nl(String... ary) {return new_apos_(String_.Concat_lines_nl(ary));}
|
||||
public static Json_doc new_apos_(String v) {return new_(Bry_.Replace(Bry_.new_utf8_(v), Byte_ascii.Apos, Byte_ascii.Quote));}
|
||||
public static Json_doc new_(String v) {return new_(Bry_.new_utf8_(v));}
|
||||
public static Json_doc new_(byte[] v) {return parser.Parse(v);} static Json_parser parser = new Json_parser();
|
||||
}
|
||||
42
400_xowa/src/gplx/json/Json_doc_bldr.java
Normal file
42
400_xowa/src/gplx/json/Json_doc_bldr.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_doc_bldr {
|
||||
public Json_itm_nde Nde() {return factory.Nde(-1);}
|
||||
public Json_itm_nde Nde(Json_grp owner) {
|
||||
Json_itm_nde rv = factory.Nde(-1);
|
||||
owner.Subs_add(rv);
|
||||
return rv;
|
||||
}
|
||||
public Json_itm Str(byte[] v) {return Str(String_.new_utf8_(v));}
|
||||
public Json_itm Str(String v) {return Json_itm_tmp.new_str_(v);}
|
||||
public Json_itm Int(int v) {return Json_itm_tmp.new_int_(v);}
|
||||
public Json_itm_kv Kv_int(Json_grp owner, String key, int val) {Json_itm_kv rv = factory.Kv(Json_itm_tmp.new_str_(key), Json_itm_tmp.new_int_(val)); owner.Subs_add(rv); return rv;}
|
||||
public Json_itm_kv Kv_str(Json_grp owner, String key, String val) {Json_itm_kv rv = factory.Kv(Json_itm_tmp.new_str_(key), Json_itm_tmp.new_str_(val)); owner.Subs_add(rv); return rv;}
|
||||
public Json_itm_ary Kv_ary(Json_grp owner, String key, Json_itm... subs) {
|
||||
Json_itm key_itm = Json_itm_tmp.new_str_(key);
|
||||
Json_itm_ary val_ary = factory.Ary(-1, -1);
|
||||
Json_itm_kv kv = factory.Kv(key_itm, val_ary);
|
||||
owner.Subs_add(kv);
|
||||
int len = subs.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
val_ary.Subs_add(subs[i]);
|
||||
return val_ary;
|
||||
}
|
||||
Json_doc doc = new Json_doc(); Json_factory factory = new Json_factory();
|
||||
}
|
||||
89
400_xowa/src/gplx/json/Json_doc_srl.java
Normal file
89
400_xowa/src/gplx/json/Json_doc_srl.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_doc_srl {
|
||||
private int indent = -1;
|
||||
private Bry_bfr bfr = Bry_bfr.reset_(255);
|
||||
public boolean Ws_enabled() {return ws_enabled;} public void Ws_enabled_(boolean v) {ws_enabled = v;} private boolean ws_enabled = false;
|
||||
public byte[] Bld() {return bfr.XtoAryAndClear();}
|
||||
public String Bld_as_str() {return bfr.XtoStrAndClear();}
|
||||
public Json_doc_srl Write_root(byte[] key, Object val) {
|
||||
Write_nde_bgn();
|
||||
Write_obj(false, key, val);
|
||||
Write_nde_end();
|
||||
return this;
|
||||
}
|
||||
public void Write_obj(boolean comma, byte[] key, Object val) {
|
||||
Class<?> t = ClassAdp_.ClassOf_obj(val);
|
||||
if (ClassAdp_.Is_array(t))
|
||||
Write_kv_ary(comma, key, (Object[])val);
|
||||
else
|
||||
Write_kv_str(comma, key, Object_.XtoStr_OrEmpty(val));
|
||||
}
|
||||
private void Write_kv_ary(boolean comma, byte[] key, Object[] val) {
|
||||
Write_key(comma, key); Write_new_line(); // '"key":\n'
|
||||
Write_ary_bgn(); // '[\n'
|
||||
Indent_add(); // -->
|
||||
int len = val.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Write_itm_hdr(i != 0); // ', '
|
||||
Write_str(Bry_.new_utf8_(Object_.XtoStr_OrNull(val[i])));
|
||||
Write_new_line();
|
||||
}
|
||||
Indent_del();
|
||||
Write_ary_end();
|
||||
}
|
||||
private void Write_kv_str(boolean comma, byte[] key, String val) {
|
||||
Write_key(comma, key); // "key":
|
||||
Write_str(Bry_.new_utf8_(val)); // "val"
|
||||
Write_new_line(); // \n
|
||||
}
|
||||
private void Write_key(boolean comma, byte[] key) { // "key":
|
||||
Write_indent();
|
||||
Write_str(key);
|
||||
bfr.Add_byte(Byte_ascii.Colon);
|
||||
}
|
||||
private void Write_indent() {if (ws_enabled && indent > 0) bfr.Add_byte_repeat(Byte_ascii.Space, indent);}
|
||||
private void Write_str(byte[] v) {
|
||||
if (v == null)
|
||||
bfr.Add(Bry_null);
|
||||
else
|
||||
bfr.Add_byte(Byte_ascii.Quote).Add(v).Add_byte(Byte_ascii.Quote);
|
||||
} private static final byte[] Bry_null = Bry_.new_ascii_("null");
|
||||
private void Write_comma(boolean comma) {
|
||||
if (comma)
|
||||
bfr.Add_byte(Byte_ascii.Comma);
|
||||
else {
|
||||
if (ws_enabled)
|
||||
bfr.Add_byte(Byte_ascii.Space);
|
||||
}
|
||||
if (ws_enabled)
|
||||
bfr.Add_byte(Byte_ascii.Space);
|
||||
}
|
||||
private void Write_ary_bgn() {Indent_add(); Write_indent(); bfr.Add_byte(Byte_ascii.Brack_bgn); Write_new_line();}
|
||||
private void Write_ary_end() { Write_indent(); bfr.Add_byte(Byte_ascii.Brack_end); Write_new_line(); Indent_del();}
|
||||
private void Write_nde_bgn() {Indent_add(); Write_indent(); bfr.Add_byte(Byte_ascii.Curly_bgn); Write_new_line();}
|
||||
private void Write_nde_end() { Write_indent(); bfr.Add_byte(Byte_ascii.Curly_end); Write_new_line(); Indent_del();}
|
||||
private void Write_itm_hdr(boolean comma) {
|
||||
Write_indent();
|
||||
Write_comma(comma);
|
||||
}
|
||||
private void Indent_add() {indent += 2;}
|
||||
private void Indent_del() {indent -= 2;}
|
||||
private void Write_new_line() {if (ws_enabled) bfr.Add_byte_nl();}
|
||||
}
|
||||
45
400_xowa/src/gplx/json/Json_doc_tst.java
Normal file
45
400_xowa/src/gplx/json/Json_doc_tst.java
Normal file
@@ -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.json; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Json_doc_tst {
|
||||
Json_qry_mgr_fxt fxt = new Json_qry_mgr_fxt();
|
||||
@Before public void init() {}
|
||||
@Test public void Select() {
|
||||
Json_doc doc = Json_doc.new_apos_(String_.Concat_lines_nl
|
||||
( "{'0':"
|
||||
, " {'0_0':"
|
||||
, " {'0_0_0':'000'"
|
||||
, " },"
|
||||
, " '0_1':"
|
||||
, " {'0_1_0':'010'"
|
||||
, " }"
|
||||
, " }"
|
||||
, "}"
|
||||
));
|
||||
fxt.Test_get_val_as_str(doc, "0/0_0/0_0_0", "000");
|
||||
fxt.Test_get_val_as_str(doc, "0/0_1/0_1_0", "010");
|
||||
fxt.Test_get_val_as_str(doc, "x", null);
|
||||
}
|
||||
}
|
||||
class Json_qry_mgr_fxt {
|
||||
public void Test_get_val_as_str(Json_doc doc, String qry, String expd){
|
||||
byte[][] qry_bry = Bry_.Split(Bry_.new_utf8_(qry), Byte_ascii.Slash);
|
||||
Tfds.Eq(expd, doc.Get_val_as_str_or(qry_bry, null));
|
||||
}
|
||||
}
|
||||
98
400_xowa/src/gplx/json/Json_doc_wtr.java
Normal file
98
400_xowa/src/gplx/json/Json_doc_wtr.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_doc_wtr {
|
||||
private int indent = -2;
|
||||
private Bry_bfr bfr = Bry_bfr.reset_(255);
|
||||
public Json_doc_wtr Indent() {return Indent(indent);}
|
||||
private Json_doc_wtr Indent(int v) {if (v > 0) bfr.Add_byte_repeat(Byte_ascii.Space, v); return this;}
|
||||
public Json_doc_wtr Indent_add() {indent += 2; return this;}
|
||||
public Json_doc_wtr Indent_del() {indent -= 2; return this;}
|
||||
public Json_doc_wtr Nde_bgn() {Indent_add(); Indent(); bfr.Add_byte(Byte_ascii.Curly_bgn).Add_byte_nl(); return this;}
|
||||
public Json_doc_wtr Nde_end() { Indent(); bfr.Add_byte(Byte_ascii.Curly_end).Add_byte_nl(); Indent_del(); return this;}
|
||||
public Json_doc_wtr Ary_bgn() {Indent_add(); Indent(); bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte_nl(); return this;}
|
||||
public Json_doc_wtr Ary_end() { Indent(); bfr.Add_byte(Byte_ascii.Brack_end).Add_byte_nl(); Indent_del(); return this;}
|
||||
public Json_doc_wtr New_line() {bfr.Add_byte_nl(); return this;}
|
||||
public Json_doc_wtr Str(byte[] v) {
|
||||
if (v == null)
|
||||
bfr.Add(Bry_null);
|
||||
else
|
||||
bfr.Add_byte(Byte_ascii.Quote).Add(v).Add_byte(Byte_ascii.Quote);
|
||||
return this;
|
||||
} private static final byte[] Bry_null = Bry_.new_ascii_("null");
|
||||
public Json_doc_wtr Int(int v) {bfr.Add_int_variable(v); return this;}
|
||||
public Json_doc_wtr Double(double v) {bfr.Add_double(v); return this;}
|
||||
public Json_doc_wtr Comma() {Indent(); bfr.Add_byte(Byte_ascii.Comma).Add_byte_nl(); return this;}
|
||||
public Json_doc_wtr Kv_ary_empty(boolean comma, byte[] key) {
|
||||
Key_internal(comma, key);
|
||||
bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte(Byte_ascii.Brack_end);
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Kv(boolean comma, byte[] key, byte[] val) {
|
||||
Key_internal(comma, key);
|
||||
Str(val);
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Kv_double(boolean comma, byte[] key, double v) {
|
||||
Key_internal(comma, key);
|
||||
Double(v);
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Kv(boolean comma, byte[] key, int v) {
|
||||
Key_internal(comma, key);
|
||||
Int(v);
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Key(boolean comma, byte[] key) {
|
||||
Key_internal(comma, key);
|
||||
bfr.Add_byte_nl();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Val(boolean comma, int v) {
|
||||
Val_internal(comma);
|
||||
Int(v);
|
||||
New_line();
|
||||
return this;
|
||||
}
|
||||
public Json_doc_wtr Val(boolean comma, byte[] v) {
|
||||
Val_internal(comma);
|
||||
Str(v);
|
||||
New_line();
|
||||
return this;
|
||||
}
|
||||
Json_doc_wtr Val_internal(boolean comma) {
|
||||
Indent();
|
||||
bfr.Add_byte(comma ? Byte_ascii.Comma : Byte_ascii.Space);
|
||||
bfr.Add_byte(Byte_ascii.Space);
|
||||
return this;
|
||||
}
|
||||
Json_doc_wtr Key_internal(boolean comma, byte[] key) {
|
||||
Indent();
|
||||
bfr.Add_byte(comma ? Byte_ascii.Comma : Byte_ascii.Space);
|
||||
bfr.Add_byte(Byte_ascii.Space);
|
||||
Str(key);
|
||||
bfr.Add_byte(Byte_ascii.Colon);
|
||||
return this;
|
||||
}
|
||||
public byte[] Bld() {return bfr.XtoAryAndClear();}
|
||||
public String Bld_as_str() {return bfr.XtoStrAndClear();}
|
||||
}
|
||||
29
400_xowa/src/gplx/json/Json_factory.java
Normal file
29
400_xowa/src/gplx/json/Json_factory.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_factory {
|
||||
public Json_itm Null() {return Json_itm_null.Null;}
|
||||
public Json_itm Bool_n() {return Json_itm_bool.Bool_n;}
|
||||
public Json_itm Bool_y() {return Json_itm_bool.Bool_y;}
|
||||
public Json_itm_int Int(Json_doc doc, int bgn, int end) {return new Json_itm_int(doc, bgn, end);}
|
||||
public Json_itm Decimal(Json_doc doc, int bgn, int end) {return new Json_itm_decimal(doc, bgn, end);}
|
||||
public Json_itm Str(Json_doc doc, int bgn, int end, boolean exact) {return new Json_itm_str(doc, bgn, end, exact);}
|
||||
public Json_itm_kv Kv(Json_itm key, Json_itm val) {return new Json_itm_kv(key, val);}
|
||||
public Json_itm_ary Ary(int bgn, int end) {return new Json_itm_ary(bgn, end);}
|
||||
public Json_itm_nde Nde(int bgn) {return new Json_itm_nde(bgn);}
|
||||
}
|
||||
34
400_xowa/src/gplx/json/Json_grp.java
Normal file
34
400_xowa/src/gplx/json/Json_grp.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public interface Json_grp extends Json_itm {
|
||||
void Src_end_(int v);
|
||||
int Subs_len();
|
||||
Json_itm Subs_get_at(int i);
|
||||
void Subs_add(Json_itm itm);
|
||||
}
|
||||
class Json_grp_ {
|
||||
public static final Json_grp[] Ary_empty = new Json_grp[0];
|
||||
public static void Print_nl(Bry_bfr bfr) { // \n\n can be caused by nested groups (EX: "[[]]"); only print 1
|
||||
if (bfr.Bfr()[bfr.Len() - 1] != Byte_ascii.NewLine)
|
||||
bfr.Add_byte_nl();
|
||||
}
|
||||
public static void Print_indent(Bry_bfr bfr, int depth) {
|
||||
if (depth > 0) bfr.Add_byte_repeat(Byte_ascii.Space, depth * 2); // indent
|
||||
}
|
||||
}
|
||||
116
400_xowa/src/gplx/json/Json_itm.java
Normal file
116
400_xowa/src/gplx/json/Json_itm.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public interface Json_itm {
|
||||
byte Tid();
|
||||
int Src_bgn();
|
||||
int Src_end();
|
||||
Object Data();
|
||||
byte[] Data_bry();
|
||||
void Print_as_json(Bry_bfr bfr, int depth);
|
||||
boolean Data_eq(byte[] comp);
|
||||
}
|
||||
class Json_itm_null extends Json_itm_base {
|
||||
Json_itm_null() {this.Ctor(-1, -1);}
|
||||
@Override public byte Tid() {return Json_itm_.Tid_null;}
|
||||
@Override public Object Data() {return null;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add(Bry_null);}
|
||||
@Override public byte[] Data_bry() {return Bry_null;}
|
||||
private static final byte[] Bry_null = Bry_.new_ascii_("null");
|
||||
public static Json_itm_null Null = new Json_itm_null();
|
||||
}
|
||||
class Json_itm_bool extends Json_itm_base {
|
||||
public Json_itm_bool(boolean data) {this.data = data; this.Ctor(-1, -1);} private boolean data;
|
||||
@Override public byte Tid() {return Json_itm_.Tid_bool;}
|
||||
@Override public Object Data() {return data;}
|
||||
@Override public byte[] Data_bry() {return data ? Json_itm_.Const_true : Json_itm_.Const_false;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add(data ? Json_itm_.Const_true: Json_itm_.Const_false);}
|
||||
public static Json_itm_bool Bool_n = new Json_itm_bool(false), Bool_y = new Json_itm_bool(true);
|
||||
}
|
||||
class Json_itm_decimal extends Json_itm_base {
|
||||
public Json_itm_decimal(Json_doc doc, int src_bgn, int src_end) {this.Ctor(src_bgn, src_end); this.doc = doc;} Json_doc doc;
|
||||
@Override public byte Tid() {return Json_itm_.Tid_decimal;}
|
||||
@Override public Object Data() {
|
||||
if (data == null)
|
||||
data = DecimalAdp_.parse_(String_.new_ascii_(this.Data_bry()));
|
||||
return data;
|
||||
} DecimalAdp data;
|
||||
@Override public byte[] Data_bry() {
|
||||
if (data_bry == null) data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end());
|
||||
return data_bry;
|
||||
} byte[] data_bry;
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());}
|
||||
}
|
||||
class Json_itm_str extends Json_itm_base {
|
||||
public Json_itm_str(Json_doc doc, int src_bgn, int src_end, boolean exact) {this.Ctor(src_bgn + 1, src_end - 1); this.doc = doc; this.exact = exact;} private boolean exact; Json_doc doc;
|
||||
@Override public byte Tid() {return Json_itm_.Tid_string;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
bfr.Add_byte(Byte_ascii.Quote);
|
||||
gplx.html.Html_utl.Escape_html_to_bfr(bfr, doc.Src(), this.Src_bgn(), this.Src_end(), true, true, true, true, false); // false to apos for backwards compatibility
|
||||
bfr.Add_byte(Byte_ascii.Quote);
|
||||
}
|
||||
@Override public Object Data() {
|
||||
if (data_str == null) {
|
||||
if (data_bry == null)
|
||||
data_bry = Data_make_bry();
|
||||
data_str = String_.new_utf8_(data_bry);
|
||||
}
|
||||
return data_str;
|
||||
} private String data_str;
|
||||
@Override public byte[] Data_bry() {if (data_bry == null) data_bry = Data_make_bry(); return data_bry;}
|
||||
@Override public boolean Data_eq(byte[] comp) {
|
||||
if (exact) return Bry_.Eq(comp, doc.Src(), this.Src_bgn(), this.Src_end());
|
||||
if (data_bry == null) data_bry = Data_make_bry();
|
||||
return Bry_.Match(data_bry, comp);
|
||||
} byte[] data_bry = null;
|
||||
private byte[] Data_make_bry() {
|
||||
byte[] src = doc.Src(); int bgn = this.Src_bgn(), end = this.Src_end();
|
||||
if (exact) return Bry_.Mid(src, bgn, end);
|
||||
Bry_bfr bfr = doc.Bfr();
|
||||
byte[] utf8_bry = doc.Str_utf8_bry();
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Backslash:
|
||||
b = src[++i];
|
||||
switch (b) { // NOTE: must properly unescape chars; EX:wd.q:2; DATE:2014-04-23
|
||||
case Byte_ascii.Ltr_t: bfr.Add_byte(Byte_ascii.Tab); break;
|
||||
case Byte_ascii.Ltr_n: bfr.Add_byte(Byte_ascii.NewLine); break;
|
||||
case Byte_ascii.Ltr_r: bfr.Add_byte(Byte_ascii.CarriageReturn); break;
|
||||
case Byte_ascii.Ltr_b: bfr.Add_byte(Byte_ascii.Backfeed); break;
|
||||
case Byte_ascii.Ltr_f: bfr.Add_byte(Byte_ascii.Formfeed); break;
|
||||
case Byte_ascii.Ltr_u:
|
||||
int utf8_val = gplx.texts.HexDecUtl.parse_or_(src, i + 1, i + 5, -1);
|
||||
int len = gplx.intl.Utf16_.Encode_int(utf8_val, utf8_bry, 0);
|
||||
bfr.Add_mid(utf8_bry, 0, len);
|
||||
i += 4;
|
||||
break; // \uFFFF 4 hex-dec
|
||||
case Byte_ascii.Backslash:
|
||||
case Byte_ascii.Slash:
|
||||
default:
|
||||
bfr.Add_byte(b); break; // \? " \ / b f n r t
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bfr.Add_byte(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bfr.XtoAryAndClear();
|
||||
}
|
||||
}
|
||||
24
400_xowa/src/gplx/json/Json_itm_.java
Normal file
24
400_xowa/src/gplx/json/Json_itm_.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_itm_ {
|
||||
public static final Json_itm[] Ary_empty = new Json_itm[0];
|
||||
public static final byte Tid_unknown = 0, Tid_null = 1, Tid_bool = 2, Tid_int = 3, Tid_decimal = 4, Tid_string = 5, Tid_kv = 6, Tid_array = 7, Tid_nde = 8;
|
||||
public static final byte[][] Names = Bry_.Ary("unknown", "null", "boolean", "int", "decimal", "string", "keyval", "array", "nde");
|
||||
public static final byte[] Const_true = Bry_.new_ascii_("true"), Const_false = Bry_.new_ascii_("false"), Const_null = Bry_.new_ascii_("null");
|
||||
}
|
||||
64
400_xowa/src/gplx/json/Json_itm_ary.java
Normal file
64
400_xowa/src/gplx/json/Json_itm_ary.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_itm_ary extends Json_itm_base implements Json_grp {
|
||||
public Json_itm_ary(int src_bgn, int src_end) {this.Ctor(src_bgn, src_end);}
|
||||
@Override public byte Tid() {return Json_itm_.Tid_array;}
|
||||
public void Src_end_(int v) {this.src_end = v;}
|
||||
@Override public Object Data() {return null;}
|
||||
@Override public byte[] Data_bry() {return null;}
|
||||
public int Subs_len() {return subs_len;} private int subs_len = 0, subs_max = 0;
|
||||
public Json_itm Subs_get_at(int i) {return subs[i];}
|
||||
public Json_itm_ary Subs_add_many(Json_itm... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Subs_add(ary[i]);
|
||||
return this;
|
||||
}
|
||||
public void Subs_add(Json_itm itm) {
|
||||
int new_len = subs_len + 1;
|
||||
if (new_len > subs_max) { // ary too small >>> expand
|
||||
subs_max = new_len * 2;
|
||||
Json_itm[] new_subs = new Json_itm[subs_max];
|
||||
Array_.CopyTo(subs, 0, new_subs, 0, subs_len);
|
||||
subs = new_subs;
|
||||
}
|
||||
subs[subs_len] = itm;
|
||||
subs_len = new_len;
|
||||
}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
if (subs_len == 0) { // empty grp; print on one line (rather than printing across 3)
|
||||
bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte(Byte_ascii.Brack_end);
|
||||
return;
|
||||
}
|
||||
bfr.Add_byte_nl();
|
||||
Json_grp_.Print_indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Brack_bgn).Add_byte(Byte_ascii.Space);
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
if (i != 0) {
|
||||
Json_grp_.Print_nl(bfr); Json_grp_.Print_indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Comma).Add_byte(Byte_ascii.Space);
|
||||
}
|
||||
subs[i].Print_as_json(bfr, depth + 1);
|
||||
}
|
||||
Json_grp_.Print_nl(bfr); Json_grp_.Print_indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Brack_end).Add_byte_nl();
|
||||
}
|
||||
Json_itm[] subs = Json_itm_.Ary_empty;
|
||||
public static Json_itm_ary cast_(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid_array ? null : (Json_itm_ary)v;}
|
||||
}
|
||||
29
400_xowa/src/gplx/json/Json_itm_base.java
Normal file
29
400_xowa/src/gplx/json/Json_itm_base.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public abstract class Json_itm_base implements Json_itm {
|
||||
public abstract byte Tid();
|
||||
public void Ctor(int src_bgn, int src_end) {this.src_bgn = src_bgn; this.src_end = src_end;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} protected int src_end;
|
||||
public abstract Object Data();
|
||||
public abstract byte[] Data_bry();
|
||||
public String Print_as_json() {Bry_bfr bfr = Bry_bfr.new_(); Print_as_json(bfr, 0); return bfr.XtoStrAndClear();}
|
||||
public abstract void Print_as_json(Bry_bfr bfr, int depth);
|
||||
@gplx.Virtual public boolean Data_eq(byte[] comp) {return false;}
|
||||
}
|
||||
33
400_xowa/src/gplx/json/Json_itm_int.java
Normal file
33
400_xowa/src/gplx/json/Json_itm_int.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_itm_int extends Json_itm_base {
|
||||
public Json_itm_int(Json_doc doc, int src_bgn, int src_end) {this.Ctor(src_bgn, src_end); this.doc = doc;} Json_doc doc;
|
||||
@Override public byte Tid() {return Json_itm_.Tid_int;}
|
||||
public int Data_as_int() {
|
||||
if (data_is_null) {
|
||||
data = doc.Utl_num_parser().Parse(doc.Src(), Src_bgn(), Src_end()).AsInt();
|
||||
data_is_null = false;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@Override public Object Data() {return Data_as_int();} int data; boolean data_is_null = true;
|
||||
@Override public byte[] Data_bry() {if (data_bry == null) data_bry = Bry_.Mid(doc.Src(), this.Src_bgn(), this.Src_end()); return data_bry;} private byte[] data_bry;
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_mid(doc.Src(), this.Src_bgn(), this.Src_end());}
|
||||
public static Json_itm_int cast_(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid_int ? null : (Json_itm_int)v;}
|
||||
}
|
||||
35
400_xowa/src/gplx/json/Json_itm_kv.java
Normal file
35
400_xowa/src/gplx/json/Json_itm_kv.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_itm_kv extends Json_itm_base {
|
||||
public Json_itm_kv(Json_itm key, Json_itm val) {this.key = key; this.val = val;}
|
||||
@Override public byte Tid() {return Json_itm_.Tid_kv;}
|
||||
public Json_itm Key() {return key;} Json_itm key;
|
||||
public Json_itm Val() {return val;} Json_itm val;
|
||||
public String Key_as_str() {return (String)key.Data();}
|
||||
public boolean Key_eq(byte[] comp) {return ((Json_itm_str)key).Data_eq(comp);}
|
||||
@Override public Object Data() {return null;}
|
||||
@Override public byte[] Data_bry() {return null;}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
key.Print_as_json(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Colon);
|
||||
val.Print_as_json(bfr, depth);
|
||||
}
|
||||
public static final Json_itm_kv[] Ary_empty = new Json_itm_kv[0];
|
||||
public static Json_itm_kv cast_(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid_kv ? null : (Json_itm_kv)v;}
|
||||
}
|
||||
72
400_xowa/src/gplx/json/Json_itm_nde.java
Normal file
72
400_xowa/src/gplx/json/Json_itm_nde.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_itm_nde extends Json_itm_base implements Json_grp {
|
||||
public Json_itm_nde(int src_bgn) {this.Ctor(src_bgn, -1);}
|
||||
@Override public byte Tid() {return Json_itm_.Tid_nde;}
|
||||
public void Src_end_(int v) {this.src_end = v;}
|
||||
@Override public Object Data() {return null;}
|
||||
@Override public byte[] Data_bry() {return null;}
|
||||
public int Subs_len() {return subs_len;} private int subs_len = 0, subs_max = 0;
|
||||
public Json_itm Subs_get_at(int i) {return subs[i];}
|
||||
public Json_itm Subs_get_by_key(byte[] key) {
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Json_itm itm = subs[i];
|
||||
if (itm.Tid() == Json_itm_.Tid_kv) {
|
||||
Json_itm_kv itm_as_kv = (Json_itm_kv)itm;
|
||||
if (Bry_.Eq(key, itm_as_kv.Key().Data_bry()))
|
||||
return itm;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Json_itm_nde Subs_add_many(Json_itm... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Subs_add(ary[i]);
|
||||
return this;
|
||||
}
|
||||
public void Subs_add(Json_itm itm) {
|
||||
int new_len = subs_len + 1;
|
||||
if (new_len > subs_max) { // ary too small >>> expand
|
||||
subs_max = new_len * 2;
|
||||
Json_itm[] new_subs = new Json_itm[subs_max];
|
||||
Array_.CopyTo(subs, 0, new_subs, 0, subs_len);
|
||||
subs = new_subs;
|
||||
}
|
||||
subs[subs_len] = (Json_itm)itm;
|
||||
subs_len = new_len;
|
||||
}
|
||||
@Override public void Print_as_json(Bry_bfr bfr, int depth) {
|
||||
if (bfr.Len() != 0)
|
||||
bfr.Add_byte_nl();
|
||||
Json_grp_.Print_indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Curly_bgn).Add_byte(Byte_ascii.Space);
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
if (i != 0) {
|
||||
Json_grp_.Print_nl(bfr); Json_grp_.Print_indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Comma).Add_byte(Byte_ascii.Space);
|
||||
}
|
||||
subs[i].Print_as_json(bfr, depth + 1);
|
||||
}
|
||||
Json_grp_.Print_nl(bfr); Json_grp_.Print_indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Curly_end).Add_byte_nl();
|
||||
}
|
||||
Json_itm[] subs = Json_itm_.Ary_empty;
|
||||
public static Json_itm_nde cast_(Json_itm v) {return v == null || v.Tid() != Json_itm_.Tid_nde ? null : (Json_itm_nde)v;}
|
||||
}
|
||||
31
400_xowa/src/gplx/json/Json_itm_tmp.java
Normal file
31
400_xowa/src/gplx/json/Json_itm_tmp.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_itm_tmp implements Json_itm {
|
||||
public Json_itm_tmp(byte tid, String data) {this.tid = tid; this.data = data;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Data_bry() {return Bry_.new_utf8_(Object_.XtoStr_OrEmpty(data));}
|
||||
public int Src_bgn() {return -1;}
|
||||
public int Src_end() {return -1;}
|
||||
public Object Data() {return data;} private String data;
|
||||
public void Print_as_json(Bry_bfr bfr, int depth) {bfr.Add_str(data);}
|
||||
public boolean Data_eq(byte[] comp) {return false;}
|
||||
public void Clear() {}
|
||||
public static Json_itm new_str_(String v) {return new Json_itm_tmp(Json_itm_.Tid_string, "\"" + v + "\"");}
|
||||
public static Json_itm new_int_(int v) {return new Json_itm_tmp(Json_itm_.Tid_int, Int_.XtoStr(v));}
|
||||
}
|
||||
61
400_xowa/src/gplx/json/Json_kv_ary_srl.java
Normal file
61
400_xowa/src/gplx/json/Json_kv_ary_srl.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_kv_ary_srl {
|
||||
public static KeyVal Kv_by_itm(Json_itm itm) {
|
||||
switch (itm.Tid()) {
|
||||
case Json_itm_.Tid_kv:
|
||||
Json_itm_kv kv = (Json_itm_kv)itm;
|
||||
return KeyVal_.new_(kv.Key_as_str(), Val_by_itm(kv.Val()));
|
||||
default:
|
||||
throw Err_.unhandled(itm.Tid());
|
||||
}
|
||||
}
|
||||
private static Object Val_by_itm(Json_itm itm) {
|
||||
switch (itm.Tid()) {
|
||||
case Json_itm_.Tid_bool: return Bool_.XtoStr_lower(Bool_.cast_(itm.Data()));
|
||||
case Json_itm_.Tid_int:
|
||||
case Json_itm_.Tid_null:
|
||||
case Json_itm_.Tid_string:
|
||||
case Json_itm_.Tid_decimal: return itm.Data();
|
||||
case Json_itm_.Tid_array: return Val_by_itm_ary((Json_itm_ary)itm);
|
||||
case Json_itm_.Tid_nde: return Val_by_itm_nde((Json_itm_nde)itm);
|
||||
case Json_itm_.Tid_kv: // kv should never be val; EX: "a":"b":c; not possible
|
||||
default: throw Err_.unhandled(itm.Tid());
|
||||
}
|
||||
}
|
||||
private static KeyVal[] Val_by_itm_ary(Json_itm_ary itm) {
|
||||
int subs_len = itm.Subs_len();
|
||||
KeyVal[] rv = new KeyVal[subs_len];
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Json_itm sub = itm.Subs_get_at(i);
|
||||
KeyVal kv = KeyVal_.new_(Int_.XtoStr(i + Int_.Base1), Val_by_itm(sub));
|
||||
rv[i] = kv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public static KeyVal[] Val_by_itm_nde(Json_itm_nde itm) {
|
||||
int subs_len = itm.Subs_len();
|
||||
KeyVal[] rv = new KeyVal[subs_len];
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Json_itm sub = itm.Subs_get_at(i);
|
||||
rv[i] = Kv_by_itm(sub);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
50
400_xowa/src/gplx/json/Json_kv_ary_srl_tst.java
Normal file
50
400_xowa/src/gplx/json/Json_kv_ary_srl_tst.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Json_kv_ary_srl_tst {
|
||||
@Before public void init() {fxt.Clear();} private Json_kv_ary_srl_fxt fxt = new Json_kv_ary_srl_fxt();
|
||||
@Test public void Null() {fxt.Test_parse("{'k0':null}" , fxt.ary_(fxt.kv_str_("k0", null)));}
|
||||
@Test public void Bool_n() {fxt.Test_parse("{'k0':false}" , fxt.ary_(fxt.kv_bool_("k0", false)));}
|
||||
@Test public void Num() {fxt.Test_parse("{'k0':123}" , fxt.ary_(fxt.kv_int_("k0", 123)));}
|
||||
@Test public void Str() {fxt.Test_parse("{'k0':'v0'}" , fxt.ary_(fxt.kv_str_("k0", "v0")));}
|
||||
@Test public void Num_dec() {fxt.Test_parse("{'k0':1.23}" , fxt.ary_(fxt.kv_dec_("k0", DecimalAdp_.parse_("1.23"))));}
|
||||
@Test public void Ary_int() {fxt.Test_parse("{'k0':[1,2,3]}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_(fxt.kv_int_("1", 1), fxt.kv_int_("2", 2), fxt.kv_int_("3", 3)))));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("{'k0':[]}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_())));}
|
||||
@Test public void Subs_int() {fxt.Test_parse("{'k0':{'k00':1,'k01':2}}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_(fxt.kv_int_("k00", 1), fxt.kv_int_("k01", 2)))));}
|
||||
@Test public void Subs_empty() {fxt.Test_parse("{'k0':{}}" , fxt.ary_(fxt.kv_obj_("k0", fxt.ary_())));}
|
||||
}
|
||||
class Json_kv_ary_srl_fxt {
|
||||
public void Clear() {
|
||||
if (parser == null) {
|
||||
parser = new Json_parser();
|
||||
}
|
||||
} private Json_parser parser;
|
||||
public void Test_parse(String raw_str, KeyVal[] expd) {
|
||||
byte[] raw_bry = Json_parser_tst.Replace_apos(Bry_.new_utf8_(raw_str));
|
||||
Json_doc doc = parser.Parse(raw_bry);
|
||||
KeyVal[] actl = Json_kv_ary_srl.Val_by_itm_nde(doc.Root());
|
||||
Tfds.Eq_str_lines(KeyVal_.Ary_x_to_str(expd), KeyVal_.Ary_x_to_str(actl));
|
||||
}
|
||||
public KeyVal[] ary_(KeyVal... ary) {return ary;}
|
||||
public KeyVal kv_obj_(String key, Object val) {return KeyVal_.new_(key, val);}
|
||||
public KeyVal kv_str_(String key, String val) {return KeyVal_.new_(key, val);}
|
||||
public KeyVal kv_int_(String key, int val) {return KeyVal_.new_(key, val);}
|
||||
public KeyVal kv_bool_(String key, boolean val) {return KeyVal_.new_(key, Bool_.XtoStr_lower(val));}
|
||||
public KeyVal kv_dec_(String key, DecimalAdp val) {return KeyVal_.new_(key, val.XtoStr());}
|
||||
}
|
||||
167
400_xowa/src/gplx/json/Json_parser.java
Normal file
167
400_xowa/src/gplx/json/Json_parser.java
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
public class Json_parser {
|
||||
public Json_factory Factory() {return factory;} Json_factory factory = new Json_factory();
|
||||
private byte[] src; private int src_len, pos; private NumberParser num_parser = new NumberParser();
|
||||
private static final byte[] Bry_bool_rue = Bry_.new_ascii_("rue"), Bry_bool_alse = Bry_.new_ascii_("alse"), Bry_null_ull = Bry_.new_ascii_("ull");
|
||||
public Json_doc Parse(byte[] src) {
|
||||
Json_doc doc = new Json_doc();
|
||||
this.src = src; this.src_len = src.length; pos = 0;
|
||||
Skip_ws();
|
||||
if (src.length == 0) return null;
|
||||
if (src[pos] != Byte_ascii.Curly_bgn) return null;
|
||||
Skip_ws();
|
||||
// if (src[pos + 1] != Byte_ascii.Quote) return null;
|
||||
// throw Err_.new_("doc must start with {");
|
||||
Json_itm_nde root = Make_nde(doc);
|
||||
doc.Ctor(src, root);
|
||||
return doc;
|
||||
}
|
||||
Json_itm_nde Make_nde(Json_doc doc) {
|
||||
++pos; // brack_bgn
|
||||
Json_itm_nde nde = new Json_itm_nde(pos);
|
||||
while (pos < src_len) {
|
||||
Skip_ws();
|
||||
if (src[pos] == Byte_ascii.Curly_end) {++pos; return nde;}
|
||||
else nde.Subs_add(Make_kv(doc));
|
||||
Skip_ws();
|
||||
switch (src[pos++]) {
|
||||
case Byte_ascii.Comma: break;
|
||||
case Byte_ascii.Curly_end: return nde;
|
||||
default: throw Err_.unhandled(src[pos - 1]);
|
||||
}
|
||||
}
|
||||
throw Err_.new_("eos inside nde");
|
||||
}
|
||||
Json_itm Make_kv(Json_doc doc) {
|
||||
Json_itm key = Make_string(doc);
|
||||
Skip_ws();
|
||||
Chk(Byte_ascii.Colon);
|
||||
Skip_ws();
|
||||
Json_itm val = Make_val(doc);
|
||||
return new Json_itm_kv(key, val);
|
||||
}
|
||||
Json_itm Make_val(Json_doc doc) {
|
||||
while (pos < src_len) {
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Ltr_n: return Make_literal(Bry_null_ull , 3, factory.Null());
|
||||
case Byte_ascii.Ltr_f: return Make_literal(Bry_bool_alse , 4, factory.Bool_n());
|
||||
case Byte_ascii.Ltr_t: return Make_literal(Bry_bool_rue , 3, factory.Bool_y());
|
||||
case Byte_ascii.Quote: return Make_string(doc);
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
case Byte_ascii.Dash: return Make_num(doc);
|
||||
case Byte_ascii.Brack_bgn: return Make_ary(doc);
|
||||
case Byte_ascii.Curly_bgn: return Make_nde(doc);
|
||||
}
|
||||
throw Err_.unhandled(Char_.XtoStr(b));
|
||||
}
|
||||
throw Err_.new_("eos reached in val");
|
||||
}
|
||||
Json_itm Make_literal(byte[] remainder, int remainder_len, Json_itm singleton) {
|
||||
++pos; // 1st char
|
||||
int literal_end = pos + remainder_len;
|
||||
if (Bry_.Eq(remainder, src, pos, literal_end)) {
|
||||
pos = literal_end;
|
||||
return singleton;
|
||||
}
|
||||
throw Err_.new_("invalid literal");
|
||||
}
|
||||
Json_itm Make_string(Json_doc doc) {
|
||||
int bgn = pos++; // ++: quote_bgn
|
||||
boolean exact = true;
|
||||
while (pos < src_len) {
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Backslash:
|
||||
++pos; // backslash
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Ltr_u: pos += 4; break; // \uFFFF 4 hex-dec
|
||||
default: ++pos; break; // \? " \ / b f n r t
|
||||
}
|
||||
exact = false;
|
||||
break;
|
||||
case Byte_ascii.Quote:
|
||||
return factory.Str(doc, bgn, ++pos, exact); // ++: quote_end
|
||||
default:
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw Err_.new_("eos reached inside quote");
|
||||
}
|
||||
Json_itm Make_num(Json_doc doc) {
|
||||
int num_bgn = pos;
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (pos == src_len) throw Err_.new_("eos reached inside num");
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
++pos;
|
||||
break;
|
||||
case Byte_ascii.Dot:
|
||||
case Byte_ascii.Dash: case Byte_ascii.Plus:
|
||||
case Byte_ascii.Ltr_E: case Byte_ascii.Ltr_e: // e e+ e- E E+ E-
|
||||
++pos;
|
||||
break;
|
||||
default:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
num_parser.Parse(src, num_bgn, pos);
|
||||
return num_parser.HasFrac()
|
||||
? factory.Decimal(doc, num_bgn, pos)
|
||||
: factory.Int(doc, num_bgn, pos);
|
||||
}
|
||||
Json_itm_ary Make_ary(Json_doc doc) {
|
||||
Json_itm_ary rv = factory.Ary(pos++, pos); // brack_bgn
|
||||
while (pos < src_len) {
|
||||
Skip_ws();
|
||||
if (src[pos] == Byte_ascii.Brack_end) {++pos; return rv;}
|
||||
else rv.Subs_add(Make_val(doc));
|
||||
Skip_ws();
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Comma: ++pos; break;
|
||||
case Byte_ascii.Brack_end: ++pos; return rv;
|
||||
}
|
||||
}
|
||||
throw Err_.new_("eos inside ary");
|
||||
}
|
||||
private void Skip_ws() {
|
||||
while (pos < src_len) {
|
||||
switch (src[pos]) {
|
||||
case Byte_ascii.Space: case Byte_ascii.NewLine: case Byte_ascii.Tab: case Byte_ascii.CarriageReturn: ++pos; break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Chk(byte expd) {
|
||||
if (src[pos] == expd)
|
||||
++pos;
|
||||
else
|
||||
throw err_(src, pos, "expected '{0}' but got '{1}'", Char_.XtoStr(expd), Char_.XtoStr(src[pos]));
|
||||
}
|
||||
Err err_(byte[] src, int bgn, String fmt, Object... args) {return err_(src, bgn, src.length, fmt, args);}
|
||||
Err err_(byte[] src, int bgn, int src_len, String fmt, Object... args) {
|
||||
String msg = String_.Format(fmt, args) + " " + Int_.XtoStr(bgn) + " " + String_.new_utf8_len_safe_(src, bgn, 20);
|
||||
return Err_.new_(msg);
|
||||
}
|
||||
}
|
||||
99
400_xowa/src/gplx/json/Json_parser_tst.java
Normal file
99
400_xowa/src/gplx/json/Json_parser_tst.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.json; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Json_parser_tst {
|
||||
Json_parser_fxt fxt = new Json_parser_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Null() {fxt.Test_parse_val0("{'k0':null}" , null);}
|
||||
@Test public void Bool_n() {fxt.Test_parse_val0("{'k0':false}" , false);}
|
||||
@Test public void Bool_y() {fxt.Test_parse_val0("{'k0':true}" , true);}
|
||||
@Test public void Num() {fxt.Test_parse_val0("{'k0':123}" , 123);}
|
||||
@Test public void Num_neg() {fxt.Test_parse_val0("{'k0':-123}" , -123);}
|
||||
@Test public void Str() {fxt.Test_parse_val0("{'k0':'v0'}" , "v0");}
|
||||
@Test public void Str_esc_quote() {fxt.Test_parse_val0("{'k0':'a\\\"b'}" , "a\"b");}
|
||||
@Test public void Str_esc_hex4() {fxt.Test_parse_val0("{'k0':'a\\u0021b'}" , "a!b");}
|
||||
@Test public void Num_dec() {fxt.Test_parse("{'k0':1.23}" , fxt.itm_nde_().Subs_add_many(fxt.itm_kv_dec_("k0", "1.23")));}
|
||||
@Test public void Num_exp() {fxt.Test_parse("{'k0':1e+2}" , fxt.itm_nde_().Subs_add_many(fxt.itm_kv_dec_("k0", "1e+2")));}
|
||||
@Test public void Num_mix() {fxt.Test_parse("{'k0':-1.23e-1}" , fxt.itm_nde_().Subs_add_many(fxt.itm_kv_dec_("k0", "-1.23e-1")));}
|
||||
@Test public void Str_many() {fxt.Test_parse("{'k0':'v0','k1':'v1','k2':'v2'}", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k0", "v0"), fxt.itm_kv_("k1", "v1"), fxt.itm_kv_("k2", "v2")));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("{'k0':[]}", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_ary_int_("k0")));}
|
||||
@Test public void Ary_int() {fxt.Test_parse("{'k0':[1,2,3]}", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_ary_int_("k0", 1, 2, 3)));}
|
||||
@Test public void Ary_str() {fxt.Test_parse("{'k0':['a','b','c']}", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_ary_str_("k0", "a", "b", "c")));}
|
||||
@Test public void Ary_ws() {fxt.Test_parse("{'k0': [ 1 , 2 , 3 ] }", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_ary_int_("k0", 1, 2, 3)));}
|
||||
@Test public void Subs_int() {fxt.Test_parse("{'k0':{'k00':1}}", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k0", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k00", 1)))));}
|
||||
@Test public void Subs_empty() {fxt.Test_parse("{'k0':{}}", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k0", fxt.itm_nde_())));}
|
||||
@Test public void Subs_ws() {fxt.Test_parse("{'k0': { 'k00' : 1 } }", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k0", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k00", 1)))));}
|
||||
@Test public void Ws() {fxt.Test_parse(" { 'k0' : 'v0' } ", fxt.itm_nde_().Subs_add_many(fxt.itm_kv_("k0", "v0")));}
|
||||
public static String Replace_apos_as_str(String v) {return String_.new_utf8_(Replace_apos(Bry_.new_utf8_(v)));}
|
||||
public static byte[] Replace_apos(byte[] v) {return Bry_.Replace(v, Byte_ascii.Apos, Byte_ascii.Quote);}
|
||||
}
|
||||
class Json_parser_fxt {
|
||||
public void Clear() {
|
||||
if (parser == null) {
|
||||
parser = new Json_parser();
|
||||
factory = parser.Factory();
|
||||
}
|
||||
} Json_parser parser; Json_factory factory; Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
|
||||
Json_itm itm_int_(int v) {return Json_itm_tmp.new_int_(v);}
|
||||
Json_itm itm_str_(String v) {return Json_itm_tmp.new_str_(v);}
|
||||
public Json_itm_ary itm_ary_() {return factory.Ary(-1, -1);}
|
||||
public Json_itm_nde itm_nde_() {return factory.Nde(-1);}
|
||||
public Json_itm_kv itm_kv_null_(String k) {return factory.Kv(itm_str_(k), factory.Null());}
|
||||
public Json_itm_kv itm_kv_(String k, String v) {return factory.Kv(itm_str_(k), itm_str_(v));}
|
||||
public Json_itm_kv itm_kv_(String k, int v) {return factory.Kv(itm_str_(k), itm_int_(v));}
|
||||
public Json_itm_kv itm_kv_(String k, boolean v) {return factory.Kv(itm_str_(k), v ? factory.Bool_y() : factory.Bool_n());}
|
||||
public Json_itm_kv itm_kv_dec_(String k, String v) {return factory.Kv(itm_str_(k), new Json_itm_tmp(Json_itm_.Tid_decimal, v));}
|
||||
public Json_itm_kv itm_kv_(String k, Json_itm_nde v) {return factory.Kv(itm_str_(k), v);}
|
||||
public Json_itm_kv itm_kv_ary_int_(String k, int... v) {
|
||||
Json_itm_ary ary = factory.Ary(-1, -1);
|
||||
int len = v.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
ary.Subs_add(itm_int_(v[i]));
|
||||
return factory.Kv(itm_str_(k), ary);
|
||||
}
|
||||
public Json_itm_kv itm_kv_ary_str_(String k, String... v) {
|
||||
Json_itm_ary ary = factory.Ary(-1, -1);
|
||||
int len = v.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
ary.Subs_add(itm_str_(v[i]));
|
||||
return factory.Kv(itm_str_(k), ary);
|
||||
}
|
||||
public void Test_parse(String raw_str, Json_itm... expd_ary) {
|
||||
byte[] raw = Json_parser_tst.Replace_apos(Bry_.new_utf8_(raw_str));
|
||||
Json_doc doc = parser.Parse(raw);
|
||||
doc.Root().Print_as_json(tmp_bfr, 0);
|
||||
String actl = tmp_bfr.XtoStrAndClear();
|
||||
String expd = Xto_str(raw, doc, expd_ary, 0, expd_ary.length);
|
||||
Tfds.Eq_str_lines(expd, actl, actl);
|
||||
}
|
||||
public void Test_parse_val0(String raw_str, Object expd) {
|
||||
byte[] raw = Json_parser_tst.Replace_apos(Bry_.new_utf8_(raw_str));
|
||||
Json_doc doc = parser.Parse(raw);
|
||||
Json_itm_kv kv = Json_itm_kv.cast_(doc.Root().Subs_get_at(0)); // assume root has kv as first sub; EX: {"a":"b"}
|
||||
Object actl = kv.Val().Data(); // NOTE: Data_bry is escaped val; EX: a\"b has DataBry of a"b
|
||||
Tfds.Eq(expd, actl);
|
||||
}
|
||||
String Xto_str(byte[] raw, Json_doc doc, Json_itm[] ary, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
Json_itm itm = ary[i];
|
||||
itm.Print_as_json(tmp_bfr, 0);
|
||||
}
|
||||
return tmp_bfr.XtoStrAndClear();
|
||||
}
|
||||
}
|
||||
21
400_xowa/src/gplx/php/Php_ctx.java
Normal file
21
400_xowa/src/gplx/php/Php_ctx.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_ctx {
|
||||
public byte[] Src() {return src;} public Php_ctx Src_(byte[] v) {this.src = v; return this;} private byte[] src;
|
||||
}
|
||||
263
400_xowa/src/gplx/php/Php_evaluator.java
Normal file
263
400_xowa/src/gplx/php/Php_evaluator.java
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
/*
|
||||
NOTE: naive implementation of PHP evaluator. intended only for parsing Messages**.php files in MediaWiki. Specifically, it assumes the following:
|
||||
- all lines are assignment lines: EX: $a = b;
|
||||
- only the assignment operator is allowed (=); EX: $a = 5 + 7; fails b/c of + operator;
|
||||
- no functions are supported: EX: strlen('a') fails
|
||||
*/
|
||||
public class Php_evaluator implements Php_tkn_wkr {
|
||||
byte mode = Mode_key_bgn, next_tid = 0, next_mode = 0;
|
||||
Php_line_assign cur_line; Php_itm_ary cur_ary; Php_key cur_kv_key;
|
||||
ListAdp frame_stack = ListAdp_.new_();
|
||||
public Php_evaluator(Gfo_msg_log msg_log) {this.msg_log = msg_log;} Gfo_msg_log msg_log;
|
||||
public void Init(Php_ctx ctx) {src = ctx.Src(); frame_stack.Clear();} private byte[] src;
|
||||
public ListAdp List() {return lines;} ListAdp lines = ListAdp_.new_();
|
||||
public Gfo_msg_log Msg_log() {return msg_log;}
|
||||
public void Clear() {
|
||||
lines.Clear(); msg_log.Clear();
|
||||
cur_line = null;
|
||||
cur_ary = null;
|
||||
cur_kv_key = null;
|
||||
mode = Mode_key_bgn;
|
||||
next_tid = next_mode = 0;
|
||||
}
|
||||
public void Process(Php_tkn tkn) {
|
||||
byte tkn_tid = tkn.Tkn_tid();
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_declaration: case Php_tkn_.Tid_comment: case Php_tkn_.Tid_ws: // always discard, regardless of mode
|
||||
return;
|
||||
}
|
||||
switch (mode) {
|
||||
case Mode_expect: // handles sequences like "array("
|
||||
if (tkn_tid == next_tid)
|
||||
mode = next_mode;
|
||||
else {
|
||||
Msg_many(src, tkn.Src_bgn(), tkn.Src_end(), Expecting_itm_failed, Php_tkn_.Xto_str(next_tid), Php_tkn_.Xto_str(tkn_tid));
|
||||
Fail();
|
||||
}
|
||||
break;
|
||||
case Mode_suspend:
|
||||
if (tkn_tid == Php_tkn_.Tid_semic) mode = Mode_key_bgn;
|
||||
break;
|
||||
case Mode_key_bgn:
|
||||
if (tkn_tid == Php_tkn_.Tid_var) {
|
||||
cur_ary = null;
|
||||
cur_line = new Php_line_assign();
|
||||
lines.Add(cur_line);
|
||||
|
||||
Php_tkn_var var_tkn = (Php_tkn_var)tkn;
|
||||
cur_line.Key_(new Php_itm_var(var_tkn.Var_name(src)));
|
||||
|
||||
mode = Mode_key_end;
|
||||
}
|
||||
else {
|
||||
Msg_many(src, tkn.Src_bgn(), tkn.Src_end(), Expecting_itm_failed, Php_tkn_.Xto_str(Php_tkn_.Tid_var), Php_tkn_.Xto_str(tkn_tid));
|
||||
Fail();
|
||||
}
|
||||
break;
|
||||
case Mode_key_end:
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_eq: mode = Mode_val; break;
|
||||
case Php_tkn_.Tid_brack_bgn: mode = Mode_brack_itm; break;
|
||||
case Php_tkn_.Tid_brack_end: Expect(Php_tkn_.Tid_eq, Mode_val); break;
|
||||
default: {
|
||||
Msg_many(src, tkn.Src_bgn(), tkn.Src_end(), Expecting_itm_failed, Php_tkn_.Xto_str(Php_tkn_.Tid_var), Php_tkn_.Xto_str(tkn_tid));
|
||||
Fail();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Mode_brack_itm:
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_quote:
|
||||
Php_tkn_quote tkn_quote = (Php_tkn_quote)tkn;
|
||||
Php_itm_quote key_sub = new Php_itm_quote(tkn_quote.Quote_text(src));
|
||||
cur_line.Key_subs_(new Php_key[] {key_sub});
|
||||
mode = Mode_key_end;
|
||||
break;
|
||||
default: {
|
||||
Msg_many(src, tkn.Src_bgn(), tkn.Src_end(), Expecting_itm_failed, Php_tkn_.Xto_str(Php_tkn_.Tid_var), Php_tkn_.Xto_str(tkn_tid));
|
||||
Fail();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Mode_val:
|
||||
Php_itm line_val = null;
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_null: Expect(Php_tkn_.Tid_semic, Mode_key_bgn); line_val = Php_itm_null._; break;
|
||||
case Php_tkn_.Tid_false: Expect(Php_tkn_.Tid_semic, Mode_key_bgn); line_val = Php_itm_bool_false._; break;
|
||||
case Php_tkn_.Tid_true: Expect(Php_tkn_.Tid_semic, Mode_key_bgn); line_val = Php_itm_bool_true._; break;
|
||||
case Php_tkn_.Tid_quote:
|
||||
Expect(Php_tkn_.Tid_semic, Mode_key_bgn);
|
||||
Php_tkn_quote tkn_quote = (Php_tkn_quote)tkn;
|
||||
line_val = new Php_itm_quote(tkn_quote.Quote_text(src));
|
||||
break;
|
||||
case Php_tkn_.Tid_ary:
|
||||
Expect(Php_tkn_.Tid_paren_bgn, Mode_ary_subs);
|
||||
Php_itm_ary ary = new Php_itm_ary();
|
||||
if (cur_ary == null)
|
||||
line_val = ary;
|
||||
else {
|
||||
cur_ary.Subs_add(ary);
|
||||
frame_stack.Add(new Php_scanner_frame(cur_ary));
|
||||
cur_kv_key = null;
|
||||
}
|
||||
this.cur_ary = ary;
|
||||
break;
|
||||
case Php_tkn_.Tid_txt:
|
||||
case Php_tkn_.Tid_var:
|
||||
break;
|
||||
case Php_tkn_.Tid_eq:
|
||||
case Php_tkn_.Tid_eq_kv:
|
||||
case Php_tkn_.Tid_semic:
|
||||
case Php_tkn_.Tid_comma:
|
||||
case Php_tkn_.Tid_paren_bgn:
|
||||
case Php_tkn_.Tid_paren_end:
|
||||
case Php_tkn_.Tid_num:
|
||||
break;
|
||||
}
|
||||
cur_line.Val_(line_val);
|
||||
break;
|
||||
case Mode_ary_subs:
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_null: Ary_add_itm(Php_itm_null._); break;
|
||||
case Php_tkn_.Tid_false: Ary_add_itm(Php_itm_bool_false._); break;
|
||||
case Php_tkn_.Tid_true: Ary_add_itm(Php_itm_bool_true._); break;
|
||||
case Php_tkn_.Tid_quote:
|
||||
Php_tkn_quote tkn_quote = (Php_tkn_quote)tkn;
|
||||
Ary_add_itm(new Php_itm_quote(tkn_quote.Quote_text(src)));
|
||||
break;
|
||||
case Php_tkn_.Tid_num:
|
||||
Php_tkn_num tkn_num = (Php_tkn_num)tkn;
|
||||
Ary_add_itm(new Php_itm_int(tkn_num.Num_val_int(src)));
|
||||
break;
|
||||
case Php_tkn_.Tid_var:
|
||||
Php_tkn_var tkn_var = (Php_tkn_var)tkn;
|
||||
Ary_add_itm(new Php_itm_var(Bry_.Mid(src, tkn_var.Src_bgn(), tkn_var.Src_end())));
|
||||
break;
|
||||
case Php_tkn_.Tid_txt:
|
||||
Php_tkn_txt tkn_txt = (Php_tkn_txt)tkn;
|
||||
Ary_add_itm(new Php_itm_var(Bry_.Mid(src, tkn_txt.Src_bgn(), tkn_txt.Src_end())));
|
||||
break;
|
||||
case Php_tkn_.Tid_ary:
|
||||
Expect(Php_tkn_.Tid_paren_bgn, Mode_ary_subs);
|
||||
Php_itm_ary ary = new Php_itm_ary();
|
||||
if (cur_ary == null)
|
||||
line_val = ary;
|
||||
else {
|
||||
frame_stack.Add(new Php_scanner_frame(cur_ary));
|
||||
if (cur_kv_key == null)
|
||||
cur_ary.Subs_add(ary);
|
||||
else {
|
||||
Php_itm_kv ary_itm = new Php_itm_kv().Key_(cur_kv_key).Val_(ary);
|
||||
cur_ary.Subs_add(ary_itm);
|
||||
cur_kv_key = null;
|
||||
}
|
||||
}
|
||||
this.cur_ary = ary;
|
||||
break;
|
||||
case Php_tkn_.Tid_paren_end:
|
||||
mode = Mode_ary_term;
|
||||
if (frame_stack.Count() == 0)
|
||||
cur_ary = null;
|
||||
else {
|
||||
Php_scanner_frame frame = (Php_scanner_frame)ListAdp_.Pop(frame_stack);
|
||||
cur_ary = frame.Ary();
|
||||
frame.Rls();
|
||||
}
|
||||
break;
|
||||
case Php_tkn_.Tid_semic: // NOTE: will occur in following construct array(array());
|
||||
mode = Mode_key_bgn;
|
||||
break;
|
||||
case Php_tkn_.Tid_eq:
|
||||
case Php_tkn_.Tid_eq_kv:
|
||||
case Php_tkn_.Tid_comma:
|
||||
case Php_tkn_.Tid_paren_bgn:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Mode_ary_dlm:
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_comma:
|
||||
mode = Mode_ary_subs;
|
||||
break;
|
||||
case Php_tkn_.Tid_paren_end:
|
||||
mode = Mode_ary_term;
|
||||
if (frame_stack.Count() == 0)
|
||||
cur_ary = null;
|
||||
else {
|
||||
Php_scanner_frame frame = (Php_scanner_frame)ListAdp_.Pop(frame_stack);
|
||||
cur_ary = frame.Ary();
|
||||
frame.Rls();
|
||||
}
|
||||
break;
|
||||
case Php_tkn_.Tid_eq_kv:
|
||||
Php_itm_sub tmp_key = cur_ary.Subs_pop();
|
||||
cur_kv_key = (Php_key)tmp_key;
|
||||
mode = Mode_ary_subs;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Mode_ary_term:
|
||||
switch (tkn_tid) {
|
||||
case Php_tkn_.Tid_comma:
|
||||
case Php_tkn_.Tid_paren_end: // NOTE: paren_end occurs in multiple nests; EX: array(array())
|
||||
mode = Mode_ary_subs;
|
||||
break;
|
||||
case Php_tkn_.Tid_semic:
|
||||
mode = Mode_key_bgn;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void Fail() {mode = Mode_suspend;}
|
||||
private void Ary_add_itm(Php_itm val) {
|
||||
mode = Mode_ary_dlm;
|
||||
if (cur_kv_key == null)
|
||||
cur_ary.Subs_add((Php_itm_sub)val);
|
||||
else {
|
||||
Php_itm_kv ary_itm = new Php_itm_kv().Key_(cur_kv_key).Val_(val);
|
||||
cur_ary.Subs_add(ary_itm);
|
||||
cur_kv_key = null;
|
||||
}
|
||||
}
|
||||
private void Expect(byte next_tid, byte next_mode) {
|
||||
mode = Mode_expect;
|
||||
this.next_tid = next_tid;
|
||||
this.next_mode = next_mode;
|
||||
}
|
||||
public void Msg_many(byte[] src, int bgn, int end, Gfo_msg_itm itm, Object... args) {
|
||||
msg_log.Add_itm_many(itm, src, bgn, end, args);
|
||||
}
|
||||
public static final Gfo_msg_itm Expecting_itm_failed = Gfo_msg_itm_.new_warn_(Php_parser.Log_nde, "expecting_itm_failed", "expecting_itm ~{0} but got ~{1} instead");
|
||||
static final byte Mode_key_bgn = 1, Mode_key_end = 2, Mode_expect = 3, Mode_suspend = 4, Mode_val = 5, Mode_ary_subs = 6, Mode_ary_dlm = 7, Mode_ary_term = 8, Mode_brack_itm = 9;
|
||||
|
||||
}
|
||||
class Php_scanner_frame {
|
||||
public Php_scanner_frame(Php_itm_ary ary) {this.ary = ary;}
|
||||
public Php_itm_ary Ary() {return ary;} Php_itm_ary ary;
|
||||
public void Rls() {ary = null;}
|
||||
}
|
||||
class Php_parser_interrupt {
|
||||
public static final Php_parser_interrupt Char = new Php_parser_interrupt();
|
||||
}
|
||||
|
||||
44
400_xowa/src/gplx/php/Php_itm.java
Normal file
44
400_xowa/src/gplx/php/Php_itm.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public interface Php_itm {
|
||||
byte Itm_tid();
|
||||
byte[] Val_obj_bry();
|
||||
}
|
||||
class Php_itm_null implements Php_itm, Php_itm_sub {
|
||||
public byte Itm_tid() {return Php_itm_.Tid_null;}
|
||||
public byte[] Val_obj_bry() {return null;}
|
||||
public static final Php_itm_null _ = new Php_itm_null(); Php_itm_null() {}
|
||||
}
|
||||
class Php_itm_bool_true implements Php_itm, Php_itm_sub {
|
||||
public byte Itm_tid() {return Php_itm_.Tid_bool_true;}
|
||||
public byte[] Val_obj_bry() {return Bry_true;}
|
||||
public static final Php_itm_bool_true _ = new Php_itm_bool_true(); Php_itm_bool_true() {}
|
||||
private static final byte[] Bry_true = Bry_.new_ascii_("true");
|
||||
}
|
||||
class Php_itm_bool_false implements Php_itm, Php_itm_sub {
|
||||
public byte Itm_tid() {return Php_itm_.Tid_bool_false;}
|
||||
public byte[] Val_obj_bry() {return Bry_true;}
|
||||
public static final Php_itm_bool_false _ = new Php_itm_bool_false(); Php_itm_bool_false() {}
|
||||
private static final byte[] Bry_true = Bry_.new_ascii_("false");
|
||||
}
|
||||
class Php_itm_var implements Php_itm, Php_itm_sub, Php_key {
|
||||
public Php_itm_var(byte[] v) {this.val_obj_bry = v;}
|
||||
public byte Itm_tid() {return Php_itm_.Tid_var;}
|
||||
public byte[] Val_obj_bry() {return val_obj_bry;} private byte[] val_obj_bry;
|
||||
}
|
||||
44
400_xowa/src/gplx/php/Php_itm_.java
Normal file
44
400_xowa/src/gplx/php/Php_itm_.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_itm_ {
|
||||
public static final byte Tid_null = 0, Tid_bool_false = 1, Tid_bool_true = 2, Tid_int = 3, Tid_quote = 4, Tid_ary = 5, Tid_kv = 6, Tid_var = 7;
|
||||
public static int Parse_int_or(Php_itm itm, int or) {
|
||||
int rv = -1;
|
||||
switch (itm.Itm_tid()) {
|
||||
case Php_itm_.Tid_int:
|
||||
rv = ((Php_itm_int)itm).Val_obj_int();
|
||||
return rv;
|
||||
case Php_itm_.Tid_quote:
|
||||
byte[] bry = ((Php_itm_quote)itm).Val_obj_bry();
|
||||
rv = Bry_.X_to_int_or(bry, -1);
|
||||
return (rv == -1) ? or : rv;
|
||||
default:
|
||||
return or;
|
||||
}
|
||||
}
|
||||
public static byte[] Parse_bry(Php_itm itm) {
|
||||
switch (itm.Itm_tid()) {
|
||||
case Php_itm_.Tid_kv:
|
||||
case Php_itm_.Tid_ary:
|
||||
throw Err_mgr._.unhandled_(itm.Itm_tid());
|
||||
default:
|
||||
return itm.Val_obj_bry();
|
||||
}
|
||||
}
|
||||
}
|
||||
37
400_xowa/src/gplx/php/Php_itm_ary.java
Normal file
37
400_xowa/src/gplx/php/Php_itm_ary.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_itm_ary implements Php_itm, Php_itm_sub {
|
||||
public Php_itm_ary() {}
|
||||
public byte Itm_tid() {return Php_itm_.Tid_ary;}
|
||||
public byte[] Val_obj_bry() {return null;}
|
||||
public int Subs_len() {return subs_len;} private int subs_len;
|
||||
public Php_itm_sub Subs_get(int i) {return ary[i];}
|
||||
public Php_itm_sub Subs_pop() {return ary[--subs_len];}
|
||||
public void Subs_add(Php_itm_sub v) {
|
||||
int new_len = subs_len + 1;
|
||||
if (new_len > subs_max) { // ary too small >>> expand
|
||||
subs_max = new_len * 2;
|
||||
Php_itm_sub[] new_ary = new Php_itm_sub[subs_max];
|
||||
Array_.CopyTo(ary, 0, new_ary, 0, subs_len);
|
||||
ary = new_ary;
|
||||
}
|
||||
ary[subs_len] = v;
|
||||
subs_len = new_len;
|
||||
} Php_itm_sub[] ary = Php_itm_sub_.Ary_empty; int subs_max;
|
||||
}
|
||||
24
400_xowa/src/gplx/php/Php_itm_int.java
Normal file
24
400_xowa/src/gplx/php/Php_itm_int.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_itm_int implements Php_itm, Php_itm_sub, Php_key {
|
||||
public Php_itm_int(int v) {this.val_obj_int = v;}
|
||||
public byte Itm_tid() {return Php_itm_.Tid_int;}
|
||||
public byte[] Val_obj_bry() {return Bry_.XbyInt(val_obj_int);}
|
||||
public int Val_obj_int() {return val_obj_int;} private int val_obj_int;
|
||||
}
|
||||
24
400_xowa/src/gplx/php/Php_itm_kv.java
Normal file
24
400_xowa/src/gplx/php/Php_itm_kv.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_itm_kv implements Php_itm, Php_itm_sub {
|
||||
public byte Itm_tid() {return Php_itm_.Tid_kv;}
|
||||
public byte[] Val_obj_bry() {return null;}
|
||||
public Php_key Key() {return key;} public Php_itm_kv Key_(Php_key v) {this.key = v; return this;} Php_key key;
|
||||
public Php_itm Val() {return val;} public Php_itm_kv Val_(Php_itm v) {this.val = v; return this;} Php_itm val;
|
||||
}
|
||||
23
400_xowa/src/gplx/php/Php_itm_quote.java
Normal file
23
400_xowa/src/gplx/php/Php_itm_quote.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_itm_quote implements Php_itm, Php_itm_sub, Php_key {
|
||||
public Php_itm_quote(byte[] v) {this.val_obj_bry = v;} // NOTE: use Php_text_itm_parser to parse \" and related
|
||||
public byte Itm_tid() {return Php_itm_.Tid_quote;}
|
||||
public byte[] Val_obj_bry() {return val_obj_bry;} private byte[] val_obj_bry;
|
||||
}
|
||||
23
400_xowa/src/gplx/php/Php_itm_sub.java
Normal file
23
400_xowa/src/gplx/php/Php_itm_sub.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public interface Php_itm_sub extends Php_itm {
|
||||
}
|
||||
class Php_itm_sub_ {
|
||||
public static final Php_itm_sub[] Ary_empty = new Php_itm_sub[0];
|
||||
}
|
||||
23
400_xowa/src/gplx/php/Php_key.java
Normal file
23
400_xowa/src/gplx/php/Php_key.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public interface Php_key extends Php_itm {
|
||||
}
|
||||
class Php_key_ {
|
||||
public static final Php_key[] Ary_empty = new Php_key[0];
|
||||
}
|
||||
19
400_xowa/src/gplx/php/Php_line.java
Normal file
19
400_xowa/src/gplx/php/Php_line.java
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public interface Php_line {}
|
||||
23
400_xowa/src/gplx/php/Php_line_assign.java
Normal file
23
400_xowa/src/gplx/php/Php_line_assign.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_line_assign implements Php_line {
|
||||
public Php_key Key() {return key;} public Php_line_assign Key_(Php_key v) {this.key = v; return this;} Php_key key;
|
||||
public Php_key[] Key_subs() {return key_subs;} public Php_line_assign Key_subs_(Php_key[] v) {this.key_subs = v; return this;} Php_key[] key_subs = Php_key_.Ary_empty;
|
||||
public Php_itm Val() {return val;} public Php_line_assign Val_(Php_itm v) {this.val = v; return this;} Php_itm val;
|
||||
}
|
||||
282
400_xowa/src/gplx/php/Php_lxr.java
Normal file
282
400_xowa/src/gplx/php/Php_lxr.java
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
interface Php_lxr {
|
||||
byte Lxr_tid();
|
||||
void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts);
|
||||
void Lxr_bgn(byte[] src, int src_len, Php_tkn_wkr tkn_wkr, Php_tkn_factory tkn_factory);
|
||||
int Lxr_make(Php_ctx ctx, int bgn, int cur);
|
||||
}
|
||||
class Php_lxr_ {
|
||||
public static final byte Tid_declaration = 1, Tid_ws = 2, Tid_comment = 3, Tid_var = 4, Tid_sym = 5, Tid_keyword = 6, Tid_num = 7, Tid_quote = 8;
|
||||
}
|
||||
abstract class Php_lxr_base implements Php_lxr {
|
||||
protected byte[] src; protected int src_len; protected Php_tkn_wkr tkn_wkr; protected Php_tkn_factory tkn_factory;
|
||||
public abstract byte Lxr_tid();
|
||||
public abstract void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts);
|
||||
public void Lxr_bgn(byte[] src, int src_len, Php_tkn_wkr tkn_wkr, Php_tkn_factory tkn_factory) {this.src = src; this.src_len = src_len; this.tkn_wkr = tkn_wkr; this.tkn_factory = tkn_factory;}
|
||||
public abstract int Lxr_make(Php_ctx ctx, int bgn, int cur);
|
||||
}
|
||||
class Php_lxr_declaration extends Php_lxr_base {
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_declaration;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
trie.Add(Bry_declaration, this);
|
||||
parser_interrupts[Byte_ascii.Lt] = Php_parser_interrupt.Char;
|
||||
}
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
boolean loop = true;
|
||||
boolean ws_found = false;
|
||||
while (loop) {
|
||||
if (cur == src_len) break;
|
||||
byte b = src[cur];
|
||||
switch (b) {
|
||||
case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn:
|
||||
ws_found = true;
|
||||
++cur;
|
||||
break;
|
||||
default:
|
||||
if (ws_found) loop = false;
|
||||
else return Php_parser.NotFound;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tkn_wkr.Process(tkn_factory.Declaration(bgn, cur));
|
||||
return cur;
|
||||
}
|
||||
private static final byte[] Bry_declaration = Bry_.new_ascii_("<?php");
|
||||
}
|
||||
class Php_lxr_ws extends Php_lxr_base {
|
||||
public Php_lxr_ws(byte ws_tid) {
|
||||
this.ws_tid = ws_tid;
|
||||
switch (ws_tid) {
|
||||
case Php_tkn_ws.Tid_space: ws_bry = Bry_ws_space; break;
|
||||
case Php_tkn_ws.Tid_nl: ws_bry = Bry_ws_nl; break;
|
||||
case Php_tkn_ws.Tid_tab: ws_bry = Bry_ws_tab; break;
|
||||
case Php_tkn_ws.Tid_cr: ws_bry = Bry_ws_cr; break;
|
||||
}
|
||||
}
|
||||
public byte Ws_tid() {return ws_tid;} private byte ws_tid;
|
||||
public byte[] Ws_bry() {return ws_bry;} private byte[] ws_bry;
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_ws;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
trie.Add(ws_bry, this);
|
||||
parser_interrupts[ws_bry[0]] = Php_parser_interrupt.Char;
|
||||
}
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (cur == src_len) break;
|
||||
byte b = src[cur];
|
||||
switch (b) {
|
||||
case Byte_ascii.Space: case Byte_ascii.NewLine: case Byte_ascii.Tab: case Byte_ascii.CarriageReturn:
|
||||
++cur;
|
||||
break;
|
||||
default:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tkn_wkr.Process(tkn_factory.Ws(bgn, cur, ws_tid));
|
||||
return cur;
|
||||
}
|
||||
public static final byte[] Bry_ws_space = Bry_.new_ascii_(" "), Bry_ws_nl = Bry_.new_ascii_("\n"), Bry_ws_tab = Bry_.new_ascii_("\t"), Bry_ws_cr = Bry_.new_ascii_("\r");
|
||||
}
|
||||
class Php_lxr_comment extends Php_lxr_base {
|
||||
public Php_lxr_comment(byte comment_tid) {
|
||||
this.comment_tid = comment_tid;
|
||||
switch (comment_tid) {
|
||||
case Php_tkn_comment.Tid_mult: comment_bgn = Bry_bgn_mult; comment_end = Bry_end_mult; break;
|
||||
case Php_tkn_comment.Tid_slash: comment_bgn = Bry_bgn_slash; comment_end = Bry_end_nl; break;
|
||||
case Php_tkn_comment.Tid_hash: comment_bgn = Bry_bgn_hash; comment_end = Bry_end_nl; break;
|
||||
}
|
||||
}
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_comment;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
trie.Add(comment_bgn, this);
|
||||
parser_interrupts[Byte_ascii.Slash] = Php_parser_interrupt.Char;
|
||||
parser_interrupts[Byte_ascii.Hash] = Php_parser_interrupt.Char;
|
||||
}
|
||||
public byte Comment_tid() {return comment_tid;} private byte comment_tid;
|
||||
public byte[] Comment_bgn() {return comment_bgn;} private byte[] comment_bgn;
|
||||
public byte[] Comment_end() {return comment_end;} private byte[] comment_end;
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
int end = Bry_finder.Find_fwd(src, comment_end, bgn);
|
||||
if (end == Bry_.NotFound) {
|
||||
tkn_wkr.Msg_many(src, bgn, cur, Php_lxr_comment.Dangling_comment, comment_tid, comment_end);
|
||||
cur = src_len; // NOTE: terminating sequence not found; assume rest of src is comment
|
||||
}
|
||||
else
|
||||
cur = end + comment_end.length;
|
||||
tkn_wkr.Process(tkn_factory.Comment(bgn, cur, comment_tid));
|
||||
return cur;
|
||||
}
|
||||
public static final Gfo_msg_itm Dangling_comment = Gfo_msg_itm_.new_warn_(Php_parser.Log_nde, "dangling_comment", "dangling_comment");
|
||||
public static final byte[] Bry_bgn_mult = Bry_.new_ascii_("/*"), Bry_bgn_slash = Bry_.new_ascii_("//"), Bry_bgn_hash = Bry_.new_ascii_("#")
|
||||
, Bry_end_mult = Bry_.new_ascii_("*/"), Bry_end_nl = Bry_.new_ascii_("\n");
|
||||
}
|
||||
class Php_lxr_var extends Php_lxr_base {
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_var;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
trie.Add(Bry_var, this);
|
||||
parser_interrupts[Byte_ascii.Dollar] = Php_parser_interrupt.Char;
|
||||
}
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (cur == src_len) break;
|
||||
byte b = src[cur];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
case Byte_ascii.Ltr_A: case Byte_ascii.Ltr_B: case Byte_ascii.Ltr_C: case Byte_ascii.Ltr_D: case Byte_ascii.Ltr_E:
|
||||
case Byte_ascii.Ltr_F: case Byte_ascii.Ltr_G: case Byte_ascii.Ltr_H: case Byte_ascii.Ltr_I: case Byte_ascii.Ltr_J:
|
||||
case Byte_ascii.Ltr_K: case Byte_ascii.Ltr_L: case Byte_ascii.Ltr_M: case Byte_ascii.Ltr_N: case Byte_ascii.Ltr_O:
|
||||
case Byte_ascii.Ltr_P: case Byte_ascii.Ltr_Q: case Byte_ascii.Ltr_R: case Byte_ascii.Ltr_S: case Byte_ascii.Ltr_T:
|
||||
case Byte_ascii.Ltr_U: case Byte_ascii.Ltr_V: case Byte_ascii.Ltr_W: case Byte_ascii.Ltr_X: case Byte_ascii.Ltr_Y: case Byte_ascii.Ltr_Z:
|
||||
case Byte_ascii.Ltr_a: case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_e:
|
||||
case Byte_ascii.Ltr_f: case Byte_ascii.Ltr_g: case Byte_ascii.Ltr_h: case Byte_ascii.Ltr_i: case Byte_ascii.Ltr_j:
|
||||
case Byte_ascii.Ltr_k: case Byte_ascii.Ltr_l: case Byte_ascii.Ltr_m: case Byte_ascii.Ltr_n: case Byte_ascii.Ltr_o:
|
||||
case Byte_ascii.Ltr_p: case Byte_ascii.Ltr_q: case Byte_ascii.Ltr_r: case Byte_ascii.Ltr_s: case Byte_ascii.Ltr_t:
|
||||
case Byte_ascii.Ltr_u: case Byte_ascii.Ltr_v: case Byte_ascii.Ltr_w: case Byte_ascii.Ltr_x: case Byte_ascii.Ltr_y: case Byte_ascii.Ltr_z:
|
||||
case Byte_ascii.Underline:
|
||||
++cur;
|
||||
break;
|
||||
default:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tkn_wkr.Process(tkn_factory.Var(bgn, cur));
|
||||
return cur;
|
||||
}
|
||||
private static final byte[] Bry_var = Bry_.new_ascii_("$");
|
||||
}
|
||||
class Php_lxr_sym extends Php_lxr_base {
|
||||
public Php_lxr_sym(String hook_str, byte tkn_tid) {this.hook = Bry_.new_ascii_(hook_str); this.tkn_tid = tkn_tid;} private byte[] hook; byte tkn_tid;
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_sym;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
trie.Add(hook, this);
|
||||
parser_interrupts[hook[0]] = Php_parser_interrupt.Char;
|
||||
}
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
tkn_wkr.Process(tkn_factory.Generic(bgn, cur, tkn_tid));
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
class Php_lxr_quote extends Php_lxr_base {
|
||||
public Php_lxr_quote(byte quote_tid) {
|
||||
this.quote_tid = quote_tid;
|
||||
switch (quote_tid) {
|
||||
case Byte_ascii.Apos: quote_bry = Quote_bry_single; break;
|
||||
case Byte_ascii.Quote: quote_bry = Quote_bry_double; break;
|
||||
}
|
||||
}
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_quote;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
trie.Add(quote_bry, this);
|
||||
parser_interrupts[quote_tid] = Php_parser_interrupt.Char;
|
||||
}
|
||||
public byte Quote_tid() {return quote_tid;} private byte quote_tid;
|
||||
public byte[] Quote_bry() {return quote_bry;} private byte[] quote_bry;
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
int end = -1;
|
||||
while (true) {
|
||||
end = Bry_finder.Find_fwd(src, quote_bry, cur);
|
||||
if (end == Bry_.NotFound) {
|
||||
tkn_wkr.Msg_many(src, bgn, cur, Php_lxr_quote.Dangling_quote, quote_tid, quote_bry);
|
||||
cur = src_len; // NOTE: terminating sequence not found; assume rest of src is comment
|
||||
break;
|
||||
}
|
||||
else {
|
||||
boolean end_quote = true;
|
||||
if (src[end - 1] == Byte_ascii.Backslash) { // \' encountered;
|
||||
int backslash_count = 1;
|
||||
for (int i = end - 2; i > -1; i--) { // count preceding backslashes
|
||||
if (src[i] == Byte_ascii.Backslash)
|
||||
++backslash_count;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (backslash_count % 2 == 1) { // odd backslashes; this means that ' is escaped; EX: \' and \\\'; note that even backslashes means not escaped; EX: \\'
|
||||
end_quote = false;
|
||||
cur = end + 1;
|
||||
}
|
||||
}
|
||||
if (end_quote) {
|
||||
cur = end + quote_bry.length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tkn_wkr.Process(tkn_factory.Quote(bgn, cur, quote_tid));
|
||||
return cur;
|
||||
}
|
||||
public static final Gfo_msg_itm Dangling_quote = Gfo_msg_itm_.new_warn_(Php_parser.Log_nde, "dangling_quote", "dangling_quote");
|
||||
public static final byte[] Quote_bry_single = Bry_.new_ascii_("'"), Quote_bry_double = Bry_.new_ascii_("\"");
|
||||
}
|
||||
class Php_lxr_keyword extends Php_lxr_base {
|
||||
public Php_lxr_keyword(String hook_str, byte tkn_tid) {this.hook = Bry_.new_ascii_(hook_str); this.tkn_tid = tkn_tid;} private byte[] hook; byte tkn_tid;
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_keyword;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {trie.Add(hook, this);}
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
if (cur < src_len) {
|
||||
byte next_byte = src[cur];
|
||||
switch (next_byte) { // valid characters for end of word; EX: 'null '; 'null='; etc..
|
||||
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.NewLine: case Byte_ascii.CarriageReturn:
|
||||
case Byte_ascii.Hash: case Byte_ascii.Slash:
|
||||
case Byte_ascii.Quote: case Byte_ascii.Apos:
|
||||
case Byte_ascii.Bang: case Byte_ascii.Dollar: case Byte_ascii.Percent: case Byte_ascii.Amp:
|
||||
case Byte_ascii.Paren_bgn: case Byte_ascii.Paren_end: case Byte_ascii.Asterisk: case Byte_ascii.Plus:
|
||||
case Byte_ascii.Comma: case Byte_ascii.Dash: case Byte_ascii.Dot: case Byte_ascii.Semic:
|
||||
case Byte_ascii.Lt: case Byte_ascii.Eq: case Byte_ascii.Gt: case Byte_ascii.Question: case Byte_ascii.At:
|
||||
case Byte_ascii.Brack_bgn: case Byte_ascii.Backslash: case Byte_ascii.Brack_end: case Byte_ascii.Pow: case Byte_ascii.Tick:
|
||||
case Byte_ascii.Curly_bgn: case Byte_ascii.Pipe: case Byte_ascii.Curly_end: case Byte_ascii.Tilde:
|
||||
break;
|
||||
default: // num,ltr or extended utf8 character sequence; treat keyword as false match; EX: 'nulla'; 'null0'
|
||||
return Php_parser.NotFound;
|
||||
}
|
||||
}
|
||||
tkn_wkr.Process(tkn_factory.Generic(bgn, cur, tkn_tid));
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
class Php_lxr_num extends Php_lxr_base {
|
||||
@Override public byte Lxr_tid() {return Php_lxr_.Tid_keyword;}
|
||||
@Override public void Lxr_ini(ByteTrieMgr_slim trie, Php_parser_interrupt[] parser_interrupts) {
|
||||
for (int i = 0; i < 10; i++)
|
||||
trie.Add(new byte[] {(byte)(i + Byte_ascii.Num_0)}, this);
|
||||
}
|
||||
@Override public int Lxr_make(Php_ctx ctx, int bgn, int cur) {
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (cur == src_len) break;
|
||||
byte b = src[cur];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
++cur;
|
||||
break;
|
||||
default:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tkn_wkr.Process(tkn_factory.Num(bgn, cur));
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
120
400_xowa/src/gplx/php/Php_parser.java
Normal file
120
400_xowa/src/gplx/php/Php_parser.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public class Php_parser {
|
||||
Php_lxr[] lxrs; int lxrs_len;
|
||||
int txt_bgn; Php_tkn_txt txt_tkn;
|
||||
private ByteTrieMgr_slim trie = ByteTrieMgr_slim.ci_ascii_(); // NOTE:ci:PHP tkns are ASCII
|
||||
byte[] src; int src_len; Php_tkn_wkr tkn_wkr; Php_tkn_factory tkn_factory = new Php_tkn_factory(); Php_ctx ctx = new Php_ctx();
|
||||
Php_parser_interrupt[] parser_interrupts = new Php_parser_interrupt[256];
|
||||
public Php_parser() {
|
||||
ListAdp list = ListAdp_.new_();
|
||||
Init_lxr(list, new Php_lxr_declaration());
|
||||
Init_lxr(list, new Php_lxr_ws(Php_tkn_ws.Tid_space));
|
||||
Init_lxr(list, new Php_lxr_ws(Php_tkn_ws.Tid_nl));
|
||||
Init_lxr(list, new Php_lxr_ws(Php_tkn_ws.Tid_tab));
|
||||
Init_lxr(list, new Php_lxr_ws(Php_tkn_ws.Tid_cr));
|
||||
Init_lxr(list, new Php_lxr_comment(Php_tkn_comment.Tid_mult));
|
||||
Init_lxr(list, new Php_lxr_comment(Php_tkn_comment.Tid_slash));
|
||||
Init_lxr(list, new Php_lxr_comment(Php_tkn_comment.Tid_hash));
|
||||
Init_lxr(list, new Php_lxr_var());
|
||||
Init_lxr(list, new Php_lxr_sym(";", Php_tkn_.Tid_semic));
|
||||
Init_lxr(list, new Php_lxr_sym("=", Php_tkn_.Tid_eq));
|
||||
Init_lxr(list, new Php_lxr_sym("=>", Php_tkn_.Tid_eq_kv));
|
||||
Init_lxr(list, new Php_lxr_sym(",", Php_tkn_.Tid_comma));
|
||||
Init_lxr(list, new Php_lxr_sym("(", Php_tkn_.Tid_paren_bgn));
|
||||
Init_lxr(list, new Php_lxr_sym(")", Php_tkn_.Tid_paren_end));
|
||||
Init_lxr(list, new Php_lxr_sym("[", Php_tkn_.Tid_brack_bgn));
|
||||
Init_lxr(list, new Php_lxr_sym("]", Php_tkn_.Tid_brack_end));
|
||||
Init_lxr(list, new Php_lxr_keyword("null", Php_tkn_.Tid_null));
|
||||
Init_lxr(list, new Php_lxr_keyword("false", Php_tkn_.Tid_false));
|
||||
Init_lxr(list, new Php_lxr_keyword("true", Php_tkn_.Tid_true));
|
||||
Init_lxr(list, new Php_lxr_keyword("array", Php_tkn_.Tid_ary));
|
||||
Init_lxr(list, new Php_lxr_num());
|
||||
Init_lxr(list, new Php_lxr_quote(Byte_ascii.Apos));
|
||||
Init_lxr(list, new Php_lxr_quote(Byte_ascii.Quote));
|
||||
lxrs = (Php_lxr[])list.XtoAry(Php_lxr.class);
|
||||
lxrs_len = list.Count();
|
||||
}
|
||||
private void Init_lxr(ListAdp list, Php_lxr lxr) {
|
||||
lxr.Lxr_ini(trie, parser_interrupts);
|
||||
list.Add(lxr);
|
||||
}
|
||||
public void Parse_tkns(String src, Php_tkn_wkr tkn_wkr) {Parse_tkns(Bry_.new_utf8_(src), tkn_wkr);}
|
||||
public void Parse_tkns(byte[] src, Php_tkn_wkr tkn_wkr) {
|
||||
this.src = src; this.src_len = src.length; this.tkn_wkr = tkn_wkr;
|
||||
ctx.Src_(src);
|
||||
tkn_wkr.Init(ctx);
|
||||
if (src_len == 0) return;
|
||||
|
||||
for (int i = 0; i < lxrs_len; i++)
|
||||
lxrs[i].Lxr_bgn(src, src_len, tkn_wkr, tkn_factory);
|
||||
|
||||
int pos = 0;
|
||||
byte b = src[pos];
|
||||
txt_tkn = null; txt_bgn = 0;
|
||||
boolean loop_raw = true, loop_txt = true;
|
||||
while (loop_raw) {
|
||||
Object o = trie.Match(b, src, pos, src_len);
|
||||
if (o == null) { // char does not hook into a lxr
|
||||
loop_txt = true;
|
||||
while (loop_txt) { // keep looping until end of String or parser_interrupt
|
||||
++pos;
|
||||
if (pos == src_len) {loop_raw = false; break;}
|
||||
b = src[pos];
|
||||
if (parser_interrupts[b & 0xFF] == Php_parser_interrupt.Char) {
|
||||
Make_txt(txt_bgn, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!loop_raw) break;
|
||||
continue; // continue b/c b is set to interrupt char, and should be matched against trie
|
||||
}
|
||||
else { // char hooks into lxr
|
||||
if (txt_bgn != pos) // txt_bgn is set; make text tkn
|
||||
Make_txt(txt_bgn, pos);
|
||||
Php_lxr lxr = (Php_lxr)o;
|
||||
int match_pos = trie.Match_pos();
|
||||
int make_pos = lxr.Lxr_make(ctx, pos, match_pos);
|
||||
if (make_pos == Php_parser.NotFound) {
|
||||
Make_txt(txt_bgn, pos);
|
||||
++pos;
|
||||
}
|
||||
else {
|
||||
txt_tkn = null;
|
||||
txt_bgn = pos = make_pos;
|
||||
}
|
||||
}
|
||||
if (pos == src_len) break;
|
||||
b = src[pos];
|
||||
}
|
||||
if (txt_bgn != pos)
|
||||
Make_txt(txt_bgn, pos);
|
||||
}
|
||||
int Make_txt(int bgn, int end) {
|
||||
if (txt_tkn == null) {
|
||||
txt_tkn = tkn_factory.Txt(bgn, end);
|
||||
tkn_wkr.Process(txt_tkn);
|
||||
}
|
||||
else
|
||||
txt_tkn.Src_end_(end);
|
||||
return end;
|
||||
}
|
||||
public static final int NotFound = -1;
|
||||
public static final Gfo_msg_grp Log_nde = Gfo_msg_grp_.new_(Gfo_msg_grp_.Root_gplx, "php_parser");
|
||||
}
|
||||
399
400_xowa/src/gplx/php/Php_parser_tst.java
Normal file
399
400_xowa/src/gplx/php/Php_parser_tst.java
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Php_parser_tst {
|
||||
Php_parser_fxt fxt = new Php_parser_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Text() {
|
||||
fxt.tst_tkns("text", fxt.tkn_txt(0, 4));
|
||||
}
|
||||
@Test public void Declaration_pass() {
|
||||
fxt.tst_tkns("<?php", fxt.tkn_declaration());
|
||||
}
|
||||
@Test public void Declaration_fail() {
|
||||
fxt.tst_tkns("<?phpx", fxt.tkn_txt(0, 6));
|
||||
}
|
||||
@Test public void Ws_basic() {
|
||||
fxt.tst_tkns(" ", fxt.tkn_ws(0, 1));
|
||||
}
|
||||
@Test public void Ws_mix() {
|
||||
fxt.tst_tkns(" a\n", fxt.tkn_ws(0, 1), fxt.tkn_txt(1, 2), fxt.tkn_ws(2, 3));
|
||||
}
|
||||
@Test public void Comment_mult() {
|
||||
fxt.tst_tkns("/*a*/", fxt.tkn_comment_mult(0, 5));
|
||||
}
|
||||
@Test public void Comment_slash() {
|
||||
fxt.tst_tkns("//a\n", fxt.tkn_comment_slash(0, 4));
|
||||
}
|
||||
@Test public void Comment_hash() {
|
||||
fxt.tst_tkns("#a\n", fxt.tkn_comment_hash(0, 3));
|
||||
}
|
||||
@Test public void Comment_mult_fail() {
|
||||
fxt.Msg(Php_lxr_comment.Dangling_comment, 0, 2).tst_tkns("/*a", fxt.tkn_comment_mult(0, 3));
|
||||
}
|
||||
@Test public void Var() {
|
||||
fxt.tst_tkns("$abc", fxt.tkn_var(0, 4, "abc"));
|
||||
}
|
||||
@Test public void Sym() {
|
||||
fxt.tst_tkns(";==>,()", fxt.tkn_generic(0, 1, Php_tkn_.Tid_semic), fxt.tkn_generic(1, 2, Php_tkn_.Tid_eq), fxt.tkn_generic(2, 4, Php_tkn_.Tid_eq_kv), fxt.tkn_generic(4, 5, Php_tkn_.Tid_comma), fxt.tkn_generic(5, 6, Php_tkn_.Tid_paren_bgn), fxt.tkn_generic(6, 7, Php_tkn_.Tid_paren_end));
|
||||
}
|
||||
@Test public void Keyword() {
|
||||
fxt.tst_tkns("null=nulla", fxt.tkn_generic(0, 4, Php_tkn_.Tid_null), fxt.tkn_generic(4, 5, Php_tkn_.Tid_eq), fxt.tkn_txt(5, 10));
|
||||
}
|
||||
@Test public void Num() {
|
||||
fxt.tst_tkns("0=123", fxt.tkn_num(0, 1, 0), fxt.tkn_generic(1, 2, Php_tkn_.Tid_eq), fxt.tkn_num(2, 5, 123));
|
||||
}
|
||||
@Test public void Quote_apos() {
|
||||
fxt.tst_tkns("'a\"b'", fxt.tkn_quote_apos(0, 5));
|
||||
}
|
||||
@Test public void Quote_quote() {
|
||||
fxt.tst_tkns("\"a'b\"", fxt.tkn_quote_quote(0, 5));
|
||||
}
|
||||
@Test public void Quote_escape() {
|
||||
fxt.tst_tkns("'a\\'b'", fxt.tkn_quote_apos(0, 6));
|
||||
}
|
||||
@Test public void Brack() {
|
||||
fxt.tst_tkns("['a']", fxt.tkn_generic(0, 1, Php_tkn_.Tid_brack_bgn), fxt.tkn_quote_apos(1, 4), fxt.tkn_generic(4, 5, Php_tkn_.Tid_brack_end));
|
||||
}
|
||||
@Test public void Line_assign_false() {
|
||||
fxt.tst_lines("$a = false;", fxt.line_assign("a", fxt.itm_bool_false()));
|
||||
}
|
||||
@Test public void Line_assign_quote_charcode() {
|
||||
fxt.tst_lines("$a = 'bc';", fxt.line_assign("a", fxt.itm_quote("bc")));
|
||||
}
|
||||
@Test public void Line_assign_mult() {
|
||||
fxt.tst_lines("$a = 'b';\n$c='d';", fxt.line_assign("a", fxt.itm_quote("b")), fxt.line_assign("c", fxt.itm_quote("d")));
|
||||
}
|
||||
@Test public void Line_ary_flat() {
|
||||
fxt.tst_lines("$a = array('b', 'c', 'd');", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_quote("b"), fxt.itm_quote("c"), fxt.itm_quote("d"))));
|
||||
}
|
||||
@Test public void Line_ary_flat_escape() { // PURPOSE.fix: \\' was being interpreted incorrectly; \\ should escape \, but somehow \' was being escaped
|
||||
fxt.tst_lines("$a = array('b\\\\', 'c');", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_quote("b\\\\"), fxt.itm_quote("c"))));
|
||||
}
|
||||
@Test public void Line_ary_flat_escape2() { // PURPOSE.fix: \\' was being interpreted incorrectly; \\ should escape \, but somehow \' was being escaped
|
||||
fxt.tst_lines("$a = array('b\\\\\\'c', 'd');", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_quote("b\\\\\\'c"), fxt.itm_quote("d"))));
|
||||
}
|
||||
@Test public void Line_ary_kv() {
|
||||
fxt.tst_lines("$a = array(k0 => 'v0', k1 => 'v1', k2 => 'v2');", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_kv_quote("k0", "v0"), fxt.itm_kv_quote("k1", "v1"), fxt.itm_kv_quote("k2", "v2"))));
|
||||
}
|
||||
@Test public void Line_ary_kv_num() {
|
||||
fxt.tst_lines("$a = array(k0 => 0, k1 => 1);", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_kv_int("k0", 0), fxt.itm_kv_int("k1", 1))));
|
||||
}
|
||||
@Test public void Line_ary_nest() {
|
||||
fxt.tst_lines("$a = array('b', array('c', 'd'), 'e');", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_quote("b"), fxt.itm_ary().Subs_(fxt.itm_quote("c"), fxt.itm_quote("d")), fxt.itm_quote("e"))));
|
||||
}
|
||||
@Test public void Line_ary_nest_kv() {
|
||||
fxt.tst_lines("$a = array('i00' => array('01', '02'), 'i10' => array('11', '12'), 'i20' => array('21', '22'));"
|
||||
, fxt.line_assign
|
||||
( "a"
|
||||
, fxt.itm_ary().Subs_
|
||||
( fxt.itm_kv_itm("i00", fxt.itm_ary().Subs_(fxt.itm_quote("01"), fxt.itm_quote("02")))
|
||||
, fxt.itm_kv_itm("i10", fxt.itm_ary().Subs_(fxt.itm_quote("11"), fxt.itm_quote("12")))
|
||||
, fxt.itm_kv_itm("i20", fxt.itm_ary().Subs_(fxt.itm_quote("21"), fxt.itm_quote("22")))
|
||||
)));
|
||||
}
|
||||
@Test public void Line_ws() {
|
||||
fxt.tst_lines("\r\n$a = false;", fxt.line_assign("a", fxt.itm_bool_false()));
|
||||
}
|
||||
@Test public void Empty_usr_array() {
|
||||
fxt.tst_lines("$a = array();\n$b = array();"
|
||||
, fxt.line_assign("a", fxt.itm_ary())
|
||||
, fxt.line_assign("b", fxt.itm_ary())
|
||||
);
|
||||
}
|
||||
@Test public void Line_ary_kv_txt() {
|
||||
fxt.tst_lines("$a = array('k0' => a, 'k1' => b);", fxt.line_assign("a", fxt.itm_ary().Subs_(fxt.itm_kv_txt("k0", "a"), fxt.itm_kv_txt("k1", "b"))));
|
||||
}
|
||||
@Test public void Line_brack() {
|
||||
fxt.tst_lines("$a['b'] = 'c';", fxt.line_assign_subs("a", String_.Ary("b"), fxt.itm_quote("c")));
|
||||
}
|
||||
}
|
||||
class Php_parser_fxt {
|
||||
Php_tkn_factory tkn_factory = new Php_tkn_factory();
|
||||
Php_parser parser = new Php_parser();
|
||||
Php_tkn_wkr_tkn tkn_wkr = new Php_tkn_wkr_tkn();
|
||||
Php_evaluator line_wkr = new Php_evaluator(new Gfo_msg_log("test"));
|
||||
Tst_mgr tst_mgr = new Tst_mgr();
|
||||
Gfo_msg_log_chkr log_mgr_chkr = new Gfo_msg_log_chkr();
|
||||
public void Clear() {log_mgr_chkr.Clear(); tkn_wkr.Clear(); line_wkr.Clear();}
|
||||
public Php_tkn_chkr_base tkn_declaration() {return Php_tkn_declaration_chkr._;}
|
||||
public Php_tkn_chkr_base tkn_txt(int bgn, int end) {return new Php_tkn_txt_chkr(bgn, end);}
|
||||
public Php_tkn_chkr_base tkn_ws(int bgn, int end) {return new Php_tkn_ws_chkr(bgn, end);}
|
||||
public Php_tkn_chkr_base tkn_generic(int bgn, int end, byte tid) {return new Php_tkn_generic_chkr(bgn, end, tid);}
|
||||
public Php_tkn_comment_chkr tkn_comment_mult(int bgn, int end) {return new Php_tkn_comment_chkr(bgn, end).Comment_tid_(Php_tkn_comment.Tid_mult);}
|
||||
public Php_tkn_comment_chkr tkn_comment_slash(int bgn, int end) {return new Php_tkn_comment_chkr(bgn, end).Comment_tid_(Php_tkn_comment.Tid_slash);}
|
||||
public Php_tkn_comment_chkr tkn_comment_hash(int bgn, int end) {return new Php_tkn_comment_chkr(bgn, end).Comment_tid_(Php_tkn_comment.Tid_hash);}
|
||||
public Php_tkn_quote_chkr tkn_quote_apos(int bgn, int end) {return new Php_tkn_quote_chkr(bgn, end).Quote_tid_(Byte_ascii.Apos);}
|
||||
public Php_tkn_quote_chkr tkn_quote_quote(int bgn, int end) {return new Php_tkn_quote_chkr(bgn, end).Quote_tid_(Byte_ascii.Quote);}
|
||||
public Php_parser_fxt Msg(Gfo_msg_itm itm, int bgn, int end) {
|
||||
log_mgr_chkr.Add_itm(itm, bgn, end);
|
||||
return this;
|
||||
}
|
||||
public Php_tkn_var_chkr tkn_var(int bgn, int end, String v) {return new Php_tkn_var_chkr(bgn, end).Var_name_(v);}
|
||||
public Php_tkn_num_chkr tkn_num(int bgn, int end, int v) {return new Php_tkn_num_chkr(bgn, end).Num_val_int_(v);}
|
||||
public Php_line_assign_chkr line_assign(String key, Php_itm_chkr_base val) {return new Php_line_assign_chkr().Key_(key).Val_(val);}
|
||||
public Php_line_assign_chkr line_assign_subs(String key, String[] subs, Php_itm_chkr_base val) {return new Php_line_assign_chkr().Key_(key).Subs_(subs).Val_(val);}
|
||||
public Php_itm_chkr_base itm_bool_true() {return new Php_itm_generic_chkr(Php_itm_.Tid_bool_true);}
|
||||
public Php_itm_chkr_base itm_bool_false() {return new Php_itm_generic_chkr(Php_itm_.Tid_bool_false);}
|
||||
public Php_itm_chkr_base itm_null() {return new Php_itm_generic_chkr(Php_itm_.Tid_null);}
|
||||
public Php_itm_chkr_base itm_quote(String v) {return new Php_itm_quote_chkr().Val_obj_str_(v);}
|
||||
public Php_itm_chkr_base itm_int(int v) {return new Php_itm_int_chkr().Val_obj_int_(v);}
|
||||
public Php_itm_chkr_base itm_txt(String v) {return new Php_itm_txt_chkr().Val_obj_str_(v);}
|
||||
public Php_itm_ary_chkr itm_ary() {return new Php_itm_ary_chkr();}
|
||||
public Php_itm_kv_chkr itm_kv_quote(String k, String v) {return new Php_itm_kv_chkr().Key_(k).Val_(itm_quote(v));}
|
||||
public Php_itm_kv_chkr itm_kv_txt(String k, String v) {return new Php_itm_kv_chkr().Key_(k).Val_(itm_txt(v));}
|
||||
public Php_itm_kv_chkr itm_kv_int(String k, int v) {return new Php_itm_kv_chkr().Key_(k).Val_(itm_int(v));}
|
||||
public Php_itm_kv_chkr itm_kv_itm(String k, Php_itm_chkr_base v) {return new Php_itm_kv_chkr().Key_(k).Val_(v);}
|
||||
public void tst_tkns(String raw, Php_tkn_chkr_base... expd) {
|
||||
byte[] raw_bry = Bry_.new_utf8_(raw);
|
||||
parser.Parse_tkns(raw_bry, tkn_wkr);
|
||||
Php_tkn[] actl = (Php_tkn[])tkn_wkr.List().XtoAry(Php_tkn.class);
|
||||
tst_mgr.Vars().Clear().Add("raw_bry", raw_bry);
|
||||
tst_mgr.Tst_ary("", expd, actl);
|
||||
log_mgr_chkr.tst(tst_mgr, tkn_wkr.Msg_log());
|
||||
}
|
||||
public void tst_lines(String raw, Php_line_assign_chkr... expd) {
|
||||
byte[] raw_bry = Bry_.new_utf8_(raw);
|
||||
parser.Parse_tkns(raw_bry, line_wkr);
|
||||
Php_line[] actl = (Php_line[])line_wkr.List().XtoAry(Php_line.class);
|
||||
tst_mgr.Vars().Clear().Add("raw_bry", raw_bry);
|
||||
tst_mgr.Tst_ary("", expd, actl);
|
||||
log_mgr_chkr.tst(tst_mgr, line_wkr.Msg_log());
|
||||
}
|
||||
}
|
||||
abstract class Php_tkn_chkr_base implements Tst_chkr {
|
||||
public abstract byte Tkn_tid();
|
||||
public abstract Class<?> TypeOf();
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn = -1;
|
||||
public int Src_end() {return src_end;} private int src_end = -1;
|
||||
public void Src_rng_(int src_bgn, int src_end) {this.src_bgn = src_bgn; this.src_end = src_end;}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Php_tkn actl = (Php_tkn)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(false, path, "tkn_tid", this.Tkn_tid(), actl.Tkn_tid());
|
||||
rv += mgr.Tst_val(src_bgn == -1, path, "src_bgn", src_bgn, actl.Src_bgn());
|
||||
rv += mgr.Tst_val(src_end == -1, path, "src_end", src_end, actl.Src_end());
|
||||
rv += Chk_tkn(mgr, path, actl);
|
||||
return rv;
|
||||
}
|
||||
@gplx.Virtual public int Chk_tkn(Tst_mgr mgr, String path, Php_tkn actl_obj) {return 0;}
|
||||
}
|
||||
class Php_tkn_declaration_chkr extends Php_tkn_chkr_base {
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_declaration.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_declaration;}
|
||||
public static final Php_tkn_declaration_chkr _ = new Php_tkn_declaration_chkr();
|
||||
}
|
||||
class Php_tkn_txt_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_txt_chkr(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_txt.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_txt;}
|
||||
}
|
||||
class Php_tkn_ws_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_ws_chkr(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_ws.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_ws;}
|
||||
}
|
||||
class Php_tkn_comment_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_comment_chkr(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_comment.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_comment;}
|
||||
public Php_tkn_comment_chkr Comment_tid_(byte v) {this.comment_tid = v; return this;} private byte comment_tid = Php_tkn_comment.Tid_null;
|
||||
@Override public int Chk_tkn(Tst_mgr mgr, String path, Php_tkn actl_obj) {
|
||||
Php_tkn_comment actl = (Php_tkn_comment)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(comment_tid == Php_tkn_comment.Tid_null, path, "comment_tid", comment_tid, actl.Comment_tid());
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_tkn_quote_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_quote_chkr(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_quote.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_quote;}
|
||||
public Php_tkn_quote_chkr Quote_tid_(byte v) {this.quote_tid = v; return this;} private byte quote_tid = Byte_ascii.Nil;
|
||||
@Override public int Chk_tkn(Tst_mgr mgr, String path, Php_tkn actl_obj) {
|
||||
Php_tkn_quote actl = (Php_tkn_quote)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(quote_tid == Byte_ascii.Nil, path, "quote_tid", quote_tid, actl.Quote_tid());
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_tkn_var_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_var_chkr(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_var.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_var;}
|
||||
public Php_tkn_var_chkr Var_name_(String v) {this.var_name = v; return this;} private String var_name;
|
||||
@Override public int Chk_tkn(Tst_mgr mgr, String path, Php_tkn actl_obj) {
|
||||
Php_tkn_var actl = (Php_tkn_var)actl_obj;
|
||||
int rv = 0;
|
||||
byte[] raw_bry = (byte[])mgr.Vars_get_by_key("raw_bry");
|
||||
rv += mgr.Tst_val(var_name == null, path, "var_name", var_name, String_.new_utf8_(actl.Var_name(raw_bry)));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_tkn_num_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_num_chkr(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn_num.class;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_num;}
|
||||
public Php_tkn_num_chkr Num_val_int_(int v) {this.num_val_int = v; return this;} private int num_val_int = Int_.MinValue;
|
||||
@Override public int Chk_tkn(Tst_mgr mgr, String path, Php_tkn actl_obj) {
|
||||
Php_tkn_num actl = (Php_tkn_num)actl_obj;
|
||||
int rv = 0;
|
||||
byte[] raw_bry = (byte[])mgr.Vars_get_by_key("raw_bry");
|
||||
rv += mgr.Tst_val(num_val_int == Int_.MinValue, path, "num_val_int", num_val_int, actl.Num_val_int(raw_bry));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_tkn_generic_chkr extends Php_tkn_chkr_base {
|
||||
public Php_tkn_generic_chkr(int src_bgn, int src_end, byte tkn_tid) {this.Src_rng_(src_bgn, src_end); this.tkn_tid = tkn_tid;}
|
||||
@Override public Class<?> TypeOf() {return Php_tkn.class;}
|
||||
@Override public byte Tkn_tid() {return tkn_tid;} private byte tkn_tid;
|
||||
}
|
||||
class Php_line_assign_chkr implements Tst_chkr {
|
||||
public Class<?> TypeOf() {return Php_line_assign.class;}
|
||||
public Php_line_assign_chkr Key_(String v) {key = v; return this;} private String key;
|
||||
public Php_line_assign_chkr Subs_(String[] v) {
|
||||
int subs_len = v.length;
|
||||
subs = new Php_itm_quote_chkr[subs_len];
|
||||
for (int i = 0; i < subs_len; i++)
|
||||
subs[i] = new Php_itm_quote_chkr().Val_obj_str_(v[i]);
|
||||
return this;
|
||||
} Php_itm_chkr_base[] subs;
|
||||
public Php_line_assign_chkr Val_(Php_itm_chkr_base v) {val = v; return this;} Php_itm_chkr_base val;
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Php_line_assign actl = (Php_line_assign)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(key == null, path, "key", key, String_.new_utf8_(actl.Key().Val_obj_bry()));
|
||||
if (subs != null) rv += mgr.Tst_sub_ary(subs, actl.Key_subs(), "subs", rv);
|
||||
rv += mgr.Tst_sub_obj(val, actl.Val(), "val", rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
abstract class Php_itm_chkr_base implements Tst_chkr {
|
||||
public abstract byte Itm_tid();
|
||||
public abstract Class<?> TypeOf();
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Php_itm actl = (Php_itm)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(false, path, "tkn_tid", this.Itm_tid(), actl.Itm_tid());
|
||||
rv += Chk_itm(mgr, path, actl);
|
||||
return rv;
|
||||
}
|
||||
@gplx.Virtual public int Chk_itm(Tst_mgr mgr, String path, Php_itm actl_obj) {return 0;}
|
||||
public static final Php_itm_chkr_base[] Ary_empty = new Php_itm_chkr_base[0];
|
||||
}
|
||||
class Php_itm_generic_chkr extends Php_itm_chkr_base {
|
||||
public Php_itm_generic_chkr(byte itm_tid) {this.itm_tid = itm_tid;} private byte itm_tid;
|
||||
@Override public byte Itm_tid() {return itm_tid;}
|
||||
@Override public Class<?> TypeOf() {return Php_itm.class;}
|
||||
}
|
||||
class Php_itm_int_chkr extends Php_itm_chkr_base {
|
||||
@Override public byte Itm_tid() {return Php_itm_.Tid_int;}
|
||||
@Override public Class<?> TypeOf() {return Php_itm.class;}
|
||||
public Php_itm_int_chkr Val_obj_int_(int v) {this.val_obj_int = v; return this;} private int val_obj_int;
|
||||
@Override public int Chk_itm(Tst_mgr mgr, String path, Php_itm actl_obj) {
|
||||
Php_itm_int actl = (Php_itm_int)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(false, path, "val_obj_str", val_obj_int, actl.Val_obj_int());
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_itm_txt_chkr extends Php_itm_chkr_base {
|
||||
@Override public byte Itm_tid() {return Php_itm_.Tid_var;}
|
||||
@Override public Class<?> TypeOf() {return Php_itm.class;}
|
||||
public Php_itm_txt_chkr Val_obj_str_(String v) {this.val_obj_str = v; return this;} private String val_obj_str;
|
||||
@Override public int Chk_itm(Tst_mgr mgr, String path, Php_itm actl_obj) {
|
||||
Php_itm_var actl = (Php_itm_var)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(false, path, "val_obj_str", val_obj_str, String_.new_utf8_(actl.Val_obj_bry()));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_itm_quote_chkr extends Php_itm_chkr_base {
|
||||
@Override public byte Itm_tid() {return Php_itm_.Tid_quote;}
|
||||
@Override public Class<?> TypeOf() {return Php_itm.class;}
|
||||
public Php_itm_quote_chkr Val_obj_str_(String v) {this.val_obj_str = v; return this;} private String val_obj_str;
|
||||
@Override public int Chk_itm(Tst_mgr mgr, String path, Php_itm actl_obj) {
|
||||
Php_itm_quote actl = (Php_itm_quote)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(false, path, "val_obj_str", val_obj_str, String_.new_utf8_(actl.Val_obj_bry()));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_itm_ary_chkr extends Php_itm_chkr_base {
|
||||
@Override public byte Itm_tid() {return Php_itm_.Tid_ary;}
|
||||
@Override public Class<?> TypeOf() {return Php_itm.class;}
|
||||
public Php_itm_ary_chkr Subs_(Php_itm_chkr_base... v) {this.itms = v; return this;} Php_itm_chkr_base[] itms = Php_itm_chkr_base.Ary_empty;
|
||||
@Override public int Chk_itm(Tst_mgr mgr, String path, Php_itm actl_obj) {
|
||||
Php_itm_ary actl = (Php_itm_ary)actl_obj;
|
||||
int rv = 0;
|
||||
int actl_subs_len = actl.Subs_len();
|
||||
Php_itm[] actl_ary = new Php_itm[actl_subs_len];
|
||||
for (int i = 0; i < actl_subs_len; i++) {
|
||||
actl_ary[i] = (Php_itm)actl.Subs_get(i);
|
||||
}
|
||||
rv += mgr.Tst_sub_ary(itms, actl_ary, "subs", rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Php_itm_kv_chkr extends Php_itm_chkr_base {
|
||||
@Override public byte Itm_tid() {return Php_itm_.Tid_kv;}
|
||||
@Override public Class<?> TypeOf() {return Php_itm.class;}
|
||||
public Php_itm_kv_chkr Key_(String v) {key = v; return this;} private String key;
|
||||
public Php_itm_kv_chkr Val_(Php_itm_chkr_base v) {val = v; return this;} Php_itm_chkr_base val;
|
||||
@Override public int Chk_itm(Tst_mgr mgr, String path, Php_itm actl_obj) {
|
||||
Php_itm_kv actl = (Php_itm_kv)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(false, path, "key", key, String_.new_utf8_(actl.Key().Val_obj_bry()));
|
||||
rv += mgr.Tst_sub_obj(val, actl.Val(), path, rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Gfo_msg_log_chkr implements Tst_chkr {
|
||||
ListAdp itms = ListAdp_.new_();
|
||||
public Class<?> TypeOf() {return Gfo_msg_log.class;}
|
||||
public void Clear() {itms.Clear();}
|
||||
public void Add_itm(Gfo_msg_itm itm, int bgn, int end) {
|
||||
Gfo_msg_data_chkr chkr = new Gfo_msg_data_chkr();
|
||||
chkr.Itm_(itm).Excerpt_bgn_(bgn).Excerpt_end_(end);
|
||||
itms.Add(chkr);
|
||||
}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {return 0;}
|
||||
public void tst(Tst_mgr mgr, Object actl_obj) {
|
||||
Gfo_msg_log actl = (Gfo_msg_log)actl_obj;
|
||||
int actl_itms_len = actl.Ary_len();
|
||||
Gfo_msg_data[] actl_itms = new Gfo_msg_data[actl_itms_len];
|
||||
for (int i = 0; i < actl_itms_len; i++)
|
||||
actl_itms[i] = actl.Ary_get(i);
|
||||
mgr.Tst_ary("itms", (Gfo_msg_data_chkr[])itms.XtoAry(Gfo_msg_data_chkr.class), actl_itms);
|
||||
}
|
||||
}
|
||||
class Gfo_msg_data_chkr implements Tst_chkr {
|
||||
public Class<?> TypeOf() {return Gfo_msg_data.class;}
|
||||
public Gfo_msg_data_chkr Itm_(Gfo_msg_itm v) {itm = v; return this;} Gfo_msg_itm itm;
|
||||
public Gfo_msg_data_chkr Excerpt_bgn_(int v) {excerpt_bgn = v; return this;} private int excerpt_bgn = -1;
|
||||
public Gfo_msg_data_chkr Excerpt_end_(int v) {excerpt_end = v; return this;} private int excerpt_end = -1;
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Gfo_msg_data actl = (Gfo_msg_data)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(itm == null, path, "itm", itm.Path_str(), actl.Item().Path_str());
|
||||
rv += mgr.Tst_val(excerpt_bgn == -1, path, "excerpt_bgn", excerpt_bgn, actl.Src_bgn());
|
||||
rv += mgr.Tst_val(excerpt_end == -1, path, "excerpt_end", excerpt_end, actl.Src_end());
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
138
400_xowa/src/gplx/php/Php_srl_itm.java
Normal file
138
400_xowa/src/gplx/php/Php_srl_itm.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
interface Php_srl_itm {
|
||||
byte Tid();
|
||||
int Src_bgn();
|
||||
int Src_end();
|
||||
Object Val();
|
||||
void Xto_bfr(Bry_bfr bfr, int depth);
|
||||
void Clear();
|
||||
}
|
||||
class Php_srl_itm_ {
|
||||
public static final Php_srl_itm[] Ary_empty = new Php_srl_itm[0];
|
||||
public static final byte Tid_unknown = 0, Tid_nil = 1, Tid_bool = 2, Tid_int = 3, Tid_double = 4, Tid_string = 5, Tid_array = 6, Tid_function = 7;
|
||||
public static final byte[][] Names = Bry_.Ary("unknown", "nil", "boolean", "int", "double", "string", "array", "function");
|
||||
public static final Object Val_nil = null, Val_table = null;
|
||||
}
|
||||
abstract class Php_srl_itm_base implements Php_srl_itm {
|
||||
public abstract byte Tid();
|
||||
public void Ctor(int src_bgn, int src_end, Object val) {this.src_bgn = src_bgn; this.src_end = src_end; this.val = val;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public Object Val() {return val;} Object val;
|
||||
@gplx.Virtual public void Xto_bfr(Bry_bfr bfr, int depth) {
|
||||
Php_srl_wtr.Indent(bfr, depth);
|
||||
bfr.Add(Php_srl_itm_.Names[this.Tid()]).Add_byte(Byte_ascii.Colon);
|
||||
bfr.Add_str(Object_.XtoStr_OrNullStr(this.Val())).Add_byte(Byte_ascii.Semic).Add_byte_nl();
|
||||
}
|
||||
public void Clear() {}
|
||||
}
|
||||
class Php_srl_itm_nil extends Php_srl_itm_base {
|
||||
public Php_srl_itm_nil() {this.Ctor(-1, -1, null);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_nil;}
|
||||
public byte[] Bry_extract(byte[] raw) {return null;}
|
||||
public static Php_srl_itm_nil Nil = new Php_srl_itm_nil();
|
||||
}
|
||||
class Php_srl_itm_bool extends Php_srl_itm_base {
|
||||
public Php_srl_itm_bool(boolean val, byte[] bry) {this.val = val; this.bry = bry; this.Ctor(-1, -1, val);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_bool;}
|
||||
public byte[] Bry_extract(byte[] raw) {return bry;} private byte[] bry;
|
||||
public boolean Val_as_bool() {return val;} private boolean val;
|
||||
public static Php_srl_itm_bool Bool_n = new Php_srl_itm_bool(false, new byte[] {Byte_ascii.Num_0}), Bool_y = new Php_srl_itm_bool(true, new byte[] {Byte_ascii.Num_1});
|
||||
}
|
||||
class Php_srl_itm_int extends Php_srl_itm_base {
|
||||
public Php_srl_itm_int(int src_bgn, int src_end, int val) {this.val = val; this.Ctor(src_bgn, src_end, val);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_int;}
|
||||
public int Val_as_int() {return val;} private int val;
|
||||
}
|
||||
class Php_srl_itm_double extends Php_srl_itm_base {
|
||||
public Php_srl_itm_double(int src_bgn, int src_end, double val) {this.val = val; this.Ctor(src_bgn, src_end, val);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_double;}
|
||||
public double Val_as_double() {return val;} double val;
|
||||
}
|
||||
class Php_srl_itm_str extends Php_srl_itm_base {
|
||||
public Php_srl_itm_str(int src_bgn, int src_end, String val) {this.val = val; this.Ctor(src_bgn, src_end, val);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_string;}
|
||||
public String Val_as_str() {return val;} private String val;
|
||||
}
|
||||
class Php_srl_itm_func extends Php_srl_itm_base {
|
||||
public Php_srl_itm_func(int src_bgn, int src_end, int val) {this.val = val; this.Ctor(src_bgn, src_end, val);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_function;}
|
||||
public int Val_as_int() {return val;} private int val;
|
||||
}
|
||||
class Php_srl_itm_ary extends Php_srl_itm_base {
|
||||
public Php_srl_itm_ary(int src_bgn, int src_end) {this.Ctor(src_bgn, src_end, null);}
|
||||
@Override public byte Tid() {return Php_srl_itm_.Tid_array;}
|
||||
public Php_srl_itm_kv[] Subs_ary() {return subs;}
|
||||
public int Subs_len() {return subs_len;} private int subs_len = 0, subs_max = 0;
|
||||
public Php_srl_itm_kv Subs_get_at(int i) {return subs[i];}
|
||||
public void Subs_clear() {
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
subs[i].Clear();
|
||||
}
|
||||
subs = Php_srl_itm_kv.Ary_empty;
|
||||
subs_len = subs_max = 0;
|
||||
}
|
||||
public Php_srl_itm_ary Subs_add_many(Php_srl_itm_kv... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Subs_add(ary[i]);
|
||||
return this;
|
||||
}
|
||||
public Php_srl_itm_ary Subs_add(Php_srl_itm_kv itm) {
|
||||
int new_len = subs_len + 1;
|
||||
if (new_len > subs_max) { // ary too small >>> expand
|
||||
subs_max = new_len * 2;
|
||||
Php_srl_itm_kv[] new_subs = new Php_srl_itm_kv[subs_max];
|
||||
Array_.CopyTo(subs, 0, new_subs, 0, subs_len);
|
||||
subs = new_subs;
|
||||
}
|
||||
subs[subs_len] = itm;
|
||||
subs_len = new_len;
|
||||
return this;
|
||||
}
|
||||
@Override public void Xto_bfr(Bry_bfr bfr, int depth) {
|
||||
Php_srl_wtr.Indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Ltr_a).Add_byte(Byte_ascii.Brack_bgn).Add_int_variable(subs_len).Add(CONST_ary_bgn);
|
||||
for (int i = 0; i < subs_len; i++)
|
||||
subs[i].Xto_bfr(bfr, depth + 1);
|
||||
Php_srl_wtr.Indent(bfr, depth);
|
||||
bfr.Add_byte(Byte_ascii.Curly_end).Add_byte_nl();
|
||||
} static final byte[] CONST_ary_bgn = Bry_.new_ascii_("]{\n");
|
||||
Php_srl_itm_kv[] subs = Php_srl_itm_kv.Ary_empty;
|
||||
}
|
||||
class Php_srl_itm_kv {
|
||||
public int Idx_int() {return idx_int;} public Php_srl_itm_kv Idx_int_(int v) {idx_int = v; return this;} private int idx_int = -1;
|
||||
public Php_srl_itm Key() {return key;} public Php_srl_itm_kv Key_(Php_srl_itm v) {key = v; return this;} Php_srl_itm key;
|
||||
public Php_srl_itm Val() {return val;} public Php_srl_itm_kv Val_(Php_srl_itm v) {val = v; return this;} Php_srl_itm val;
|
||||
public void Clear() {
|
||||
key.Clear();
|
||||
val.Clear();
|
||||
}
|
||||
public void Xto_bfr(Bry_bfr bfr, int depth) {
|
||||
key.Xto_bfr(bfr, depth);
|
||||
val.Xto_bfr(bfr, depth);
|
||||
}
|
||||
public static final Php_srl_itm_kv[] Ary_empty = new Php_srl_itm_kv[0];
|
||||
}
|
||||
class Php_srl_wtr {
|
||||
public static void Indent(Bry_bfr bfr, int depth) {
|
||||
if (depth > 0) bfr.Add_byte_repeat(Byte_ascii.Space, depth * 2); // indent
|
||||
}
|
||||
}
|
||||
208
400_xowa/src/gplx/php/Php_srl_parser.java
Normal file
208
400_xowa/src/gplx/php/Php_srl_parser.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
import gplx.texts.*;
|
||||
public class Php_srl_parser {
|
||||
@gplx.Internal protected Php_srl_factory Factory() {return factory;} Php_srl_factory factory = new Php_srl_factory();
|
||||
byte[] raw; int raw_len, pos;
|
||||
public KeyVal[] Parse_as_kvs(byte[] raw) {
|
||||
Php_srl_itm_ary root = Parse(raw);
|
||||
return Xto_kv_ary(root);
|
||||
}
|
||||
KeyVal[] Xto_kv_ary(Php_srl_itm_ary ary) {
|
||||
int len = ary.Subs_len();
|
||||
KeyVal[] rv = new KeyVal[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
rv[i] = Xto_kv(ary.Subs_get_at(i));
|
||||
return rv;
|
||||
}
|
||||
KeyVal Xto_kv(Php_srl_itm_kv itm) {
|
||||
Php_srl_itm itm_key = itm.Key();
|
||||
Object key = itm_key == null ? null : itm_key.Val();
|
||||
Php_srl_itm itm_val = itm.Val();
|
||||
Object val = null;
|
||||
switch (itm_val.Tid()) {
|
||||
case Php_srl_itm_.Tid_array:
|
||||
Php_srl_itm_ary ary = (Php_srl_itm_ary)itm_val;
|
||||
val = Xto_kv_ary(ary);
|
||||
break;
|
||||
case Php_srl_itm_.Tid_function:
|
||||
val = new gplx.xowa.xtns.scribunto.Scrib_lua_proc(Object_.XtoStr_OrNullStr(key), Int_.cast_(itm_val.Val())); // NOTE: in most cases, key is a STRING (name of ScribFunction); however, for gsub it is an INT (arg_idx) b/c it is passed as a parameter
|
||||
break;
|
||||
default:
|
||||
val = itm_val.Val();
|
||||
break;
|
||||
}
|
||||
return KeyVal_.obj_(key, val);
|
||||
}
|
||||
@gplx.Internal protected Php_srl_itm_ary Parse(byte[] raw) {
|
||||
this.raw = raw; this.raw_len = raw.length; pos = 0;
|
||||
Php_srl_itm_ary rv = new Php_srl_itm_ary(0, raw_len);
|
||||
Php_srl_itm_kv cur_kv = factory.Kv();
|
||||
rv.Subs_add(cur_kv);
|
||||
boolean mode_is_key = false;
|
||||
while (true) {
|
||||
if (pos >= raw_len) break;
|
||||
if (mode_is_key) {
|
||||
cur_kv.Key_(Parse_itm(pos));
|
||||
mode_is_key = false;
|
||||
}
|
||||
else {
|
||||
cur_kv.Val_(Parse_itm(pos));
|
||||
mode_is_key = true;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
Php_srl_itm_ary Parse_array(int bgn, int subs_len) { // enters after '{'; EX: 'a:1{' -> Parse_array
|
||||
Php_srl_itm_ary rv = factory.Ary(bgn, bgn);
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Php_srl_itm_kv kv = factory.Kv();
|
||||
Php_srl_itm key_itm = Parse_itm(pos);
|
||||
kv.Key_(key_itm);
|
||||
Php_srl_itm val_itm = Parse_itm(pos);
|
||||
kv.Val_(val_itm);
|
||||
rv.Subs_add(kv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
Php_srl_itm Parse_itm(int bgn) {
|
||||
pos = bgn;
|
||||
Php_srl_itm rv = null;
|
||||
byte b = raw[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Ltr_N: // EX: 'N;'
|
||||
rv = factory.Nil();
|
||||
pos = Chk(raw, pos + 1, Byte_ascii.Semic);
|
||||
break;
|
||||
case Byte_ascii.Ltr_b: // EX: 'b:0;' or 'b:1;'
|
||||
pos = Chk(raw, pos + 1, Byte_ascii.Colon);
|
||||
b = raw[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_1: rv = factory.Bool_y(); break;
|
||||
case Byte_ascii.Num_0: rv = factory.Bool_n(); break;
|
||||
default: throw err_(raw, pos, raw_len, "unknown boolean type {0}", Char_.XtoStr(b));
|
||||
}
|
||||
pos = Chk(raw, pos + 1, Byte_ascii.Semic);
|
||||
break;
|
||||
case Byte_ascii.Ltr_i: // EX: 'i:123;'
|
||||
rv = Parse_int(pos);
|
||||
pos = Chk(raw, pos, Byte_ascii.Semic);
|
||||
break;
|
||||
case Byte_ascii.Ltr_d: // EX: 'd:1.23;'
|
||||
pos = Chk(raw, pos + 1, Byte_ascii.Colon);
|
||||
int double_end = Bry_finder.Find_fwd(raw, Byte_ascii.Semic, pos, raw_len);
|
||||
String double_str = String_.new_ascii_(raw, pos, double_end);
|
||||
double double_val = 0;
|
||||
if (String_.Eq(double_str, "INF")) double_val = Double_.Inf_pos;
|
||||
else if (String_.Eq(double_str, "NAN")) double_val = Double_.NaN;
|
||||
else double_val = Double_.parse_(double_str);
|
||||
rv = factory.Double(pos, double_end, double_val);
|
||||
pos = Chk(raw, double_end, Byte_ascii.Semic);
|
||||
break;
|
||||
case Byte_ascii.Ltr_s: // EX: 's:3:"abc";'
|
||||
int len_val = Parse_int(pos).Val_as_int();
|
||||
pos = Chk(raw, pos, Byte_ascii.Colon);
|
||||
pos = Chk(raw, pos, Byte_ascii.Quote);
|
||||
int str_end = pos + len_val;
|
||||
String str_val = String_.new_utf8_(raw, pos, str_end);
|
||||
rv = factory.Str(pos, str_end, str_val);
|
||||
pos = Chk(raw, str_end, Byte_ascii.Quote);
|
||||
pos = Chk(raw, pos, Byte_ascii.Semic);
|
||||
break;
|
||||
case Byte_ascii.Ltr_a: // EX: 'a:0:{}'
|
||||
int subs_len = Parse_int(pos).Val_as_int();
|
||||
pos = Chk(raw, pos, Byte_ascii.Colon);
|
||||
pos = Chk(raw, pos, Byte_ascii.Curly_bgn);
|
||||
rv = Parse_array(pos, subs_len);
|
||||
pos = Chk(raw, pos, Byte_ascii.Curly_end);
|
||||
break;
|
||||
case Byte_ascii.Ltr_O: // EX: 'O:42:"Scribunto_LuaStandaloneInterpreterFunction":1:{s:2:"id";i:123;}'
|
||||
int func_bgn = pos;
|
||||
pos += 62; // 64= len of constant String after ":42:"Scribunto...."
|
||||
int func_id = Parse_int_val(pos);
|
||||
rv = factory.Func(func_bgn, pos, func_id);
|
||||
pos += 2;
|
||||
break;
|
||||
default: throw err_(raw, pos, "unexpected type: {0}", Char_.XtoStr(b));
|
||||
}
|
||||
return rv;
|
||||
} static final byte[] CONST_funct_bgn = Bry_.new_ascii_("O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:"), CONST_funct_end = Bry_.new_ascii_(";}");
|
||||
int Parse_int_val(int bgn) {
|
||||
pos = bgn;
|
||||
pos = Chk(raw, pos + 1, Byte_ascii.Colon);
|
||||
int int_end = Skip_while_num(raw, raw_len, pos, true);
|
||||
int int_val = Bry_.X_to_int_or(raw, pos, int_end, Int_.MinValue);
|
||||
pos = int_end;
|
||||
return int_val;
|
||||
}
|
||||
Php_srl_itm_int Parse_int(int bgn) {
|
||||
pos = bgn;
|
||||
pos = Chk(raw, pos + 1, Byte_ascii.Colon);
|
||||
int int_end = Skip_while_num(raw, raw_len, pos, true);
|
||||
int int_val = Bry_.X_to_int_or(raw, pos, int_end, Int_.MinValue);
|
||||
Php_srl_itm_int rv = factory.Int(pos, int_end, int_val);
|
||||
pos = int_end;
|
||||
return rv;
|
||||
}
|
||||
int Chk(byte[] raw, int i, byte expd) {
|
||||
byte actl = raw[i];
|
||||
if (actl == expd)
|
||||
return i + 1;
|
||||
else
|
||||
throw err_(raw, i, "expected '{0}' but got '{1}'", Char_.XtoStr(expd), Char_.XtoStr(actl));
|
||||
}
|
||||
int Skip_while_num(byte[] raw, int raw_len, int bgn, boolean num_is_int) {
|
||||
int num_len = 1;
|
||||
for (int i = bgn; i < raw_len; i++) {
|
||||
byte b = raw[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
break;
|
||||
case Byte_ascii.Dot:
|
||||
case Byte_ascii.Dash:
|
||||
break;
|
||||
default:
|
||||
if (num_is_int && num_len < 11) {
|
||||
return i;
|
||||
}
|
||||
else
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw err_(raw, raw_len, raw_len, "skip_ws found eos");
|
||||
}
|
||||
Err err_(byte[] raw, int bgn, String fmt, Object... args) {return err_(raw, bgn, raw.length, fmt, args);}
|
||||
Err err_(byte[] raw, int bgn, int raw_len, String fmt, Object... args) {
|
||||
String msg = String_.Format(fmt, args) + " " + Int_.XtoStr(bgn) + " " + String_.new_utf8_len_safe_(raw, bgn, 20);
|
||||
return Err_.new_(msg);
|
||||
}
|
||||
}
|
||||
class Php_srl_factory {
|
||||
public Php_srl_itm Nil() {return Php_srl_itm_nil.Nil;}
|
||||
public Php_srl_itm Bool_n() {return Php_srl_itm_bool.Bool_n;}
|
||||
public Php_srl_itm Bool_y() {return Php_srl_itm_bool.Bool_y;}
|
||||
public Php_srl_itm_int Int(int bgn, int end, int v) {return new Php_srl_itm_int(bgn, end, v);}
|
||||
public Php_srl_itm Double(int bgn, int end, double v) {return new Php_srl_itm_double(bgn, end, v);}
|
||||
public Php_srl_itm Str(int bgn, int end) {return new Php_srl_itm_str(bgn, end, null);}
|
||||
public Php_srl_itm Str(int bgn, int end, String v) {return new Php_srl_itm_str(bgn, end, v);}
|
||||
public Php_srl_itm_func Func(int bgn, int end, int v) {return new Php_srl_itm_func(bgn, end, v);}
|
||||
public Php_srl_itm_ary Ary(int bgn, int end) {return new Php_srl_itm_ary(bgn, end);}
|
||||
public Php_srl_itm_kv Kv() {return new Php_srl_itm_kv();}
|
||||
}
|
||||
112
400_xowa/src/gplx/php/Php_srl_parser_tst.java
Normal file
112
400_xowa/src/gplx/php/Php_srl_parser_tst.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Php_srl_parser_tst {
|
||||
Php_srl_parser_fxt fxt = new Php_srl_parser_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Nil() {fxt.Test_parse("N;", fxt.itm_nil_());}
|
||||
@Test public void Bool_y() {fxt.Test_parse("b:1;", fxt.itm_bool_y_());}
|
||||
@Test public void Bool_n() {fxt.Test_parse("b:0;", fxt.itm_bool_n_());}
|
||||
@Test public void Num_int() {fxt.Test_parse("i:123;", fxt.itm_int_(123));}
|
||||
@Test public void Num_int_neg() {fxt.Test_parse("i:-123;", fxt.itm_int_(-123));}
|
||||
@Test public void Num_double() {fxt.Test_parse("d:1.23;", fxt.itm_double_(1.23d));}
|
||||
@Test public void Num_double_inf_pos(){fxt.Test_parse("d:INF;", fxt.itm_double_(Double_.Inf_pos));}
|
||||
@Test public void Num_double_exp() {fxt.Test_parse("d:1.2e+2;", fxt.itm_double_(120));}
|
||||
@Test public void Num_double_nan() {fxt.Test_parse("d:NAN;", fxt.itm_double_(Double_.NaN));}
|
||||
@Test public void Str_len_3() {fxt.Test_parse("s:3:\"abc\";", fxt.itm_str_("abc"));}
|
||||
@Test public void Str_len_4() {fxt.Test_parse("s:4:\"abcd\";", fxt.itm_str_("abcd"));}
|
||||
@Test public void Str_len_0() {fxt.Test_parse("s:0:\"\";", fxt.itm_str_(""));}
|
||||
@Test public void Ary_empty() {fxt.Test_parse("a:0:{}", fxt.itm_ary_());}
|
||||
@Test public void Ary_flat_one() {fxt.Test_parse("a:1:{i:1;i:9;}", fxt.itm_ary_().Subs_add(fxt.itm_kvi_(1, fxt.itm_int_(9))));}
|
||||
@Test public void Ary_flat_many() {
|
||||
fxt.Test_parse(String_.Concat
|
||||
( "a:3:{"
|
||||
, "i:1;i:9;"
|
||||
, "i:2;i:8;"
|
||||
, "i:3;i:7;"
|
||||
, "}"), fxt.itm_ary_().Subs_add_many
|
||||
( fxt.itm_kvi_(1, fxt.itm_int_(9))
|
||||
, fxt.itm_kvi_(2, fxt.itm_int_(8))
|
||||
, fxt.itm_kvi_(3, fxt.itm_int_(7))
|
||||
));
|
||||
}
|
||||
@Test public void Ary_nest_one() {
|
||||
fxt.Test_parse(String_.Concat
|
||||
( "a:1:{"
|
||||
, "i:1;"
|
||||
, "a:2:{"
|
||||
, "i:1;i:9;"
|
||||
, "i:2;i:8;"
|
||||
, "}"
|
||||
, "}"
|
||||
)
|
||||
, fxt.itm_ary_().Subs_add_many
|
||||
( fxt.itm_kvi_(1, fxt.itm_ary_().Subs_add_many
|
||||
( fxt.itm_kvi_(1, fxt.itm_int_(9))
|
||||
, fxt.itm_kvi_(2, fxt.itm_int_(8))
|
||||
))));
|
||||
}
|
||||
@Test public void Ary_key_str() {
|
||||
fxt.Test_parse(String_.Concat
|
||||
( "a:1:{"
|
||||
, "s:3:\"abc\";"
|
||||
, "i:987;"
|
||||
, "}"), fxt.itm_ary_().Subs_add_many
|
||||
( fxt.itm_kvs_("abc", fxt.itm_int_(987))
|
||||
));
|
||||
}
|
||||
@Test public void Func() {
|
||||
fxt.Test_parse("O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:123;}", fxt.itm_func_(123));
|
||||
}
|
||||
@Test public void Smoke() {
|
||||
// fxt.Test_parse("a:2:{s:6:\"values\";a:1:{i:1;a:9:{s:21:\"makeProt"+"ectedEnvFuncs\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:2;}s:3:\"log\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:3;}s:14:\"clearLogBuffer\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:4;}s:5:\"setup\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:5;}s:5:\"clone\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:6;}s:15:\"getCurrentFrame\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:7;}s:13:\"executeModule\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:8;}s:15:\"executeFunction\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:9;}s:12:\"getLogBuffer\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:10;}}}s:2:\"op\";s:6:\"return\";}");
|
||||
}
|
||||
}
|
||||
class Php_srl_parser_fxt {
|
||||
public void Clear() {
|
||||
parser = new Php_srl_parser();
|
||||
factory = parser.Factory();
|
||||
} Php_srl_parser parser; Php_srl_factory factory; Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
|
||||
public Php_srl_itm itm_nil_() {return factory.Nil();}
|
||||
public Php_srl_itm itm_bool_n_() {return factory.Bool_n();}
|
||||
public Php_srl_itm itm_bool_y_() {return factory.Bool_y();}
|
||||
public Php_srl_itm itm_int_(int v) {return factory.Int(-1, -1, v);}
|
||||
public Php_srl_itm itm_double_(double v) {return factory.Double(-1, -1, v);}
|
||||
public Php_srl_itm itm_str_(String v) {return factory.Str(-1, -1, v);}
|
||||
public Php_srl_itm itm_func_(int v) {return factory.Func(-1, -1, v);}
|
||||
public Php_srl_itm_ary itm_ary_() {return factory.Ary(-1, -1);}
|
||||
public Php_srl_itm_kv itm_kvi_(int k, Php_srl_itm v){return factory.Kv().Key_(itm_int_(k)).Val_(v);}
|
||||
public Php_srl_itm_kv itm_kvs_(String k, Php_srl_itm v){return factory.Kv().Key_(itm_str_(k)).Val_(v);}
|
||||
public void Test_parse(String raw_str, Php_srl_itm... expd_ary) {
|
||||
byte[] raw = Bry_.new_utf8_(raw_str);
|
||||
Php_srl_itm_ary root = parser.Parse(raw);
|
||||
Php_srl_itm root_sub = root.Subs_get_at(0).Val();
|
||||
root_sub.Xto_bfr(tmp_bfr, 0);
|
||||
String actl = tmp_bfr.XtoStrAndClear();
|
||||
String expd = Xto_str(expd_ary, 0, expd_ary.length);
|
||||
Tfds.Eq_str_lines(expd, actl, actl);
|
||||
}
|
||||
String Xto_str(Php_srl_itm[] ary, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
Php_srl_itm itm = ary[i];
|
||||
itm.Xto_bfr(tmp_bfr, 0);
|
||||
}
|
||||
return tmp_bfr.XtoStrAndClear();
|
||||
}
|
||||
}
|
||||
62
400_xowa/src/gplx/php/Php_text_itm.java
Normal file
62
400_xowa/src/gplx/php/Php_text_itm.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
interface Php_text_itm {
|
||||
byte Tid();
|
||||
int Src_bgn();
|
||||
int Src_end();
|
||||
void Bld(Bry_bfr bfr, byte[] src);
|
||||
}
|
||||
class Php_text_itm_ {
|
||||
public static final byte Tid_text = 0, Tid_escaped = 1, Tid_arg = 2, Tid_utf16 = 3;
|
||||
}
|
||||
class Php_text_itm_text implements Php_text_itm {
|
||||
public Php_text_itm_text(int src_bgn, int src_end) {this.src_bgn = src_bgn; this.src_end = src_end;}
|
||||
public byte Tid() {return Php_text_itm_.Tid_text;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public void Bld(Bry_bfr bfr, byte[] src) {bfr.Add_mid(src, src_bgn, src_end);}
|
||||
}
|
||||
class Php_text_itm_escaped implements Php_text_itm {
|
||||
public Php_text_itm_escaped(int src_bgn, int src_end, byte literal) {this.src_bgn = src_bgn; this.src_end = src_end; this.literal = literal;}
|
||||
public byte Tid() {return Php_text_itm_.Tid_escaped;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public byte Literal() {return literal;} private byte literal;
|
||||
public void Bld(Bry_bfr bfr, byte[] src) {bfr.Add_byte(literal);}
|
||||
}
|
||||
class Php_text_itm_utf16 implements Php_text_itm {
|
||||
public Php_text_itm_utf16(int src_bgn, int src_end, byte[] literal) {this.src_bgn = src_bgn; this.src_end = src_end; this.literal = literal;}
|
||||
public byte Tid() {return Php_text_itm_.Tid_utf16;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public byte[] Literal() {return literal;} private byte[] literal;
|
||||
public void Bld(Bry_bfr bfr, byte[] src) {bfr.Add(literal);}
|
||||
}
|
||||
class Php_text_itm_arg implements Php_text_itm {
|
||||
public Php_text_itm_arg(int src_bgn, int src_end, int idx) {this.src_bgn = src_bgn; this.src_end = src_end; this.idx = idx;}
|
||||
public byte Tid() {return Php_text_itm_.Tid_escaped;}
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public int Idx() {return idx;} private int idx;
|
||||
public void Bld(Bry_bfr bfr, byte[] src) {
|
||||
bfr.Add_byte(Byte_ascii.Tilde).Add_byte(Byte_ascii.Curly_bgn)
|
||||
.Add_int_variable(idx - ListAdp_.Base1) // php is super 1
|
||||
.Add_byte(Byte_ascii.Curly_end);
|
||||
}
|
||||
}
|
||||
126
400_xowa/src/gplx/php/Php_text_itm_parser.java
Normal file
126
400_xowa/src/gplx/php/Php_text_itm_parser.java
Normal file
@@ -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.php; import gplx.*;
|
||||
public class Php_text_itm_parser {
|
||||
public static final byte Rslt_orig = 0, Rslt_dirty = 1, Rslt_fmt = 2;
|
||||
public byte[] Parse_as_bry(ListAdp tmp_list, byte[] raw, Byte_obj_ref rslt_ref, Bry_bfr tmp_bfr) {
|
||||
Parse(tmp_list, raw, rslt_ref);
|
||||
byte[] rv = raw;
|
||||
switch (rslt_ref.Val()) {
|
||||
case Rslt_orig: break;
|
||||
case Rslt_dirty:
|
||||
case Rslt_fmt:
|
||||
tmp_bfr.Clear();
|
||||
int tmp_list_len = tmp_list.Count();
|
||||
for (int i = 0; i < tmp_list_len; i++) {
|
||||
Php_text_itm itm = (Php_text_itm)tmp_list.FetchAt(i);
|
||||
itm.Bld(tmp_bfr, raw);
|
||||
}
|
||||
rv = tmp_bfr.XtoAryAndClear();
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public void Parse(ListAdp tmp_list, byte[] raw) {
|
||||
Parse(tmp_list, raw, Byte_obj_ref.zero_());
|
||||
}
|
||||
public void Parse(ListAdp tmp_list, byte[] raw, Byte_obj_ref rslt) {
|
||||
tmp_list.Clear();
|
||||
int raw_len = raw.length; int raw_last = raw_len - 1;
|
||||
int txt_bgn = -1;
|
||||
byte rslt_val = Rslt_orig;
|
||||
for (int i = 0; i < raw_len; i++) {
|
||||
byte b = raw[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Backslash:
|
||||
if (txt_bgn != -1) {tmp_list.Add(new Php_text_itm_text(txt_bgn, i)); txt_bgn = -1; rslt_val = Rslt_dirty;}
|
||||
if (i == raw_last) throw Err_mgr._.fmt_auto_(GRP_KEY, "backslash_is_last_char", String_.new_utf8_(raw));
|
||||
int next_pos = i + 1;
|
||||
byte next_char = raw[next_pos];
|
||||
switch (next_char) {
|
||||
case Byte_ascii.Ltr_N:
|
||||
case Byte_ascii.Ltr_n: next_char = Byte_ascii.NewLine; break;
|
||||
case Byte_ascii.Ltr_T:
|
||||
case Byte_ascii.Ltr_t: next_char = Byte_ascii.Tab; break;
|
||||
case Byte_ascii.Ltr_R:
|
||||
case Byte_ascii.Ltr_r: next_char = Byte_ascii.CarriageReturn; break;
|
||||
case Byte_ascii.Ltr_U:
|
||||
case Byte_ascii.Ltr_u: { // EX: "\u007C"
|
||||
rslt_val = Rslt_dirty;
|
||||
Parse_utf16(tmp_list, raw, next_pos + 1, raw_len); // +1 to skip u
|
||||
i = next_pos + 4; // +4 to skip utf16 seq; EX: \u007C; +4 for 007C
|
||||
continue;
|
||||
}
|
||||
case Byte_ascii.Ltr_X:
|
||||
case Byte_ascii.Ltr_x: { // EX: "\xc2"
|
||||
rslt_val = Rslt_dirty;
|
||||
byte[] literal = Bry_.Add(CONST_utf_prefix, Bry_.Mid(raw, next_pos + 1, next_pos + 3));
|
||||
tmp_list.Add(new Php_text_itm_utf16(i, i + 4, literal));
|
||||
i = next_pos + 2; // +2 to skip rest; EX: \xc2; +2 for c2
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tmp_list.Add(new Php_text_itm_escaped(i, next_pos, next_char)); rslt_val = Rslt_dirty;
|
||||
i = next_pos;
|
||||
break;
|
||||
case Byte_ascii.Dollar:
|
||||
if (txt_bgn != -1) {tmp_list.Add(new Php_text_itm_text(txt_bgn, i)); txt_bgn = -1;}
|
||||
if (i == raw_last) {
|
||||
//throw Err_mgr._.fmt_auto_(GRP_KEY, "dollar_is_last_char", String_.new_utf8_(raw));
|
||||
}
|
||||
int int_end = Find_fwd_non_int(raw, i + 1, raw_len); // +1 to search after $
|
||||
int int_val = Bry_.X_to_int_or(raw, i + 1, int_end, -1); // +1 to search after $
|
||||
if (int_val == -1) {
|
||||
tmp_list.Add(new Php_text_itm_text(i, i + 1));
|
||||
continue;
|
||||
}
|
||||
//throw Err_mgr._.fmt_auto_(GRP_KEY, "invalid_arg", String_.new_utf8_(raw));
|
||||
tmp_list.Add(new Php_text_itm_arg(i, int_end, int_val));
|
||||
rslt_val = Rslt_fmt;
|
||||
i = int_end - 1; // -1 b/c i++ in for loop
|
||||
break;
|
||||
default:
|
||||
if (txt_bgn == -1) txt_bgn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (txt_bgn != -1) {tmp_list.Add(new Php_text_itm_text(txt_bgn, raw_len)); txt_bgn = -1; rslt_val = Rslt_dirty;}
|
||||
rslt.Val_(rslt_val);
|
||||
} private static final byte[] CONST_utf_prefix = Bry_.new_ascii_("\\u00");
|
||||
private void Parse_utf16(ListAdp rv, byte[] src, int bgn, int src_len) {
|
||||
int end = bgn + 4;
|
||||
if (end >= src_len) throw Err_mgr._.fmt_auto_(GRP_KEY, "utf16_parse", String_.new_utf8_(src));
|
||||
int v = Int_.Xto_int_hex(src, bgn, end); // +2; skip "\" + "u"
|
||||
byte[] literal = gplx.intl.Utf16_.Encode_int_to_bry(v);
|
||||
rv.Add(new Php_text_itm_utf16(bgn, end, literal));
|
||||
}
|
||||
private static final String GRP_KEY = "xowa.php.quote_text_parser";
|
||||
public static int Find_fwd_non_int(byte[] src, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
break;
|
||||
default:
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return end;
|
||||
}
|
||||
}
|
||||
39
400_xowa/src/gplx/php/Php_text_itm_tst.java
Normal file
39
400_xowa/src/gplx/php/Php_text_itm_tst.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Php_text_itm_tst {
|
||||
@Test public void Basic() {Tst_("abcde", "abcde");}
|
||||
@Test public void Escaped() {Tst_("a\\$b\\\"c\\td\\ne", "a$b\"c\td\ne");}
|
||||
@Test public void Fmt() {Tst_("a$1b$2c", "a~{0}b~{1}c");}
|
||||
@Test public void Utf16() {Tst_("a\\u007Cd", "a|d");}
|
||||
@Test public void Utf8_nbsp() {Tst_("a\\xc2\\xa0d", "a\\u00c2\\u00a0d");}
|
||||
private void Tst_(String raw_str, String expd) {
|
||||
Php_text_itm_parser parser = new Php_text_itm_parser();
|
||||
ListAdp list = ListAdp_.new_();
|
||||
byte[] raw = Bry_.new_utf8_(raw_str);
|
||||
parser.Parse(list, raw);
|
||||
Bry_bfr bfr = Bry_bfr.reset_(255);
|
||||
int list_len = list.Count();
|
||||
for (int i = 0; i < list_len; i++) {
|
||||
Php_text_itm itm = (Php_text_itm)list.FetchAt(i);
|
||||
itm.Bld(bfr, raw);
|
||||
}
|
||||
Tfds.Eq(expd, bfr.XtoStrAndClear());
|
||||
}
|
||||
}
|
||||
74
400_xowa/src/gplx/php/Php_tkn.java
Normal file
74
400_xowa/src/gplx/php/Php_tkn.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public interface Php_tkn {
|
||||
byte Tkn_tid();
|
||||
int Src_bgn();
|
||||
int Src_end();
|
||||
}
|
||||
class Php_tkn_ {
|
||||
public static final byte Tid_txt = 1, Tid_declaration = 2, Tid_ws = 3, Tid_comment = 4, Tid_var = 5, Tid_eq = 6, Tid_eq_kv = 7, Tid_semic = 8, Tid_comma = 9, Tid_paren_bgn = 10, Tid_paren_end = 11, Tid_null = 12, Tid_false = 13, Tid_true = 14, Tid_ary = 15, Tid_num = 16, Tid_quote = 17, Tid_brack_bgn = 18, Tid_brack_end = 19;
|
||||
public static String Xto_str(byte tid) {return Byte_.XtoStr(tid);}
|
||||
}
|
||||
abstract class Php_tkn_base implements Php_tkn {
|
||||
public abstract byte Tkn_tid();
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} public void Src_end_(int v) {this.src_end = v;} private int src_end;
|
||||
public void Src_rng_(int src_bgn, int src_end) {this.src_bgn = src_bgn; this.src_end = src_end;}
|
||||
}
|
||||
class Php_tkn_generic extends Php_tkn_base {
|
||||
public Php_tkn_generic(int src_bgn, int src_end, byte tid) {this.Src_rng_(src_bgn, src_end); this.tid = tid;}
|
||||
@Override public byte Tkn_tid() {return tid;} private byte tid;
|
||||
}
|
||||
class Php_tkn_txt extends Php_tkn_base {
|
||||
public Php_tkn_txt(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_txt;}
|
||||
}
|
||||
class Php_tkn_ws extends Php_tkn_base {
|
||||
public Php_tkn_ws(int src_bgn, int src_end, byte ws_tid) {this.Src_rng_(src_bgn, src_end); this.ws_tid = ws_tid;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_ws;}
|
||||
public byte Ws_tid() {return ws_tid;} private byte ws_tid;
|
||||
public static final byte Tid_space = 0, Tid_nl = 1, Tid_tab = 2, Tid_cr = 3;
|
||||
}
|
||||
class Php_tkn_comment extends Php_tkn_base {
|
||||
public Php_tkn_comment(int src_bgn, int src_end, byte comment_tid) {this.Src_rng_(src_bgn, src_end); this.comment_tid = comment_tid;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_comment;}
|
||||
public byte Comment_tid() {return comment_tid;} private byte comment_tid;
|
||||
public static final byte Tid_null = 0, Tid_mult = 1, Tid_slash = 2, Tid_hash = 3;
|
||||
}
|
||||
class Php_tkn_var extends Php_tkn_base {
|
||||
public Php_tkn_var(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_var;}
|
||||
public byte[] Var_name(byte[] src) {return Bry_.Mid(src, this.Src_bgn() + 1, this.Src_end());} // NOTE: assume vars are of form $abc; +1 to skip first $
|
||||
}
|
||||
class Php_tkn_num extends Php_tkn_base {
|
||||
public Php_tkn_num(int src_bgn, int src_end) {this.Src_rng_(src_bgn, src_end);}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_num;}
|
||||
public int Num_val_int(byte[] src) {return Bry_.X_to_int_or(src, this.Src_bgn(), this.Src_end(), Int_.MinValue);}
|
||||
}
|
||||
class Php_tkn_quote extends Php_tkn_base {
|
||||
public Php_tkn_quote(int src_bgn, int src_end, byte quote_tid) {this.Src_rng_(src_bgn, src_end); this.quote_tid = quote_tid;}
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_quote;}
|
||||
public byte Quote_tid() {return quote_tid;} private byte quote_tid;
|
||||
public byte[] Quote_text(byte[] src) {return Bry_.Mid(src, this.Src_bgn() + 1, this.Src_end() - 1);} // NOTE: assume quote are of form 'abc'; +1, -1 to skip flanking chars
|
||||
public static final byte Tid_null = 0, Tid_mult = 1, Tid_slash = 2, Tid_hash = 3;
|
||||
}
|
||||
class Php_tkn_declaration extends Php_tkn_base {
|
||||
@Override public byte Tkn_tid() {return Php_tkn_.Tid_declaration;}
|
||||
public static final Php_tkn_declaration _ = new Php_tkn_declaration();
|
||||
}
|
||||
28
400_xowa/src/gplx/php/Php_tkn_factory.java
Normal file
28
400_xowa/src/gplx/php/Php_tkn_factory.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
class Php_tkn_factory {
|
||||
public Php_tkn_generic Generic(int bgn, int end, byte tid) {return new Php_tkn_generic(bgn, end, tid);}
|
||||
public Php_tkn_txt Txt(int bgn, int end) {return new Php_tkn_txt(bgn, end);}
|
||||
public Php_tkn Declaration(int bgn, int end) {return Php_tkn_declaration._;}
|
||||
public Php_tkn_ws Ws(int bgn, int end, byte ws_tid) {return new Php_tkn_ws(bgn, end, ws_tid);}
|
||||
public Php_tkn_var Var(int bgn, int end) {return new Php_tkn_var(bgn, end);}
|
||||
public Php_tkn_num Num(int bgn, int end) {return new Php_tkn_num(bgn, end);}
|
||||
public Php_tkn_comment Comment(int bgn, int end, byte comment_tid) {return new Php_tkn_comment(bgn, end, comment_tid);}
|
||||
public Php_tkn_quote Quote(int bgn, int end, byte quote_tid) {return new Php_tkn_quote(bgn, end, quote_tid);}
|
||||
}
|
||||
35
400_xowa/src/gplx/php/Php_tkn_wkr.java
Normal file
35
400_xowa/src/gplx/php/Php_tkn_wkr.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.php; import gplx.*;
|
||||
public interface Php_tkn_wkr {
|
||||
void Init(Php_ctx ctx);
|
||||
void Process(Php_tkn tkn);
|
||||
void Msg_many(byte[] src, int bgn, int end, Gfo_msg_itm itm, Object... args);
|
||||
}
|
||||
class Php_tkn_wkr_tkn implements Php_tkn_wkr {
|
||||
public void Init(Php_ctx ctx) {}
|
||||
public ListAdp List() {return lines;} ListAdp lines = ListAdp_.new_();
|
||||
public Gfo_msg_log Msg_log() {return msg_log;} Gfo_msg_log msg_log = new Gfo_msg_log("gplx.php");
|
||||
public void Clear() {lines.Clear(); msg_log.Clear();}
|
||||
public void Process(Php_tkn tkn) {
|
||||
lines.Add(tkn);
|
||||
}
|
||||
public void Msg_many(byte[] src, int bgn, int end, Gfo_msg_itm itm, Object... args) {
|
||||
msg_log.Add_itm_many(itm, src, bgn, end, args);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user