mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.10.3.1
This commit is contained in:
@@ -22,5 +22,5 @@ public class Bry_comparer implements ComparerAble {
|
||||
byte[] lhs = (byte[])lhsObj, rhs = (byte[])rhsObj;
|
||||
return Bry_.Compare(lhs, 0, lhs.length, rhs, 0, rhs.length);
|
||||
}
|
||||
public static final Bry_comparer _ = new Bry_comparer(); Bry_comparer() {}
|
||||
public static final Bry_comparer Instance = new Bry_comparer(); Bry_comparer() {}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.core.caches; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.consoles.*;
|
||||
public class Gfo_cache_mgr {
|
||||
private Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
private Ordered_hash recent = Ordered_hash_.new_bry_();
|
||||
private Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
private Ordered_hash recent = Ordered_hash_.New_bry();
|
||||
public int Max_size() {return max_size;} public Gfo_cache_mgr Max_size_(int v) {max_size = v; return this;} private int max_size;
|
||||
public int Reduce_by() {return reduce_by;} public Gfo_cache_mgr Reduce_by_(int v) {reduce_by = v; return this;} private int reduce_by;
|
||||
public int Cur_size() {return cur_size;} private int cur_size;
|
||||
@@ -65,7 +65,7 @@ public class Gfo_cache_mgr {
|
||||
hash.Add(key, itm);
|
||||
}
|
||||
public void Reduce_recent() {
|
||||
// Console_adp__sys.I.WriteLine("reducing");
|
||||
// Console_adp__sys.Instance.WriteLine("reducing");
|
||||
int len = recent.Count();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_cache_data itm = (Gfo_cache_data)recent.Get_at(i);
|
||||
@@ -74,7 +74,7 @@ public class Gfo_cache_mgr {
|
||||
recent.Clear();
|
||||
}
|
||||
public void Reduce_cache() {
|
||||
Console_adp__sys.I.Write_str_w_nl("compacting:");
|
||||
Console_adp__sys.Instance.Write_str_w_nl("compacting:");
|
||||
// hash.Sort();
|
||||
// int len = hash.Count();
|
||||
// List_adp deleted = List_adp_.new_();
|
||||
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.caches; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cache_mgr_base {
|
||||
private Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
private Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
public int Compress_max() {return compress_max;} public void Compress_max_(int v) {compress_max = v;} private int compress_max = 16;
|
||||
public int Compress_to() {return compress_to;} public void Compress_to_(int v) {compress_to = v;} private int compress_to = 8;
|
||||
protected Object Base_get_or_null(byte[] key) {
|
||||
|
||||
@@ -46,7 +46,7 @@ class Io_url_exists_mgr {
|
||||
byte[] url_key = url.RawBry();
|
||||
Object rv_obj = cache_mgr.Get_or_null(url_key);
|
||||
if (rv_obj != null) return ((Bool_obj_ref)rv_obj).Val(); // cached val exists; use it
|
||||
boolean exists = Io_mgr.I.ExistsFil(url);
|
||||
boolean exists = Io_mgr.Instance.ExistsFil(url);
|
||||
cache_mgr.Add(url_key, Bool_obj_ref.new_(exists));
|
||||
return exists;
|
||||
}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
public class App_cmd_arg {
|
||||
App_cmd_arg(byte tid, byte val_tid, String key, boolean reqd) {this.tid = tid; this.val_tid = val_tid; this.key = key; this.reqd = reqd;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte Val_tid() {return val_tid;} public App_cmd_arg Val_tid_(byte v) {val_tid = v; return this;} private byte val_tid;
|
||||
public String Val_tid_str() {
|
||||
switch (val_tid) {
|
||||
case Val_tid_string: return "string";
|
||||
case Val_tid_yn: return "yes_no";
|
||||
case Val_tid_url: return "path";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
public String Key() {return key;} private String key;
|
||||
public boolean Reqd() {return reqd;} private boolean reqd;
|
||||
public String Reqd_str() {return reqd ? "required" : "optional";}
|
||||
public boolean Dirty() {return dirty;} public App_cmd_arg Dirty_(boolean v) {this.dirty = v; return this;} private boolean dirty;
|
||||
public String Note() {return note;} public App_cmd_arg Note_(String v) {note = v; return this;} private String note;
|
||||
public String Example() {return example;}
|
||||
public App_cmd_arg Example_(String v) {example = v; return this;} private String example;
|
||||
public App_cmd_arg Example_url_(String v) {
|
||||
Example_(v);
|
||||
val_tid = Val_tid_url;
|
||||
return this;
|
||||
}
|
||||
public App_cmd_arg Example_list_str_(String v) {
|
||||
example = String_.Concat_with_obj(" ", v);
|
||||
val_tid = Val_tid_list_string;
|
||||
return this;
|
||||
}
|
||||
public Object Val() {return val;} public App_cmd_arg Val_(Object v) {this.val = v; return this;} Object val;
|
||||
public Object Dflt() {return dflt;} public App_cmd_arg Dflt_(Object v) {dflt = v; return this;} Object dflt;
|
||||
public boolean Val_as_bool() {return Bool_.cast(val);}
|
||||
public String Val_as_str_or(String or) {return val == null ? or : (String)val;}
|
||||
public String Val_as_str() {return (String)val;}
|
||||
public int Val_as_int_or(int or) {return val == null ? or : Int_.parse_or((String)val, or);}
|
||||
public Io_url Val_as_url_rel_dir_or(Io_url owner_dir, Io_url or) {return Val_as_url_rel_url_or(owner_dir, or, true);}
|
||||
public Io_url Val_as_url_rel_fil_or(Io_url owner_dir, Io_url or) {return Val_as_url_rel_url_or(owner_dir, or, false);}
|
||||
public Io_url Val_as_url_rel_url_or(Io_url owner_dir, Io_url or, boolean dir) {return Val_as_url_rel_url_or(Val_as_str(), owner_dir, or, dir);}
|
||||
public boolean Parse(App_cmd_mgr mgr, String[] s_ary) {
|
||||
dirty = true;
|
||||
String s = s_ary.length == 0 ? "" : s_ary[0];
|
||||
switch (val_tid) {
|
||||
case Val_tid_string:
|
||||
val = s;
|
||||
break;
|
||||
case Val_tid_url: // NOTE: do not parse urls as it can either be absolute (C:\dir\fil.txt) or relative (fil.txt). relative cannot be parsed without knowing owner dir
|
||||
val = s;
|
||||
break;
|
||||
case Val_tid_yn:
|
||||
int v_int = Yn.parse_as_int(s);
|
||||
if (v_int == Bool_.__int) {return mgr.Errs_add(Err_parse_yn, "value must be either y or n: ~{0}", s);}
|
||||
val = v_int == Bool_.Y_int;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} public static final String Err_parse_yn = "parse_yn";
|
||||
public App_cmd_arg Clone() {
|
||||
App_cmd_arg rv = new App_cmd_arg(tid, val_tid, key, reqd);
|
||||
rv.val = val;
|
||||
rv.dflt = dflt;
|
||||
rv.note = note;
|
||||
rv.example = example;
|
||||
return rv;
|
||||
}
|
||||
public static App_cmd_arg req_(String key) {return new App_cmd_arg(Tid_general, Val_tid_string, key, true);}
|
||||
public static App_cmd_arg opt_(String key) {return new App_cmd_arg(Tid_general, Val_tid_string, key, false);}
|
||||
public static App_cmd_arg new_(String key, boolean reqd) {return new App_cmd_arg(Tid_general, Val_tid_string, key, reqd);}
|
||||
public static App_cmd_arg sys_help_() {return sys_help_("help");}
|
||||
public static App_cmd_arg sys_help_(String key) {return new App_cmd_arg(Tid_help, Val_tid_string, key, false);}
|
||||
public static App_cmd_arg sys_header_(String key) {return new App_cmd_arg(Tid_header, Val_tid_yn, key, false);}
|
||||
public static App_cmd_arg sys_args_(String key) {return new App_cmd_arg(Tid_args, Val_tid_yn, key, false);}
|
||||
public static final byte Tid_general = 0, Tid_help = 1, Tid_header = 2, Tid_args = 3;
|
||||
public static final byte Val_tid_string = 0, Val_tid_yn = 1, Val_tid_url = 2, Val_tid_list_string = 3;
|
||||
|
||||
public static Io_url Val_as_url_rel_url_or(String val_str, Io_url owner_dir, Io_url or, boolean dir) {
|
||||
if (val_str == null) return or;
|
||||
byte val_has_dir = Op_sys.Tid_nil; // if val_str is dir, use it literally (only checking for closing dir_spr); if it's just a name, assume a simple relative path
|
||||
if (String_.Has(val_str, Op_sys.Lnx.Fsys_dir_spr_str()))
|
||||
val_has_dir = Op_sys.Tid_lnx;
|
||||
else if (String_.Has(val_str, Op_sys.Wnt.Fsys_dir_spr_str()))
|
||||
val_has_dir = Op_sys.Tid_wnt;
|
||||
if (val_has_dir != Op_sys.Tid_nil) {
|
||||
if (dir) { // NOTE: need to do extra logic to guarantee trailing "/"; JAVA:7 apparently strips "/dir/" to "/dir" when passed in as argument; DATE:2013-03-20
|
||||
String val_dir_spr = val_has_dir == Op_sys.Tid_lnx ? Op_sys.Lnx.Fsys_dir_spr_str() : Op_sys.Wnt.Fsys_dir_spr_str();
|
||||
if (!String_.Has_at_end(val_str, val_dir_spr))
|
||||
val_str += val_dir_spr;
|
||||
return Io_url_.new_dir_(val_str);
|
||||
}
|
||||
else
|
||||
return Io_url_.new_fil_(val_str);
|
||||
}
|
||||
else
|
||||
return dir ? owner_dir.GenSubDir(val_str) : owner_dir.GenSubFil(val_str);
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.strings.*;
|
||||
public class App_cmd_mgr {
|
||||
private Ordered_hash expd_args = Ordered_hash_.new_(), actl_args = Ordered_hash_.new_();
|
||||
private List_adp tmp_vals = List_adp_.new_(); private String[] orig_ary;
|
||||
public App_cmd_mgr Msg_root_(Gfo_msg_root v) {msg_root = v; return this;} private Gfo_msg_root msg_root = Gfo_msg_root._;
|
||||
public String Arg_prefix() {return arg_prefix;} public App_cmd_mgr Arg_prefix_(String v) {arg_prefix = v; prefix_len = String_.Len(v); return this;} private String arg_prefix = "--"; int prefix_len = 2;
|
||||
public void Clear() {expd_args.Clear(); actl_args.Clear(); errs.Clear(); key_help = key_header = null;}
|
||||
public int Actl_len() {return actl_args.Count();}
|
||||
public App_cmd_arg[] Actl_ary() {return (App_cmd_arg[])actl_args.To_ary(App_cmd_arg.class);}
|
||||
public App_cmd_mgr Expd_add_many(App_cmd_arg... ary) {for (App_cmd_arg o : ary) Expd_add(o); return this;}
|
||||
public App_cmd_mgr Expd_add(App_cmd_arg prm) {
|
||||
expd_args.Add(prm.Key(), prm);
|
||||
switch (prm.Tid()) {
|
||||
case App_cmd_arg.Tid_help: key_help = prm.Key(); break;
|
||||
case App_cmd_arg.Tid_header: key_header = prm.Key(); break;
|
||||
case App_cmd_arg.Tid_args: key_args = prm.Key(); break;
|
||||
}
|
||||
return this;
|
||||
} String key_help, key_header, key_args;
|
||||
public boolean Args_process(String[] ary) {Args_parse(ary); return errs.Count() == 0;}
|
||||
private void Args_parse(String[] ary) {
|
||||
this.orig_ary = ary;
|
||||
App_cmd_arg arg = null;
|
||||
int ary_len = ary.length;
|
||||
actl_args = Expd_copy();
|
||||
errs.Clear(); tmp_vals.Clear();
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
String itm = ary[i];
|
||||
if (String_.Has_at_bgn(itm, arg_prefix)) { // key
|
||||
if (arg != null) {
|
||||
String[] tmp_ary = tmp_vals.To_str_ary();
|
||||
if (!arg.Parse(this, tmp_ary)) {continue;}
|
||||
tmp_vals.Clear();
|
||||
}
|
||||
String key = String_.Mid(itm, prefix_len);
|
||||
Object o = actl_args.Get_by(key);
|
||||
if (o == null) {Errs_add(Err_argument_is_unknown, "unknown argument: '~{0}'", key); continue;}
|
||||
arg = (App_cmd_arg)o;
|
||||
if (arg.Dirty()) {Errs_add(Err_argument_is_duplicate, "duplicate argument: '~{0}'", key); continue;}
|
||||
arg.Dirty_(true);
|
||||
}
|
||||
else {
|
||||
if (arg == null) {Errs_add(Err_argument_is_invalid_key, "argument key must be prefixed with '~{0}'; EX: '~{0}~{1}'", arg_prefix, itm); continue;} // should only happen if 1st itm is not "--%"
|
||||
// if (arg.Val() != null) return Errs_add("argument_is_already_valued", "argument can only take one value: '{0}'", itm);
|
||||
tmp_vals.Add(itm);
|
||||
}
|
||||
}
|
||||
if (arg != null) {
|
||||
String[] tmp_ary = tmp_vals.To_str_ary();
|
||||
arg.Parse(this, tmp_ary);
|
||||
tmp_vals.Clear();
|
||||
}
|
||||
int len = actl_args.Count();
|
||||
for (int i = 0; i < len; i++) {
|
||||
arg = (App_cmd_arg)actl_args.Get_at(i);
|
||||
if (arg.Reqd() && !arg.Dirty()) {Errs_add(Err_argument_is_required, "argument is required: '~{0}'", arg.Key()); continue;}
|
||||
if (!arg.Dirty() && arg.Dflt() != null) arg.Val_(arg.Dflt());
|
||||
}
|
||||
} public static final String Err_argument_is_duplicate = "argument_is_duplicate", Err_argument_is_required = "argument_is_required", Err_argument_is_unknown = "argument_is_unknown", Err_argument_is_invalid_key = "argument_is_invalid_key";
|
||||
public String Fmt_hdr() {return fmt_hdr;} public App_cmd_mgr Fmt_hdr_(String v) {fmt_hdr = v; return this;} private String fmt_hdr = "";
|
||||
public App_cmd_arg Args_get(String key) {return (App_cmd_arg)actl_args.Get_by(key);}
|
||||
public boolean Args_has_help() {
|
||||
App_cmd_arg arg = (App_cmd_arg)actl_args.Get_by(key_help);
|
||||
return arg != null && arg.Dirty();
|
||||
}
|
||||
public App_cmd_mgr Print_header(Gfo_usr_dlg usr_dlg) {
|
||||
App_cmd_arg arg_hdr = (App_cmd_arg)actl_args.Get_by(key_header);
|
||||
if (arg_hdr == null) return this; // no key_header specified; assume header shouldn't be printed
|
||||
if (!arg_hdr.Val_as_bool()) return this; // key_header specified as false; return;
|
||||
usr_dlg.Note_gui_none(GRP_KEY, "print.header", fmt_hdr);
|
||||
return this;
|
||||
}
|
||||
public void Print_args(Gfo_usr_dlg usr_dlg) {
|
||||
sb.Add_char_crlf();
|
||||
sb.Add_str_w_crlf("arguments:");
|
||||
int len = orig_ary.length;
|
||||
if (len == 0) {
|
||||
sb.Add_fmt_line(" **** NONE ****");
|
||||
sb.Add_fmt_line(" use --help to show help");
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < len; i++)
|
||||
sb.Add_fmt_line(" [{0}] = '{1}'", i, orig_ary[i]);
|
||||
}
|
||||
usr_dlg.Note_none(GRP_KEY, "print.args", sb.Xto_str_and_clear());
|
||||
} String_bldr sb = String_bldr_.new_();
|
||||
public void Print_fail(Gfo_usr_dlg usr_dlg) {
|
||||
sb.Add("** error: ").Add_char_crlf();
|
||||
int len = errs.Count();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_msg_data data = (Gfo_msg_data)errs.Get_at(i);
|
||||
sb.Add_fmt_line(" " + data.Gen_str_ary());
|
||||
}
|
||||
sb.Add_char_crlf();
|
||||
sb.Add_str_w_crlf(String_.Repeat("-", 80));
|
||||
usr_dlg.Note_none(GRP_KEY, "print.fail", sb.Xto_str_and_clear());
|
||||
}
|
||||
public void Print_help(Gfo_usr_dlg usr_dlg, String app_name) {
|
||||
sb.Add_str_w_crlf("example:");
|
||||
sb.Add_fmt(" java -jar {0}.jar", app_name);
|
||||
int key_max = 0, tid_max = 0;
|
||||
int len = expd_args.Count();
|
||||
for (int i = 0; i < len; i++) {
|
||||
App_cmd_arg arg = (App_cmd_arg)expd_args.Get_at(i);
|
||||
if (arg.Tid() != App_cmd_arg.Tid_general) continue; // skip header, help
|
||||
sb.Add(" ").Add(arg_prefix).Add(arg.Key()).Add(" ").Add(arg.Example());
|
||||
int key_len = String_.Len(arg.Key()); if (key_len > key_max) key_max = key_len;
|
||||
int tid_len = String_.Len(String_.Format("[{0}:{1}]", arg.Reqd_str(), arg.Val_tid_str())); if (tid_len > tid_max) tid_max = tid_len;
|
||||
} sb.Add_char_crlf();
|
||||
sb.Add_char_crlf();
|
||||
sb.Add_str_w_crlf("detail:");
|
||||
for (int i = 0; i < len; i++) {
|
||||
App_cmd_arg arg = (App_cmd_arg)expd_args.Get_at(i);
|
||||
// if (arg.Tid() != App_cmd_arg.Tid_general) continue; // skip header, help
|
||||
sb.Add(" ").Add(arg_prefix).Add(String_.PadEnd(arg.Key(), key_max + 1, " ")).Add(String_.PadEnd(String_.Format("[{0}:{1}]", arg.Reqd_str(), arg.Val_tid_str()), tid_max, " "));
|
||||
if (arg.Dflt() != null)
|
||||
sb.Add_fmt(" default={0}", arg.Dflt());
|
||||
sb.Add_char_crlf();
|
||||
if (arg.Note() != null)
|
||||
sb.Add(" ").Add(arg.Note()).Add_char_crlf();
|
||||
// for (int j = 0; j < arg.Itms().Count(); j++) {
|
||||
// App_arg_info expdInf = (App_arg_info)arg.Itms().Get_at(j);
|
||||
// sb.Add(" ").Add(String_.PadEnd(expdInf.Key(), key_max + 1, " ")).Add_str_w_crlf(expdInf.Descrip());
|
||||
// }
|
||||
}
|
||||
usr_dlg.Note_gui_none(GRP_KEY, "print.info", sb.Xto_str_and_clear());
|
||||
}
|
||||
private Ordered_hash Expd_copy() {
|
||||
Ordered_hash rv = Ordered_hash_.new_();
|
||||
int expd_len = expd_args.Count();
|
||||
for (int i = 0 ; i < expd_len; i++) {
|
||||
App_cmd_arg arg = (App_cmd_arg)expd_args.Get_at(i);
|
||||
rv.Add(arg.Key(), arg.Clone());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public boolean Errs_add(String key, String fmt, Object... vals) {
|
||||
errs.Add(msg_root.Data_new_many(Gfo_msg_itm_.Cmd_warn, GRP_KEY, key, fmt, vals));
|
||||
return false;
|
||||
}
|
||||
public int Errs_len() {return errs.Count();} private List_adp errs = List_adp_.new_();
|
||||
public Gfo_msg_data Errs_get(int i) {return (Gfo_msg_data)errs.Get_at(i);}
|
||||
private static final String GRP_KEY = "gplx.app.app_cmd_mgr";
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
public class App_cmd_mgr_tst {
|
||||
App_cmd_mgr_fxt fxt = new App_cmd_mgr_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Basic() {
|
||||
fxt .Expd_(fxt.arg_("a"), fxt.arg_("b"))
|
||||
.Args_process("--a", "0", "--b", "1")
|
||||
.Tst_errs_none()
|
||||
.Tst_actl(fxt.chkr_("a", "0"), fxt.chkr_("b", "1"));
|
||||
;
|
||||
}
|
||||
@Test public void Dflt() {
|
||||
fxt .Expd_(fxt.arg_("a").Val_tid_(App_cmd_arg.Val_tid_yn).Dflt_(true));
|
||||
fxt .Args_process("--a", "n").Tst_actl(fxt.chkr_("a", false)); // if val, use it
|
||||
fxt .Args_process().Tst_actl(fxt.chkr_("a", true)); // if no val, use default
|
||||
}
|
||||
@Test public void Header_y() {
|
||||
fxt.Expd_(App_cmd_arg.sys_header_("print_license")).Args_process("--print_license", "y");
|
||||
fxt.Mgr().Fmt_hdr_("test_hdr").Print_header(fxt.Usr_dlg());
|
||||
fxt.tst_write("test_hdr");
|
||||
fxt.Clear();
|
||||
}
|
||||
@Test public void Header_n() {
|
||||
fxt.Expd_(App_cmd_arg.sys_header_("print_license")).Args_process("--print_license", "n");
|
||||
fxt.Mgr().Fmt_hdr_("test_hdr").Print_header(fxt.Usr_dlg());
|
||||
fxt.tst_write();
|
||||
}
|
||||
// @Test public void Help_y() {
|
||||
// fxt.Expd_(App_cmd_arg.sys_header_("help")).Args_process("--help");
|
||||
//// fxt.Mgr().Fmt_help_grp("bgn ~{args} end").Fmt_help_itm_("~{0} ~{1}").Print_header(fxt.Status_mgr());
|
||||
//// fxt.Tst_write("test_hdr");
|
||||
// fxt.Clear();
|
||||
// }
|
||||
@Test public void Err_parse_yn() {
|
||||
fxt .Expd_(fxt.arg_("a").Val_tid_(App_cmd_arg.Val_tid_yn))
|
||||
.Args_process("--a", "x")
|
||||
.Tst_errs(App_cmd_arg.Err_parse_yn);
|
||||
;
|
||||
}
|
||||
@Test public void Err_reqd() {
|
||||
fxt .Expd_(fxt.arg_("a", true), fxt.arg_("b", false))
|
||||
.Args_process("--b", "1")
|
||||
.Tst_errs(App_cmd_mgr.Err_argument_is_required);
|
||||
;
|
||||
}
|
||||
@Test public void Err_dupe() {
|
||||
fxt .Expd_(fxt.arg_("a"))
|
||||
.Args_process("--a", "0", "--a", "0")
|
||||
.Tst_errs(App_cmd_mgr.Err_argument_is_duplicate);
|
||||
;
|
||||
}
|
||||
@Test public void Err_unknown() {
|
||||
fxt .Expd_(fxt.arg_("a"))
|
||||
.Args_process("--b")
|
||||
.Tst_errs(App_cmd_mgr.Err_argument_is_unknown);
|
||||
;
|
||||
}
|
||||
@Test public void Err_key_invalid() {
|
||||
fxt .Expd_(fxt.arg_("a"))
|
||||
.Args_process("a")
|
||||
.Tst_errs(App_cmd_mgr.Err_argument_is_invalid_key);
|
||||
;
|
||||
}
|
||||
@Test public void Val_as_url_rel_dir_or() { // PURPOSE: "/xowa" -> "/xowa/"
|
||||
String root_dir = Op_sys.Cur().Tid_is_wnt() ? "C:\\" : "/", dir_spr = Op_sys.Cur().Fsys_dir_spr_str();
|
||||
Tst_val_as_url_rel_dir_or(root_dir, dir_spr, root_dir + "sub" , root_dir + "sub" + dir_spr); // /sub -> /sub/
|
||||
Tst_val_as_url_rel_dir_or(root_dir, dir_spr, root_dir + "sub" + dir_spr , root_dir + "sub" + dir_spr); // /sub/ -> /sub/
|
||||
Tst_val_as_url_rel_dir_or(root_dir, dir_spr, "sub" , root_dir + "dir" + dir_spr + "sub" + dir_spr); // sub -> /dir/sub/
|
||||
}
|
||||
private void Tst_val_as_url_rel_dir_or(String root_dir, String dir_spr, String val, String expd) {
|
||||
Io_url actl = fxt.arg_("key").Val_(val).Val_as_url_rel_dir_or(Io_url_.new_dir_(root_dir).GenSubDir("dir"), null);
|
||||
Tfds.Eq(expd, actl.Raw());
|
||||
}
|
||||
}
|
||||
class App_cmd_mgr_fxt {
|
||||
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} Gfo_usr_dlg usr_dlg;
|
||||
public App_cmd_mgr Mgr() {return mgr;} App_cmd_mgr mgr = new App_cmd_mgr(); Tst_mgr tst_mgr = new Tst_mgr();
|
||||
public App_cmd_mgr_fxt Clear() {
|
||||
if (usr_dlg == null) {
|
||||
usr_dlg = Gfo_usr_dlg_.Test();
|
||||
}
|
||||
mgr.Clear();
|
||||
usr_dlg.Gui_wkr().Clear();
|
||||
return this;
|
||||
}
|
||||
public App_cmd_arg arg_(String key) {return arg_(key, false);}
|
||||
public App_cmd_arg arg_(String key, boolean reqd) {return App_cmd_arg.new_(key, reqd);}
|
||||
public App_cmd_arg_chkr chkr_(String key, Object val) {return new App_cmd_arg_chkr(key, val);}
|
||||
public App_cmd_mgr_fxt Expd_(App_cmd_arg... v) {mgr.Expd_add_many(v); return this;}
|
||||
public App_cmd_mgr_fxt Args_process(String... v) {mgr.Args_process(v); return this;}
|
||||
public App_cmd_mgr_fxt Tst_actl_len(int v) {Tfds.Eq(v, mgr.Actl_len()); return this;}
|
||||
public App_cmd_mgr_fxt Tst_actl(App_cmd_arg_chkr... expd) {
|
||||
App_cmd_arg[] actl = mgr.Actl_ary();
|
||||
tst_mgr.Tst_ary("", expd, actl);
|
||||
return this;
|
||||
}
|
||||
public App_cmd_mgr_fxt Tst_errs_none() {return Tst_errs(String_.Ary_empty);}
|
||||
public App_cmd_mgr_fxt Tst_errs(String... expd) {
|
||||
int len = mgr.Errs_len();
|
||||
String[] actl = new String[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_msg_data data = mgr.Errs_get(i);
|
||||
actl[i] = data.Item().Key_str();
|
||||
}
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
return this;
|
||||
}
|
||||
public App_cmd_mgr_fxt tst_write(String... expd) {
|
||||
String[] actl = ((Gfo_usr_dlg__gui_test)usr_dlg.Gui_wkr()).Xto_str_ary();
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class App_cmd_arg_chkr implements Tst_chkr {
|
||||
public App_cmd_arg_chkr(String key, Object val) {this.key = key; this.val = val;} private String key; Object val;
|
||||
public Class<?> TypeOf() {return App_cmd_arg.class;}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
App_cmd_arg actl = (App_cmd_arg)actl_obj;
|
||||
int err = 0;
|
||||
err += mgr.Tst_val(false, path, "key", key, actl.Key());
|
||||
err += mgr.Tst_val(false, path, "val", val, actl.Val());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
55
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_itm.java
Normal file
55
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_itm.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_itm {
|
||||
public Gfo_cmd_arg_itm(int tid, boolean reqd, String key, int val_tid) {this.tid = tid; this.reqd = reqd; this.key = key; this.val_tid = val_tid;}
|
||||
public int Tid() {return tid;} private final int tid;
|
||||
public boolean Reqd() {return reqd;} private final boolean reqd;
|
||||
public String Key() {return key;} private final String key;
|
||||
public int Val_tid() {return val_tid;} private int val_tid;
|
||||
public Object Val() {return val;} public Gfo_cmd_arg_itm Val_(Object v) {this.val = v; dirty = true; return this;} private Object val;
|
||||
public String Note() {return note;} public Gfo_cmd_arg_itm Note_(String v) {note = v; return this;} private String note = "";
|
||||
public String Example() {return example;} public Gfo_cmd_arg_itm Example_(String v) {example = v; return this;} private String example = "";
|
||||
public Object Dflt() {return dflt;} public Gfo_cmd_arg_itm Dflt_(Object v) {dflt = v; return this;} private Object dflt;
|
||||
public boolean Dirty() {return dirty;} private boolean dirty;
|
||||
public void Clear() {
|
||||
dirty = false;
|
||||
val = null;
|
||||
}
|
||||
public Gfo_cmd_arg_itm Example_url_(String v) {
|
||||
Example_(v);
|
||||
this.val_tid = Gfo_cmd_arg_itm_.Val_tid_url;
|
||||
return this;
|
||||
}
|
||||
public String Reqd_str() {return reqd ? "required" : "optional";}
|
||||
public String Val_tid_str() {
|
||||
switch (val_tid) {
|
||||
case Gfo_cmd_arg_itm_.Val_tid_string: return "string";
|
||||
case Gfo_cmd_arg_itm_.Val_tid_yn: return "y/n";
|
||||
case Gfo_cmd_arg_itm_.Val_tid_url: return "path";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
public boolean Val_as_bool() {return Bool_.cast(val);}
|
||||
public String Val_as_str_or(String or) {return val == null ? or : (String)val;}
|
||||
public String Val_as_str() {return (String)val;}
|
||||
public int Val_as_int_or(int or) {return val == null ? or : Int_.parse_or((String)val, or);}
|
||||
public Io_url Val_as_url__rel_dir_or(Io_url owner_dir, Io_url or) {return Val_as_url__rel_url_or(Bool_.Y, owner_dir, or);}
|
||||
public Io_url Val_as_url__rel_fil_or(Io_url owner_dir, Io_url or) {return Val_as_url__rel_url_or(Bool_.N, owner_dir, or);}
|
||||
public Io_url Val_as_url__rel_url_or(boolean to_dir, Io_url owner_dir, Io_url or) {return Gfo_cmd_arg_itm_.Val_as_url__rel_url_or(Val_as_str(), to_dir, owner_dir, or);}
|
||||
}
|
||||
47
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_itm_.java
Normal file
47
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_itm_.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_itm_ {
|
||||
public static final int Tid_general = 0, Tid_system = 1;
|
||||
public static final int Val_tid_string = 0, Val_tid_yn = 1, Val_tid_url = 2, Val_tid_list_string = 3;
|
||||
public static Gfo_cmd_arg_itm req_(String key) {return new Gfo_cmd_arg_itm(Tid_general, Bool_.Y, key, Val_tid_string);}
|
||||
public static Gfo_cmd_arg_itm opt_(String key) {return new Gfo_cmd_arg_itm(Tid_general, Bool_.N, key, Val_tid_string);}
|
||||
public static Gfo_cmd_arg_itm new_(String key, boolean reqd, int val_tid) {return new Gfo_cmd_arg_itm(Tid_general, reqd , key, val_tid);}
|
||||
public static Gfo_cmd_arg_itm sys_(String key) {return new Gfo_cmd_arg_itm(Tid_system , Bool_.N, key, Val_tid_yn);}
|
||||
public static Gfo_cmd_arg_itm new_(int tid, String key, boolean reqd, int val_tid) {return new Gfo_cmd_arg_itm(tid , reqd , key, val_tid);}
|
||||
public static Io_url Val_as_url__rel_url_or(String raw, boolean to_dir, Io_url owner_dir, Io_url or) {
|
||||
if (raw == null) return or;
|
||||
byte val_has_dir = Op_sys.Tid_nil; // if raw is to_dir, use it literally (only checking for closing dir_spr); if it's just a name, assume a simple relative path
|
||||
if (String_.Has(raw, Op_sys.Lnx.Fsys_dir_spr_str()))
|
||||
val_has_dir = Op_sys.Tid_lnx;
|
||||
else if (String_.Has(raw, Op_sys.Wnt.Fsys_dir_spr_str()))
|
||||
val_has_dir = Op_sys.Tid_wnt;
|
||||
if (val_has_dir != Op_sys.Tid_nil) {
|
||||
if (to_dir) { // NOTE: need to do extra logic to guarantee trailing "/"; JAVA:7 apparently strips "/to_dir/" to "/to_dir" when passed in as argument; DATE:2013-03-20
|
||||
String val_dir_spr = val_has_dir == Op_sys.Tid_lnx ? Op_sys.Lnx.Fsys_dir_spr_str() : Op_sys.Wnt.Fsys_dir_spr_str();
|
||||
if (!String_.Has_at_end(raw, val_dir_spr))
|
||||
raw += val_dir_spr;
|
||||
return Io_url_.new_dir_(raw);
|
||||
}
|
||||
else
|
||||
return Io_url_.new_fil_(raw);
|
||||
}
|
||||
else
|
||||
return to_dir ? owner_dir.GenSubDir(raw) : owner_dir.GenSubFil(raw);
|
||||
}
|
||||
}
|
||||
91
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr.java
Normal file
91
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_mgr {
|
||||
private final Ordered_hash hash = Ordered_hash_.New();
|
||||
private final List_adp err_list = List_adp_.new_(), tmp_vals = List_adp_.new_();
|
||||
public String[] Orig_ary() {return orig_ary;} private String[] orig_ary;
|
||||
public void Reset() {
|
||||
hash.Clear();
|
||||
this.Clear();
|
||||
}
|
||||
public void Clear() {
|
||||
int len = hash.Count();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Gfo_cmd_arg_itm itm = (Gfo_cmd_arg_itm)hash.Get_at(i);
|
||||
itm.Clear();
|
||||
}
|
||||
err_list.Clear();
|
||||
}
|
||||
public Gfo_cmd_arg_mgr Reg_many(Gfo_cmd_arg_itm... ary) {for (Gfo_cmd_arg_itm itm : ary) Reg(itm); return this;}
|
||||
public int Len() {return hash.Count();}
|
||||
public boolean Has(String k) {
|
||||
Gfo_cmd_arg_itm arg = (Gfo_cmd_arg_itm)hash.Get_by(k);
|
||||
return arg != null && arg.Dirty();
|
||||
}
|
||||
public boolean Get_by_as_bool(String k) {
|
||||
Gfo_cmd_arg_itm arg = (Gfo_cmd_arg_itm)hash.Get_by(k);
|
||||
return arg != null && arg.Val() != null && arg.Val_as_bool();
|
||||
}
|
||||
public Gfo_cmd_arg_itm Get_at(int i) {return (Gfo_cmd_arg_itm)hash.Get_at(i);}
|
||||
public Gfo_cmd_arg_itm Get_by(String key) {return (Gfo_cmd_arg_itm)hash.Get_by(key);}
|
||||
public void Parse(String[] orig_ary) {
|
||||
this.Clear();
|
||||
this.orig_ary = orig_ary; int orig_len = orig_ary.length;
|
||||
Gfo_cmd_arg_itm cur_itm = null;
|
||||
int orig_idx = 0;
|
||||
while (true) {
|
||||
boolean done = orig_idx == orig_len;
|
||||
String itm = done ? "" : orig_ary[orig_idx++];
|
||||
boolean itm_is_key = String_.Has_at_bgn(itm, Key_prefix); // has "--" -> is key
|
||||
if ( cur_itm != null // pending itm
|
||||
&& (itm_is_key || done)) { // cur arg is key ("--key2"), or all done
|
||||
cur_itm.Val_(Gfo_cmd_arg_mgr_.Parse_ary_to_str(this, cur_itm.Val_tid(), tmp_vals.To_str_ary_and_clear()));
|
||||
cur_itm = null;
|
||||
}
|
||||
if (done) break;
|
||||
if (itm_is_key) {
|
||||
String key = String_.Mid(itm, prefix_len);
|
||||
Object o = hash.Get_by(key); if (o == null) {Errs__add(Gfo_cmd_arg_mgr_.Err__key__unknown , key); continue;}
|
||||
cur_itm = (Gfo_cmd_arg_itm)o; if (cur_itm.Dirty()) {Errs__add(Gfo_cmd_arg_mgr_.Err__key__duplicate , key); continue;}
|
||||
}
|
||||
else {
|
||||
if (cur_itm == null) {Errs__add(Gfo_cmd_arg_mgr_.Err__key__missing, itm); continue;} // should only happen if 1st itm is not "--%"
|
||||
tmp_vals.Add(itm);
|
||||
}
|
||||
}
|
||||
|
||||
// calc .Reqd and .Dflt
|
||||
int len = hash.Count();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
cur_itm = (Gfo_cmd_arg_itm)hash.Get_at(i);
|
||||
if (!cur_itm.Dirty()) { // arg not passed
|
||||
if (cur_itm.Reqd()) // arg required but no value passed; add error
|
||||
Errs__add(Gfo_cmd_arg_mgr_.Err__val__required, cur_itm.Key());
|
||||
else if (cur_itm.Dflt() != null) // arg has default
|
||||
cur_itm.Val_(cur_itm.Dflt());
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean Errs__exist() {return err_list.Count() > 0;}
|
||||
public void Errs__add(String key, String val) {err_list.Add(key + ": " + val);}
|
||||
public String[] Errs__to_str_ary() {return err_list.To_str_ary();}
|
||||
public Gfo_cmd_arg_itm[] To_ary() {return (Gfo_cmd_arg_itm[])hash.To_ary(Gfo_cmd_arg_itm.class);}
|
||||
private void Reg(Gfo_cmd_arg_itm defn) {hash.Add(defn.Key(), defn);}
|
||||
public static final String Key_prefix = "--"; private static final int prefix_len = 2;
|
||||
}
|
||||
42
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr_.java
Normal file
42
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr_.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
class Gfo_cmd_arg_mgr_ {
|
||||
public static final String
|
||||
Err__key__unknown = "unknown key"
|
||||
, Err__key__duplicate = "duplicate key"
|
||||
, Err__key__missing = "first argument must be prefixed with --"
|
||||
, Err__val__required = "value is required"
|
||||
, Err__val__invalid__yn = "value must be either y or n"
|
||||
;
|
||||
public static Object Parse_ary_to_str(Gfo_cmd_arg_mgr mgr, int val_tid, String[] ary) {
|
||||
String itm = ary.length == 0 ? "" : ary[0];
|
||||
switch (val_tid) {
|
||||
case Gfo_cmd_arg_itm_.Val_tid_string: return itm;
|
||||
case Gfo_cmd_arg_itm_.Val_tid_url: return itm; // NOTE: do not parse urls as it can either be absolute (C:\dir\fil.txt) or relative (fil.txt). relative cannot be parsed without knowing owner dir
|
||||
case Gfo_cmd_arg_itm_.Val_tid_yn:
|
||||
int itm_as_int = Yn.parse_as_int(itm);
|
||||
if (itm_as_int == Bool_.__int) {
|
||||
mgr.Errs__add(Gfo_cmd_arg_mgr_.Err__val__invalid__yn, itm);
|
||||
return null;
|
||||
}
|
||||
return itm_as_int == Bool_.Y_int;
|
||||
default: throw Err_.new_unhandled(val_tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr_printer.java
Normal file
95
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr_printer.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_cmd_arg_mgr_printer {
|
||||
private final Gfo_cmd_arg_mgr arg_mgr;
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr.new_();
|
||||
public Gfo_cmd_arg_mgr_printer(Gfo_cmd_arg_mgr arg_mgr) {this.arg_mgr = arg_mgr;}
|
||||
public boolean Print(Gfo_usr_dlg usr_dlg, String header, String app_name, String key__print_help, String key__print_header, String key__print_args) {
|
||||
if (arg_mgr.Get_by_as_bool(key__print_header))
|
||||
usr_dlg.Note_gui_none("", "", header);
|
||||
if (arg_mgr.Errs__exist()) {
|
||||
usr_dlg.Note_none("", "", Get_args());
|
||||
usr_dlg.Note_none("", "", Get_fail());
|
||||
usr_dlg.Note_none("", "", Get_help(app_name));
|
||||
return false;
|
||||
}
|
||||
if (arg_mgr.Has(key__print_help)) {
|
||||
usr_dlg.Note_none("", "", Get_help(app_name));
|
||||
return false;
|
||||
}
|
||||
if (arg_mgr.Get_by_as_bool(key__print_args))
|
||||
usr_dlg.Note_none("", "", Get_args());
|
||||
return true;
|
||||
}
|
||||
public String Get_args() {
|
||||
tmp_bfr.Add_byte_nl();
|
||||
tmp_bfr.Add_str_a7_w_nl("arguments:");
|
||||
String[] orig_ary = arg_mgr.Orig_ary();
|
||||
int len = orig_ary.length;
|
||||
if (len == 0) {
|
||||
tmp_bfr.Add_str_a7_w_nl(" **** NONE ****");
|
||||
tmp_bfr.Add_str_a7_w_nl(" use --help to show help");
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
String line = String_.Format(" [{0}] = '{1}'", i, orig_ary[i]);
|
||||
tmp_bfr.Add_str_u8_w_nl(line);
|
||||
}
|
||||
}
|
||||
return tmp_bfr.To_str_and_clear();
|
||||
}
|
||||
public String Get_fail() {
|
||||
tmp_bfr.Add_str_a7_w_nl("** error: ");
|
||||
String[] err_ary = arg_mgr.Errs__to_str_ary();
|
||||
int len = err_ary.length;
|
||||
for (int i = 0; i < len; ++i)
|
||||
tmp_bfr.Add_str_u8_w_nl(" " + err_ary[i]);
|
||||
tmp_bfr.Add_byte_nl();
|
||||
tmp_bfr.Add_str_a7_w_nl(String_.Repeat("-", 80));
|
||||
return tmp_bfr.To_str_and_clear();
|
||||
}
|
||||
public String Get_help(String app_name) {
|
||||
tmp_bfr.Add_str_a7_w_nl("example:");
|
||||
tmp_bfr.Add_str_a7(String_.Format(" java -jar {0}.jar", app_name));
|
||||
int key_max = 0, tid_max = 0;
|
||||
int len = arg_mgr.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_cmd_arg_itm arg = arg_mgr.Get_at(i); if (arg.Tid() != Gfo_cmd_arg_itm_.Tid_general) continue; // skip header, help
|
||||
tmp_bfr.Add_str_a7(" ").Add_str_a7(Gfo_cmd_arg_mgr.Key_prefix).Add_str_u8(arg.Key()).Add_str_a7(" ").Add_str_u8(arg.Example());
|
||||
int key_len = String_.Len(arg.Key()); if (key_len > key_max) key_max = key_len;
|
||||
int tid_len = String_.Len(String_.Format("[{0}:{1}]", arg.Reqd_str(), arg.Val_tid_str())); if (tid_len > tid_max) tid_max = tid_len;
|
||||
}
|
||||
tmp_bfr.Add_byte_nl().Add_byte_nl();
|
||||
tmp_bfr.Add_str_a7_w_nl("detail:");
|
||||
for (int i = 0; i < len; i++) {
|
||||
Gfo_cmd_arg_itm arg = (Gfo_cmd_arg_itm)arg_mgr.Get_at(i);
|
||||
tmp_bfr.Add_str_a7(" ").Add_str_a7(Gfo_cmd_arg_mgr.Key_prefix)
|
||||
.Add_str_u8(String_.PadEnd(arg.Key(), key_max + 1, " "))
|
||||
.Add_str_u8(String_.PadEnd(String_.Format("[{0}:{1}]", arg.Reqd_str(), arg.Val_tid_str()), tid_max, " "));
|
||||
if (arg.Dflt() != null) {
|
||||
String dflt_val = Object_.Xto_str_strict_or_null_mark(arg.Dflt());
|
||||
tmp_bfr.Add_str_u8(String_.Format(" default={0}", dflt_val));
|
||||
}
|
||||
tmp_bfr.Add_byte_nl();
|
||||
if (arg.Note() != null)
|
||||
tmp_bfr.Add_str_a7(" ").Add_str_u8(arg.Note()).Add_byte_nl();
|
||||
}
|
||||
return tmp_bfr.To_str_and_clear();
|
||||
}
|
||||
}
|
||||
123
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr_tst.java
Normal file
123
400_xowa/src/gplx/core/consoles/Gfo_cmd_arg_mgr_tst.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.consoles; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
public class Gfo_cmd_arg_mgr_tst {
|
||||
@Before public void init() {fxt.Clear();} private final Gfo_cmd_arg_mgr_fxt fxt = new Gfo_cmd_arg_mgr_fxt();
|
||||
@Test public void Val__many() {
|
||||
fxt.Init_args(fxt.Make_arg("a"), fxt.Make_arg("b"));
|
||||
fxt.Exec_process("--a", "0", "--b", "1");
|
||||
fxt.Test_errs_none();
|
||||
fxt.Test_actl(fxt.Make_chkr("a", "0"), fxt.Make_chkr("b", "1"));
|
||||
}
|
||||
@Test public void Val__yn() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Gfo_cmd_arg_itm_.Val_tid_yn), fxt.Make_arg("b", Gfo_cmd_arg_itm_.Val_tid_yn));
|
||||
fxt.Exec_process("--a", "y", "--b", "n");
|
||||
fxt.Test_errs_none();
|
||||
fxt.Test_actl(fxt.Make_chkr("a", Bool_.Y), fxt.Make_chkr("b", Bool_.N));
|
||||
}
|
||||
@Test public void Dflt() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Gfo_cmd_arg_itm_.Val_tid_yn).Dflt_(Bool_.Y));
|
||||
fxt.Exec_process("--a", "n").Test_actl(fxt.Make_chkr("a", Bool_.N)); // if val, use it
|
||||
fxt.Exec_process() .Test_actl(fxt.Make_chkr("a", Bool_.Y)); // if no val, use default
|
||||
}
|
||||
@Test public void Err__key__unknown() {
|
||||
fxt.Init_args(fxt.Make_arg("a"));
|
||||
fxt.Exec_process("--b");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__key__unknown);
|
||||
}
|
||||
@Test public void Err__key__missing() {
|
||||
fxt.Init_args(fxt.Make_arg("a"));
|
||||
fxt.Exec_process("a");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__key__missing);
|
||||
}
|
||||
@Test public void Err__key__dupe() {
|
||||
fxt.Init_args(fxt.Make_arg("a"));
|
||||
fxt.Exec_process("--a", "0", "--a", "0");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__key__duplicate);
|
||||
}
|
||||
@Test public void Err__val__reqd() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Bool_.Y), fxt.Make_arg("b", Bool_.N));
|
||||
fxt.Exec_process("--b", "1");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__val__required);
|
||||
}
|
||||
@Test public void Err__val__parse__yn() {
|
||||
fxt.Init_args(fxt.Make_arg("a", Gfo_cmd_arg_itm_.Val_tid_yn));
|
||||
fxt.Exec_process("--a", "x");
|
||||
fxt.Test_errs(Gfo_cmd_arg_mgr_.Err__val__invalid__yn);
|
||||
}
|
||||
@Test public void Val_as_url_rel_dir_or() { // PURPOSE: "/xowa" -> "/xowa/"
|
||||
String root_dir = Op_sys.Cur().Tid_is_wnt() ? "C:\\" : "/", dir_spr = Op_sys.Cur().Fsys_dir_spr_str();
|
||||
fxt.Test_val_as_url_rel_dir_or(root_dir, dir_spr, root_dir + "sub" , root_dir + "sub" + dir_spr); // /sub -> /sub/
|
||||
fxt.Test_val_as_url_rel_dir_or(root_dir, dir_spr, root_dir + "sub" + dir_spr , root_dir + "sub" + dir_spr); // /sub/ -> /sub/
|
||||
fxt.Test_val_as_url_rel_dir_or(root_dir, dir_spr, "sub" , root_dir + "dir" + dir_spr + "sub" + dir_spr); // sub -> /dir/sub/
|
||||
}
|
||||
}
|
||||
class Gfo_cmd_arg_mgr_fxt {
|
||||
private final Tst_mgr tst_mgr = new Tst_mgr();
|
||||
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} Gfo_usr_dlg usr_dlg;
|
||||
public Gfo_cmd_arg_mgr Mgr() {return mgr;} private final Gfo_cmd_arg_mgr mgr = new Gfo_cmd_arg_mgr();
|
||||
public Gfo_cmd_arg_mgr_fxt Clear() {
|
||||
if (usr_dlg == null)
|
||||
usr_dlg = Gfo_usr_dlg_.Test();
|
||||
mgr.Reset();
|
||||
usr_dlg.Gui_wkr().Clear();
|
||||
return this;
|
||||
}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key) {return Make_arg(key, false);}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key, int tid) {return Make_arg(key, false, tid);}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key, boolean reqd) {return Gfo_cmd_arg_itm_.new_(key, reqd, Gfo_cmd_arg_itm_.Val_tid_string);}
|
||||
public Gfo_cmd_arg_itm Make_arg(String key, boolean reqd, int tid) {return Gfo_cmd_arg_itm_.new_(key, reqd, tid);}
|
||||
public Gfo_cmd_itm_chkr Make_chkr(String key, Object val) {return new Gfo_cmd_itm_chkr(key, val);}
|
||||
public Gfo_cmd_arg_mgr_fxt Init_args(Gfo_cmd_arg_itm... v) {mgr.Reg_many(v); return this;}
|
||||
public Gfo_cmd_arg_mgr_fxt Exec_process(String... v) {mgr.Parse(v); return this;}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_actl(Gfo_cmd_itm_chkr... expd) {
|
||||
Gfo_cmd_arg_itm[] actl = mgr.To_ary();
|
||||
tst_mgr.Tst_ary("", expd, actl);
|
||||
return this;
|
||||
}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_errs_none() {return Test_errs(String_.Ary_empty);}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_errs(String... expd) {
|
||||
String[] actl = mgr.Errs__to_str_ary();
|
||||
int len = actl.length;
|
||||
for (int i = 0; i < len; ++i) { // extract key part; EX: "unknown key: abc" -> unknown key
|
||||
actl[i] = String_.GetStrBefore(actl[i], ":");
|
||||
}
|
||||
Tfds.Eq_ary_str(expd, actl);
|
||||
return this;
|
||||
}
|
||||
public Gfo_cmd_arg_mgr_fxt Test_write(String... expd) {
|
||||
Tfds.Eq_ary_str(expd, ((Gfo_usr_dlg__gui_test)usr_dlg.Gui_wkr()).Xto_str_ary_and_clear());
|
||||
return this;
|
||||
}
|
||||
public void Test_val_as_url_rel_dir_or(String root_dir, String dir_spr, String val, String expd) {
|
||||
Io_url actl = Make_arg("key").Val_(val).Val_as_url__rel_dir_or(Io_url_.new_dir_(root_dir).GenSubDir("dir"), null);
|
||||
Tfds.Eq(expd, actl.Raw());
|
||||
}
|
||||
}
|
||||
class Gfo_cmd_itm_chkr implements Tst_chkr {
|
||||
public Gfo_cmd_itm_chkr(String key, Object val) {this.key = key; this.val = val;} private String key; Object val;
|
||||
public Class<?> TypeOf() {return Gfo_cmd_arg_itm.class;}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Gfo_cmd_arg_itm actl = (Gfo_cmd_arg_itm)actl_obj;
|
||||
int err = 0;
|
||||
err += mgr.Tst_val(false, path, "key", key, actl.Key());
|
||||
err += mgr.Tst_val(false, path, "val", val, actl.Val());
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.enums; import gplx.*; import gplx.core.*;
|
||||
class Gfo_enum_grp {
|
||||
// private Ordered_hash itms = Ordered_hash_.new_();
|
||||
// private Ordered_hash itms = Ordered_hash_.New();
|
||||
public Gfo_enum_grp(Guid_adp uid, String key, int id, String name, int sort, String xtn) {
|
||||
this.uid = uid; this.key = key; this.id = id; this.name = name; this.sort = sort; this.xtn = xtn;
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ public class Gfo_fld_rdr extends Gfo_fld_base {
|
||||
}
|
||||
throw Err_.new_wo_type("fld_dlm failed", "fld_dlm", (char)fld_dlm, "bgn", fld_bgn);
|
||||
}
|
||||
public String Read_str_escape() {Move_next_escaped(bfr); return String_.new_u8(bfr.Xto_bry_and_clear());}
|
||||
public byte[] Read_bry_escape() {Move_next_escaped(bfr); return bfr.Xto_bry_and_clear();}
|
||||
public String Read_str_escape() {Move_next_escaped(bfr); return String_.new_u8(bfr.To_bry_and_clear());}
|
||||
public byte[] Read_bry_escape() {Move_next_escaped(bfr); return bfr.To_bry_and_clear();}
|
||||
public void Move_1() {++pos;}
|
||||
public void Move_next_escaped() {Move_next_escaped(bfr); bfr.Clear();}
|
||||
public int Move_next_simple_fld() {
|
||||
|
||||
@@ -50,7 +50,7 @@ class Gfo_fld_rdr_fxt {
|
||||
byte[] bry = Bry_.new_u8(val);
|
||||
wtr.Bfr_(bfr);
|
||||
wtr.Write_bry_escape_fld(bry);
|
||||
Tfds.Eq(expd, bfr.Xto_str());
|
||||
Tfds.Eq(expd, bfr.To_str());
|
||||
return this;
|
||||
} private Bry_bfr bfr = Bry_bfr.new_();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class Gfo_fld_wtr extends Gfo_fld_base {
|
||||
public boolean Flush_needed(int v) {return bfr.Len() + v > bfr_max;}
|
||||
public void Flush() {
|
||||
if (Fil_gen().Cur_url() == null) fil_gen.Nxt_url();
|
||||
Io_mgr.I.AppendFilBfr(fil_gen.Cur_url(), bfr);
|
||||
Io_mgr.Instance.AppendFilBfr(fil_gen.Cur_url(), bfr);
|
||||
}
|
||||
public void Flush_nxt() {Flush(); fil_gen.Nxt_url();}
|
||||
public Gfo_fld_wtr Ctor_xdat() {return (Gfo_fld_wtr)super.Ctor_xdat_base();}
|
||||
|
||||
@@ -33,7 +33,7 @@ class Gfo_i18n_itm {
|
||||
synchronized (tmp_fmtr) {
|
||||
tmp_fmtr.Fmt_(val);
|
||||
tmp_fmtr.Bld_bfr_many(tmp_bfr, args);
|
||||
rv = tmp_bfr.Xto_bry_and_clear();
|
||||
rv = tmp_bfr.To_bry_and_clear();
|
||||
}
|
||||
return val_cmd == null ? rv : val_cmd.Process(src, key, rv);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.core.lists; import gplx.*; import gplx.core.*;
|
||||
import org.junit.*;
|
||||
public class StatRng_tst {
|
||||
// Mwl_parser_fxt fx = new Mwl_parser_fxt(); Pf_func_lang_rsc rsc = Pf_func_lang_rsc._;
|
||||
// Mwl_parser_fxt fx = new Mwl_parser_fxt(); Pf_func_lang_rsc rsc = Pf_func_lang_rsc.Instance;
|
||||
StatRng_fxt fx = new StatRng_fxt();
|
||||
@Test public void Empty() {
|
||||
fx.ini_(1, 1, 5);
|
||||
@@ -34,6 +34,6 @@ public class StatRng_tst {
|
||||
}
|
||||
/*
|
||||
public class Pf_func_switch_tst {
|
||||
// Mwl_parser_fxt fx = new Mwl_parser_fxt(); Pf_func_lang_rsc rsc = Pf_func_lang_rsc._;
|
||||
// Mwl_parser_fxt fx = new Mwl_parser_fxt(); Pf_func_lang_rsc rsc = Pf_func_lang_rsc.Instance;
|
||||
|
||||
*/
|
||||
@@ -46,10 +46,10 @@ public class Gfo_log_fil {
|
||||
if (session != null) session.Add_by_bfr(msg_bfr);
|
||||
}
|
||||
public void Flush() {
|
||||
Io_mgr.I.AppendFilBfr(fil_cur, fil_bfr);
|
||||
Io_mgr.Instance.AppendFilBfr(fil_cur, fil_bfr);
|
||||
}
|
||||
private Io_url Fil_new() {
|
||||
String part = size_max == -1 ? "" : "-" + Int_.Xto_str(++file_idx);
|
||||
String part = size_max == -1 ? "" : "-" + Int_.To_str(++file_idx);
|
||||
return dir.OwnerDir().GenSubFil_ary(key, part, ".log");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.logs; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_log_mgr {
|
||||
private final Ordered_hash fil_list = Ordered_hash_.new_();
|
||||
private final Ordered_hash fil_list = Ordered_hash_.New();
|
||||
private final Gfo_log_fil session_fil;
|
||||
private final Io_url dir;
|
||||
private final long size_dflt = Io_mgr.Len_mb * 2;
|
||||
|
||||
@@ -17,7 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
public interface Gfo_inet_conn {
|
||||
void Clear();
|
||||
void Upload_by_bytes(String url, byte[] data);
|
||||
byte[] Download_as_bytes_or_null(String url); // return null instead of throwing exception
|
||||
int Tid();
|
||||
void Clear();
|
||||
void Upload_by_bytes(String url, byte[] data);
|
||||
byte[] Download_as_bytes_or_null(String url); // return null instead of throwing exception
|
||||
}
|
||||
|
||||
@@ -17,19 +17,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
public class Gfo_inet_conn_ {
|
||||
public static final int Tid__http = 1, Tid__mem__hash = 2, Tid__mem__pile = 3;
|
||||
public static Gfo_inet_conn new_http() {return new Gfo_inet_conn__http();}
|
||||
public static Gfo_inet_conn new_mem_hash() {return new Gfo_inet_conn__mem__hash();}
|
||||
public static Gfo_inet_conn new_mem_pile() {return new Gfo_inet_conn__mem__pile();}
|
||||
public static Gfo_inet_conn new_() {
|
||||
switch (new_prototype) {
|
||||
default:
|
||||
case Tid__http: return new_http();
|
||||
case Tid__mem__hash: return new_mem_hash();
|
||||
case Tid__mem__pile: return new_mem_pile();
|
||||
}
|
||||
}
|
||||
public static void new_prototype_(int v) {new_prototype = v;} private static int new_prototype = Tid__http;
|
||||
}
|
||||
class Gfo_inet_conn__mem__hash implements Gfo_inet_conn {
|
||||
private final Hash_adp_bry hash = Hash_adp_bry.cs();
|
||||
public void Clear() {hash.Clear();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {hash.Add(url, data);}
|
||||
public byte[] Download_as_bytes_or_null(String url) {return (byte[])hash.Get_by(url);}
|
||||
private final Hash_adp hash = Hash_adp_.new_();
|
||||
public int Tid() {return Gfo_inet_conn_.Tid__mem__hash;}
|
||||
public void Clear() {hash.Clear();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {hash.Add(url, data);}
|
||||
public byte[] Download_as_bytes_or_null(String url) {return (byte[])hash.Get_by(url);}
|
||||
}
|
||||
class Gfo_inet_conn__mem__pile implements Gfo_inet_conn {
|
||||
private final List_adp pile = List_adp_.new_();
|
||||
public void Clear() {pile.Clear();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {pile.Add(data);}
|
||||
public byte[] Download_as_bytes_or_null(String url) {return (byte[])List_adp_.Pop_last(pile);}
|
||||
public int Tid() {return Gfo_inet_conn_.Tid__mem__hash;}
|
||||
public void Clear() {pile.Clear();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {pile.Add(data);}
|
||||
public byte[] Download_as_bytes_or_null(String url) {return (byte[])List_adp_.Pop_last(pile);}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
import gplx.ios.*;
|
||||
class Gfo_inet_conn__http implements Gfo_inet_conn {
|
||||
private final IoEngine_xrg_downloadFil downloader = IoEngine_xrg_downloadFil.new_("", Io_url_.Empty);
|
||||
public void Clear() {throw Err_.new_unsupported();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {throw Err_.new_unsupported();}
|
||||
public byte[] Download_as_bytes_or_null(String url) {
|
||||
public int Tid() {return Gfo_inet_conn_.Tid__http;}
|
||||
public void Clear() {throw Err_.new_unsupported();}
|
||||
public void Upload_by_bytes(String url, byte[] data) {throw Err_.new_unsupported();}
|
||||
public byte[] Download_as_bytes_or_null(String url) {
|
||||
try {return downloader.Exec_as_bry(url);}
|
||||
catch (Exception e) {Err_.Noop(e); return null;}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class Gfo_protocol_itm {
|
||||
, Tid_relative_1 = 29 // [//a.org]
|
||||
, Tid_relative_2 = 30 // [[//a.org]]
|
||||
;
|
||||
public static final Ordered_hash Regy = Ordered_hash_.new_bry_();
|
||||
public static final Ordered_hash Regy = Ordered_hash_.New_bry();
|
||||
public static final Gfo_protocol_itm
|
||||
Itm_http = new_(Tid_http , "http://")
|
||||
, Itm_https = new_(Tid_https , "https://")
|
||||
|
||||
@@ -46,6 +46,6 @@ public class Gfo_qarg_itm {
|
||||
bfr.Add(itm.Val_bry());
|
||||
bfr.Add_byte_nl();
|
||||
}
|
||||
return bfr.Xto_str_and_clear();
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class Gfo_qarg_mgr {
|
||||
Gfo_qarg_itm arg = (Gfo_qarg_itm)hash.Get_by(key);
|
||||
return arg == null ? or : String_.new_u8(arg.Val_bry());
|
||||
}
|
||||
public void Set_val_by_int(byte[] key, int val) {Set_val_by_bry(key, Bry_.new_a7(Int_.Xto_str(val)));}
|
||||
public void Set_val_by_int(byte[] key, int val) {Set_val_by_bry(key, Bry_.new_a7(Int_.To_str(val)));}
|
||||
public void Set_val_by_bry(byte[] key, byte[] val) {
|
||||
Gfo_qarg_itm arg = (Gfo_qarg_itm)hash.Get_by(key);
|
||||
if (arg == null) {
|
||||
@@ -68,13 +68,13 @@ public class Gfo_qarg_mgr {
|
||||
Gfo_qarg_itm itm = Get_arg(key); if (itm == null) continue;
|
||||
bfr.Add_byte(Byte_ascii.Amp).Add(itm.Key_bry()).Add_byte(Byte_ascii.Eq).Add(itm.Val_bry());
|
||||
}
|
||||
return bfr.Xto_bry_and_clear();
|
||||
return bfr.To_bry_and_clear();
|
||||
}
|
||||
public byte[] To_bry() {
|
||||
int len = list.Count(); if (len == 0) return Bry_.Empty;
|
||||
Bry_bfr bfr = Bry_bfr.new_();
|
||||
To_bry(bfr, gplx.xowa.Xoa_app_.Utl__encoder_mgr().Href(), false);
|
||||
return bfr.Xto_bry_and_clear();
|
||||
return bfr.To_bry_and_clear();
|
||||
}
|
||||
public void To_bry(Bry_bfr bfr, Url_encoder href_encoder, boolean encode) {
|
||||
int len = list.Count(); if (len == 0) return;
|
||||
|
||||
@@ -255,7 +255,7 @@ public class Gfo_url_parser {
|
||||
tmp_bfr.Add_byte_eq().Add(qarg_val);
|
||||
}
|
||||
qargs.Clear();
|
||||
segs_ary.Set_at_last(tmp_bfr.Xto_bry_and_clear());
|
||||
segs_ary.Set_at_last(tmp_bfr.To_bry_and_clear());
|
||||
}
|
||||
public static final byte[] Bry_double_slash = new byte[] {Byte_ascii.Slash, Byte_ascii.Slash};
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
public class Http_post_data_hash {
|
||||
private final Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
private final Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
public int Len() {return hash.Count();}
|
||||
public Http_post_data_itm Get_at(int i) {return (Http_post_data_itm)hash.Get_at(i);}
|
||||
public Http_post_data_itm Get_by(byte[] k) {return (Http_post_data_itm)hash.Get_by(k);}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class Http_request_itm {
|
||||
bfr.Add_kv_dlm(line, String_.new_u8(itm.Key()), itm.Val());
|
||||
}
|
||||
}
|
||||
return bfr.Xto_str_and_clear();
|
||||
return bfr.To_str_and_clear();
|
||||
}
|
||||
public static final int Type_get = 1, Type_post = 2;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ public class Http_request_parser {
|
||||
if (Bry_.Has_at_bgn(line, content_type_boundary)) break;
|
||||
tmp_bfr.Add(line);
|
||||
}
|
||||
byte[] val = tmp_bfr.Xto_bry_and_clear();
|
||||
byte[] val = tmp_bfr.To_bry_and_clear();
|
||||
post_data_hash.Add(key, val);
|
||||
return line;
|
||||
}
|
||||
|
||||
@@ -18,5 +18,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.core.net; import gplx.*; import gplx.core.*;
|
||||
import gplx.core.consoles.*;
|
||||
class Http_server_wtr__console implements Http_server_wtr {
|
||||
public void Write_str_w_nl(String s) {Console_adp__sys.I.Write_str_w_nl(s);}
|
||||
public void Write_str_w_nl(String s) {Console_adp__sys.Instance.Write_str_w_nl(s);}
|
||||
}
|
||||
|
||||
@@ -30,5 +30,5 @@ public class Bry_cache {
|
||||
return ((Bry_obj_ref)rv).Val();
|
||||
}
|
||||
Hash_adp hash = Hash_adp_.new_(); Bry_obj_ref hash_ref = Bry_obj_ref.null_();
|
||||
public static final Bry_cache _ = new Bry_cache(); Bry_cache() {}
|
||||
public static final Bry_cache Instance = new Bry_cache(); Bry_cache() {}
|
||||
}
|
||||
|
||||
@@ -29,5 +29,5 @@ public class Int_2_val {
|
||||
int v1 = Int_.parse_or(itms[1], Int_.Min_value); if (v1 == Int_.Min_value) return Null_ptr;
|
||||
return new Int_2_val(v0, v1);
|
||||
}
|
||||
public static String Xto_str(Bry_bfr bfr, int x, int y) {return bfr.Add_int_variable(x).Add_byte_comma().Add_int_variable(y).Xto_str_and_clear();}
|
||||
public static String Xto_str(Bry_bfr bfr, int x, int y) {return bfr.Add_int_variable(x).Add_byte_comma().Add_int_variable(y).To_str_and_clear();}
|
||||
}
|
||||
|
||||
@@ -35,5 +35,5 @@ public class Int_ary_parser extends Obj_ary_parser_base {
|
||||
parser.Parse(bry, bgn, end); if (parser.Has_err() || parser.Has_frac()) throw Err_.new_wo_type("failed to parse number", "val", String_.new_u8(bry, bgn, end));
|
||||
ary[ary_idx++] = parser.Rv_as_int();
|
||||
}
|
||||
public static final Int_ary_parser _ = new Int_ary_parser();
|
||||
public static final Int_ary_parser Instance = new Int_ary_parser();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Int_ary_parser_tst {
|
||||
@Test public void One() {tst_ints("1" , 0, 1, Int_.Ary(1));}
|
||||
@Test public void None() {tst_ints("" , 0, 0, Int_.Ary());}
|
||||
private void tst_ints(String raw, int bgn, int end, int[] expd) {
|
||||
int[] actl = Int_ary_parser._.Parse_ary(Bry_.new_a7(raw), bgn, end, Byte_ascii.Comma);
|
||||
int[] actl = Int_ary_parser.Instance.Parse_ary(Bry_.new_a7(raw), bgn, end, Byte_ascii.Comma);
|
||||
Tfds.Eq_ary(expd, actl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class Tst_mgr {
|
||||
int max_len = expd_ary_len > actl_ary_len ? expd_ary_len : actl_ary_len;
|
||||
int err = 0;
|
||||
for (int i = 0; i < max_len; i++) {
|
||||
String path = ownerPath + Int_.Xto_str(i);
|
||||
String path = ownerPath + Int_.To_str(i);
|
||||
Tst_chkr expd_obj = i < expd_ary_len ? expd_ary[i] : Tst_mgr.Null_chkr;
|
||||
Object actl_obj = i < actl_ary_len ? actl_ary[i] : "<NULL OBJ>";
|
||||
String actl_type = i < actl_ary_len ? Type_adp_.NameOf_obj(actl_obj) : "<NULL TYPE>";
|
||||
@@ -86,7 +86,7 @@ public class Tst_mgr {
|
||||
Object itm = Array_.Get_at(ary, i);
|
||||
ary_sb.Add(Object_.Xto_str_strict_or_null_mark(itm)).Add(",");
|
||||
}
|
||||
return ary_sb.Xto_str_and_clear();
|
||||
return ary_sb.To_str_and_clear();
|
||||
} String_bldr ary_sb = String_bldr_.new_();
|
||||
String Build() {
|
||||
String_bldr sb = String_bldr_.new_();
|
||||
@@ -104,7 +104,7 @@ public class Tst_mgr {
|
||||
if (!itm.Pass())
|
||||
sb.Add_fmt("\n{0} {1} {2} '{3}'", String_.PadEnd("", comp_max, " "), " " + String_.PadEnd("", path_max, " "), " " + String_.PadEnd("", name_max, " ") + " ", itm.Actl());
|
||||
}
|
||||
return sb.Xto_str_and_clear();
|
||||
return sb.To_str_and_clear();
|
||||
}
|
||||
int Max(int max, String s) {int len = String_.Len(s); return len > max ? len : max;}
|
||||
public static final Tst_chkr Null_chkr = new Tst_chkr_null();
|
||||
|
||||
@@ -32,10 +32,10 @@ public class Gfo_thread_cmd_download implements Gfo_thread_cmd {
|
||||
public int Async_sleep_interval() {return Gfo_thread_cmd_.Async_sleep_interval_1_second;}
|
||||
public boolean Async_prog_enabled() {return false;}
|
||||
@gplx.Virtual public byte Async_init() {
|
||||
if (Io_mgr.I.ExistsFil(trg)) {
|
||||
if (Io_mgr.Instance.ExistsFil(trg)) {
|
||||
int rslt = kit.Ask_yes_no_cancel(GRP_KEY, "target_exists", "Target file already exists: '~{0}'.\nDo you want to delete it?", trg.Raw());
|
||||
switch (rslt) {
|
||||
case Gfui_dlg_msg_.Btn_yes: Io_mgr.I.DeleteFil(trg); break;
|
||||
case Gfui_dlg_msg_.Btn_yes: Io_mgr.Instance.DeleteFil(trg); break;
|
||||
case Gfui_dlg_msg_.Btn_no: return Gfo_thread_cmd_.Init_cancel_step;
|
||||
case Gfui_dlg_msg_.Btn_cancel: return Gfo_thread_cmd_.Init_cancel_all;
|
||||
default: throw Err_.new_unhandled(rslt);
|
||||
@@ -59,7 +59,7 @@ public class Gfo_thread_cmd_download implements Gfo_thread_cmd {
|
||||
kit.Ask_ok(GRP_KEY, "download.fail", "download failed. Please select 'read from file' if you've already downloaded a dump: url=~{0} error=~{1}", src, xrg.Rslt_err_str());
|
||||
}
|
||||
} boolean download_pass = true;
|
||||
protected gplx.ios.IoEngine_xrg_downloadFil xrg = Io_mgr.I.DownloadFil_args("", Io_url_.Empty);
|
||||
protected gplx.ios.IoEngine_xrg_downloadFil xrg = Io_mgr.Instance.DownloadFil_args("", Io_url_.Empty);
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_async_bgn)) Download();
|
||||
else if (ctx.Match(k, Invk_owner)) return owner;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class Gfo_thread_cmd_replace implements Gfo_thread_cmd {
|
||||
public int Async_sleep_interval() {return Gfo_thread_cmd_.Async_sleep_interval_1_second;}
|
||||
public boolean Async_prog_enabled() {return false;}
|
||||
@gplx.Virtual public byte Async_init() {
|
||||
if (!Io_mgr.I.ExistsFil(fil)) {kit.Ask_ok(GRP_KEY, "file_missing", "File does not exist: '~{0}'", fil.Raw()); return Gfo_thread_cmd_.Init_cancel_step;}
|
||||
if (!Io_mgr.Instance.ExistsFil(fil)) {kit.Ask_ok(GRP_KEY, "file_missing", "File does not exist: '~{0}'", fil.Raw()); return Gfo_thread_cmd_.Init_cancel_step;}
|
||||
return Gfo_thread_cmd_.Init_ok;
|
||||
}
|
||||
public boolean Async_term() {return true;}
|
||||
@@ -38,13 +38,13 @@ public class Gfo_thread_cmd_replace implements Gfo_thread_cmd {
|
||||
public boolean Async_running() {return false;}
|
||||
@gplx.Virtual public void Async_run() {Exec_find_replace();} // NOTE: do not run async; if multiple commands for same file then they will not always work
|
||||
public void Exec_find_replace() {
|
||||
String raw = Io_mgr.I.LoadFilStr(fil);
|
||||
String raw = Io_mgr.Instance.LoadFilStr(fil);
|
||||
int pairs_len = pairs.Count();
|
||||
for (int i = 0; i < pairs_len; i++) {
|
||||
KeyVal kv = (KeyVal)pairs.Get_at(i);
|
||||
raw = String_.Replace(raw, kv.Key(), kv.Val_to_str_or_null());
|
||||
}
|
||||
Io_mgr.I.SaveFilStr(fil, raw);
|
||||
Io_mgr.Instance.SaveFilStr(fil, raw);
|
||||
usr_dlg.Prog_many(GRP_KEY, "done", "replace completed: ~{0} ~{1}", fil.Raw(), pairs_len);
|
||||
}
|
||||
public List_adp pairs = List_adp_.new_();
|
||||
|
||||
@@ -32,22 +32,22 @@ public class Gfo_thread_cmd_unzip implements Gfo_thread_cmd {
|
||||
public boolean Async_prog_enabled() {return true;}
|
||||
public void Async_prog_run(int async_sleep_sum) {
|
||||
String size_str = " please wait...";
|
||||
if (trg.Type_fil()) size_str = gplx.ios.Io_size_.To_str(Io_mgr.I.QueryFil(trg).Size());
|
||||
if (trg.Type_fil()) size_str = gplx.ios.Io_size_.To_str(Io_mgr.Instance.QueryFil(trg).Size());
|
||||
usr_dlg.Prog_many(GRP_KEY, "unzip", "unzipping: ~{0}", size_str);
|
||||
}
|
||||
@gplx.Virtual public byte Async_init() {
|
||||
if (!Io_mgr.I.ExistsFil(src)) {
|
||||
if (!Io_mgr.Instance.ExistsFil(src)) {
|
||||
kit.Ask_ok(GRP_KEY, "source_missing", "Source file does not exist: '~{0}'", src.Raw());
|
||||
return Gfo_thread_cmd_.Init_cancel_step;
|
||||
}
|
||||
trg_is_dir = trg.Type_dir();
|
||||
if (delete_trg_if_exists
|
||||
&& (( trg_is_dir && Io_mgr.I.ExistsDir(trg))
|
||||
|| (!trg_is_dir && Io_mgr.I.ExistsFil(trg)))
|
||||
&& (( trg_is_dir && Io_mgr.Instance.ExistsDir(trg))
|
||||
|| (!trg_is_dir && Io_mgr.Instance.ExistsFil(trg)))
|
||||
) {
|
||||
int rslt = kit.Ask_yes_no_cancel(GRP_KEY, "target_exists", "Target file already exists: '~{0}'.\nDo you want to delete it?", trg.Raw());
|
||||
switch (rslt) {
|
||||
case Gfui_dlg_msg_.Btn_yes: if (trg_is_dir) Io_mgr.I.DeleteDirDeep(trg); else Io_mgr.I.DeleteFil(trg); break;
|
||||
case Gfui_dlg_msg_.Btn_yes: if (trg_is_dir) Io_mgr.Instance.DeleteDirDeep(trg); else Io_mgr.Instance.DeleteFil(trg); break;
|
||||
case Gfui_dlg_msg_.Btn_no: return Gfo_thread_cmd_.Init_cancel_step;
|
||||
case Gfui_dlg_msg_.Btn_cancel: return Gfo_thread_cmd_.Init_cancel_all;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class Gfo_thread_cmd_unzip implements Gfo_thread_cmd {
|
||||
}
|
||||
public boolean Async_term() {
|
||||
if (rename_dir) {
|
||||
Io_url[] dirs = Io_mgr.I.QueryDir_args(trg.OwnerDir()).DirOnly_().Recur_(false).ExecAsUrlAry();
|
||||
Io_url[] dirs = Io_mgr.Instance.QueryDir_args(trg.OwnerDir()).DirOnly_().Recur_(false).ExecAsUrlAry();
|
||||
int dirs_len = dirs.length;
|
||||
Io_url zip_dir = Io_url_.Empty;
|
||||
for (int i = 0; i < dirs_len; i++) {
|
||||
@@ -76,14 +76,14 @@ public class Gfo_thread_cmd_unzip implements Gfo_thread_cmd {
|
||||
return false;
|
||||
}
|
||||
if (!String_.Eq(String_.Lower(zip_dir.Raw()), String_.Lower(trg.Raw()))) // HACK: inkscape is itself
|
||||
Io_mgr.I.MoveDirDeep(zip_dir, trg);
|
||||
Io_mgr.Instance.MoveDirDeep(zip_dir, trg);
|
||||
}
|
||||
switch (term_cmd_for_src) {
|
||||
case Term_cmd_for_src_noop: break;
|
||||
case Term_cmd_for_src_delete: Io_mgr.I.DeleteFil(src); break;
|
||||
case Term_cmd_for_src_delete: Io_mgr.Instance.DeleteFil(src); break;
|
||||
case Term_cmd_for_src_move:
|
||||
if (term_cmd_for_src_url == Io_url_.Empty) throw Err_.new_wo_type("move specified, but no url");
|
||||
Io_mgr.I.MoveFil_args(src, term_cmd_for_src_url, true).Exec();
|
||||
Io_mgr.Instance.MoveFil_args(src, term_cmd_for_src_url, true).Exec();
|
||||
break;
|
||||
default: throw Err_.new_unhandled(term_cmd_for_src);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
public interface Gfo_poolable_itm {
|
||||
int Pool__idx();
|
||||
void Pool__clear (Object[] args);
|
||||
Gfo_poolable_itm Pool__make (int idx, Object[] args);
|
||||
}
|
||||
127
400_xowa/src/gplx/core/threads/poolables/Gfo_poolable_mgr.java
Normal file
127
400_xowa/src/gplx/core/threads/poolables/Gfo_poolable_mgr.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
public class Gfo_poolable_mgr {
|
||||
private final Object thread_lock = new Object();
|
||||
private final Gfo_poolable_itm prototype; private final Object[] make_args, clear_args;
|
||||
private Gfo_poolable_itm[] pool; private int pool_next, pool_len; private final int pool_max;
|
||||
public Gfo_poolable_mgr(Gfo_poolable_itm prototype, Object[] make_args, Object[] clear_args, int init_pool_len, int pool_max) {// NOTE: random IndexOutOfBounds errors in Get around free[--free_len] with free_len being -1; put member variable initialization within thread_lock to try to avoid; DATE:2014-09-21
|
||||
this.prototype = prototype; this.make_args = make_args; this.clear_args = clear_args;
|
||||
this.pool_len = init_pool_len; this.pool_max = pool_max;
|
||||
this.Clear_fast();
|
||||
}
|
||||
public void Clear_safe() {synchronized (thread_lock) {Clear_fast();}}
|
||||
public void Clear_fast() {
|
||||
this.pool = new Gfo_poolable_itm[pool_len];
|
||||
for (int i = 0; i < pool_len; ++i)
|
||||
pool[i] = prototype.Pool__make(i, make_args);
|
||||
this.free = new int[pool_len];
|
||||
pool_next = free_len = 0;
|
||||
}
|
||||
public Gfo_poolable_itm Get_safe() {synchronized (thread_lock) {return Get_fast();}}
|
||||
public Gfo_poolable_itm Get_fast() {
|
||||
Gfo_poolable_itm rv = null;
|
||||
int pool_idx = -1;
|
||||
if (free_len > 0) { // free_itms in pool; use it
|
||||
pool_idx = free[--free_len];
|
||||
rv = pool[pool_idx];
|
||||
}
|
||||
else { // nothing in pool; take next
|
||||
if (pool_next == pool_len)
|
||||
Expand_pool();
|
||||
pool_idx = pool_next++;
|
||||
rv = pool[pool_idx];
|
||||
if (rv == null) {
|
||||
rv = prototype.Pool__make(pool_idx, make_args);
|
||||
pool[pool_idx] = rv;
|
||||
}
|
||||
}
|
||||
rv.Pool__clear(clear_args); // NOTE: ALWAYS call Clear when doing Get. caller may forget to call Clear, and reused bfr may have leftover bytes. unit tests will not catch, and difficult to spot in app
|
||||
return rv;
|
||||
}
|
||||
public void Rls_safe(int idx) {synchronized (thread_lock) {Rls_safe(idx);}}
|
||||
public void Rls_fast(int idx) {
|
||||
if (idx == -1) throw Err_.new_wo_type("rls called on poolable that was not created by pool_mgr");
|
||||
int pool_idx = pool_next - 1;
|
||||
if (idx == pool_idx) // in-sequence; decrement count
|
||||
this.pool_next = pool_idx;
|
||||
else { // out-of-sequence
|
||||
if (free_len == pool_max) { // all used; assume entire pool released, but out of order
|
||||
// Array_.Sort((Object[])free);
|
||||
// for (int i = 0; i < pool_max; ++i) {
|
||||
// if (i != free[i]) throw Err_.new_("pool", "available_list out of order", "contents", "");
|
||||
// }
|
||||
for (int i = 0; i < free_len; ++i)
|
||||
free[i] = 0;
|
||||
free_len = 0;
|
||||
}
|
||||
else { // add to free pool
|
||||
free[free_len] = idx;
|
||||
++free_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Expand_pool() {
|
||||
// expand pool
|
||||
int new_pool_len = pool_len == 0 ? 2 : pool_len * 2;
|
||||
Gfo_poolable_itm[] new_pool = new Gfo_poolable_itm[new_pool_len];
|
||||
Array_.Copy_to(pool, 0, new_pool, 0, pool_len);
|
||||
this.pool = new_pool;
|
||||
this.pool_len = new_pool_len;
|
||||
|
||||
// expand free to same len
|
||||
int[] new_free = new int[pool_len];
|
||||
Array_.Copy_to(free, 0, new_free, 0, free_len);
|
||||
this.free = new_free;
|
||||
}
|
||||
@gplx.Internal protected int[] Free() {return free;} private int[] free; private int free_len;
|
||||
@gplx.Internal protected int Pool_len() {return pool_len;}
|
||||
// public int Mgr_id() {return mgr_id;} private int mgr_id;
|
||||
// public void Reset_if_gt(int v) {
|
||||
// this.Clear(); // TODO: for now, just call clear
|
||||
// }
|
||||
// public void Clear_fail_check() {
|
||||
// synchronized (thread_lock) {
|
||||
// for (int i = 0; i < ary_max; i++) {
|
||||
// Object itm = ary[i];
|
||||
// if (itm != null) {
|
||||
// if (!itm.Mkr_idx_is_null()) throw Err_.new_wo_type("failed to clear bfr", "idx", Int_.To_str(i));
|
||||
// itm.Clear();
|
||||
// }
|
||||
// ary[i] = null;
|
||||
// }
|
||||
// ary = Ary_empty;
|
||||
// free = Int_.Ary_empty;
|
||||
// free_len = 0;
|
||||
// nxt_idx = ary_max = 0;
|
||||
// }
|
||||
// }
|
||||
// public void Clear() {
|
||||
// synchronized (thread_lock) {
|
||||
// for (int i = 0; i < ary_max; i++) {
|
||||
// Object itm = ary[i];
|
||||
// if (itm != null) itm.Clear();
|
||||
// ary[i] = null;
|
||||
// }
|
||||
// ary = Ary_empty;
|
||||
// free = Int_.Ary_empty;
|
||||
// free_len = 0;
|
||||
// nxt_idx = ary_max = 0;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.threads.poolables; import gplx.*; import gplx.core.*; import gplx.core.threads.*;
|
||||
import org.junit.*;
|
||||
public class Gfo_poolable_mgr_tst {
|
||||
private final Gfo_poolable_mgr_tstr tstr = new Gfo_poolable_mgr_tstr();
|
||||
@Before public void init() {tstr.Clear();}
|
||||
@Test public void Get__one() {
|
||||
tstr.Test__get(0);
|
||||
tstr.Test__mgr__free(0, 0);
|
||||
tstr.Test__pool__len(2);
|
||||
}
|
||||
}
|
||||
class Gfo_poolable_mgr_tstr {
|
||||
private final Gfo_poolable_mgr mgr = new Gfo_poolable_mgr(new Sample_poolable_itm(-1, Object_.Ary_empty), Object_.Ary("make"), Object_.Ary("clear"), 2, 8);
|
||||
public void Clear() {mgr.Clear_fast();}
|
||||
public void Test__get(int expd_idx) {
|
||||
Sample_poolable_itm actl_itm = (Sample_poolable_itm)mgr.Get_fast();
|
||||
Tfds.Eq(expd_idx, actl_itm.Pool__idx(), "pool_idx");
|
||||
}
|
||||
public void Test__mgr__free(int... expd) {
|
||||
Tfds.Eq_ary(expd, mgr.Free(), "mgr.Free()");
|
||||
}
|
||||
public void Test__pool__len(int expd) {
|
||||
Tfds.Eq(expd, mgr.Pool_len(), "mgr.Pool_len()");
|
||||
}
|
||||
}
|
||||
class Sample_poolable_itm implements Gfo_poolable_itm {
|
||||
public Sample_poolable_itm(int pool_idx, Object[] make_args) {this.pool_idx = pool_idx; this.pool__make_args = make_args;}
|
||||
public int Pool__idx() {return pool_idx;} private final int pool_idx;
|
||||
public Object[] Pool__make_args() {return pool__make_args;} private final Object[] pool__make_args;
|
||||
public Object[] Pool__clear_args() {return pool__clear_args;} private Object[] pool__clear_args;
|
||||
public void Pool__clear (Object[] args) {this.pool__clear_args = args;}
|
||||
public Gfo_poolable_itm Pool__make (int idx, Object[] args) {return new Sample_poolable_itm(idx, args);}
|
||||
}
|
||||
Reference in New Issue
Block a user