1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

v2.11.1.1

This commit is contained in:
gnosygnu
2015-11-01 20:50:05 -05:00
parent 4f43f51b18
commit b990ec409f
858 changed files with 6758 additions and 4187 deletions

View File

@@ -51,10 +51,8 @@ public class Err_ {
return new Err(Bool_.Y, Trace_null, Type__gplx, "cast failed", "type", Type_adp_.NameOf_type(t), "obj", o_str);
}
public static String Message_lang(Exception e) {return e.getMessage();}
public static String Message_lang_error(Error e) {return e.getMessage();}
public static String Trace_lang(Exception e) {return Trace_lang_exec(e.getStackTrace());}
public static String Trace_lang(Error e) {return Trace_lang_exec(e.getStackTrace());}
public static String Message_lang(Throwable e) {return e.getMessage();}
public static String Trace_lang(Throwable e) {return Trace_lang_exec(e.getStackTrace());}
private static String Trace_lang_exec(StackTraceElement[] ary) {
String rv = "";
int len = ary.length;
@@ -70,6 +68,6 @@ public class Err_ {
}
public static String Message_gplx_full(Exception e) {return cast_or_make(e).To_str__full();}
public static String Message_gplx_log(Exception e) {return cast_or_make(e).To_str__log();}
public static Err cast_or_make(Exception e) {return Type_adp_.Eq_typeSafe(e, Err.class) ? (Err)e : new Err(Bool_.N, Err_.Trace_lang(e), Type_adp_.NameOf_obj(e), Err_.Message_lang(e));}
public static Err cast_or_make(Throwable e) {return Type_adp_.Eq_typeSafe(e, Err.class) ? (Err)e : new Err(Bool_.N, Err_.Trace_lang(e), Type_adp_.NameOf_obj(e), Err_.Message_lang(e));}
public static final String Type__op_canceled = "gplx.op_canceled";
}

View File

@@ -0,0 +1,163 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
import gplx.core.primitives.*; import gplx.core.ios.*; /*IoItmFil, IoItmDir..*/
public class Io_mgr { // exists primarily to gather all cmds under gplx namespace; otherwise need to use gplx.core.ios whenever copying/deleting file
public boolean Exists(Io_url url) {return url.Type_dir() ? ExistsDir(url) : ExistsFil(url);}
public boolean ExistsFil(Io_url url) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).ExistsFil_api(url);}
public void ExistsFilOrFail(Io_url url) {if (!ExistsFil(url)) throw Err_.new_wo_type("could not find file", "url", url);}
public void SaveFilStr(String url, String text) {SaveFilStr_args(Io_url_.new_fil_(url), text).Exec();}
public void SaveFilStr(Io_url url, String text) {SaveFilStr_args(url, text).Exec();}
public IoEngine_xrg_saveFilStr SaveFilStr_args(Io_url url, String text) {return IoEngine_xrg_saveFilStr.new_(url, text);}
public void AppendFilStr(String url, String text) {AppendFilStr(Io_url_.new_fil_(url), text);}
public void AppendFilStr(Io_url url, String text) {SaveFilStr_args(url, text).Append_(true).Exec();}
public void DeleteFil(Io_url url) {DeleteFil_args(url).Exec();}
public IoEngine_xrg_deleteFil DeleteFil_args(Io_url url) {return IoEngine_xrg_deleteFil.new_(url);}
public void MoveFil(Io_url src, Io_url trg) {IoEngine_xrg_xferFil.move_(src, trg).Exec();}
public IoEngine_xrg_xferFil MoveFil_args(Io_url src, Io_url trg, boolean overwrite) {return IoEngine_xrg_xferFil.move_(src, trg).Overwrite_(overwrite);}
public void CopyFil(Io_url src, Io_url trg, boolean overwrite) {IoEngine_xrg_xferFil.copy_(src, trg).Overwrite_(overwrite).Exec();}
public IoEngine_xrg_xferFil CopyFil_args(Io_url src, Io_url trg, boolean overwrite) {return IoEngine_xrg_xferFil.copy_(src, trg).Overwrite_(overwrite);}
public IoRecycleBin RecycleBin() {return recycleBin;} IoRecycleBin recycleBin = IoRecycleBin.Instance;
public IoStream OpenStreamWrite(Io_url url) {return OpenStreamWrite_args(url).Exec();}
public IoEngine_xrg_openWrite OpenStreamWrite_args(Io_url url) {return IoEngine_xrg_openWrite.new_(url);}
public IoItmFil QueryFil(Io_url url) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).QueryFil(url);}
public void UpdateFilAttrib(Io_url url, IoItmAttrib attrib) {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).UpdateFilAttrib(url, attrib);}
public void UpdateFilModifiedTime(Io_url url, DateAdp modified) {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).UpdateFilModifiedTime(url, modified);}
public boolean ExistsDir(Io_url url) {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).ExistsDir(url);}
public void CreateDir(Io_url url) {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).CreateDir(url);}
public boolean CreateDirIfAbsent(Io_url url) {
boolean exists = ExistsDir(url);
if (!exists) {
CreateDir(url);
return true;
}
return false;
}
public void Create_fil_ary(Io_fil[] fil_ary) {
for (Io_fil fil : fil_ary)
SaveFilStr(fil.Url(), fil.Data());
}
public Io_url[] QueryDir_fils(Io_url dir) {return QueryDir_args(dir).ExecAsUrlAry();}
public IoEngine_xrg_queryDir QueryDir_args(Io_url dir) {return IoEngine_xrg_queryDir.new_(dir);}
public void DeleteDirSubs(Io_url url) {IoEngine_xrg_deleteDir.new_(url).Exec();}
public IoEngine_xrg_deleteDir DeleteDir_cmd(Io_url url) {return IoEngine_xrg_deleteDir.new_(url);}
public void DeleteDirDeep(Io_url url) {IoEngine_xrg_deleteDir.new_(url).Recur_().Exec();}
public void DeleteDirDeep_ary(Io_url... urls) {for (Io_url url : urls) IoEngine_xrg_deleteDir.new_(url).Recur_().Exec();}
public int Delete_dir_empty(Io_url url) {return Io_mgr_.Delete_dir_empty(url);}
public void MoveDirDeep(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.move_(src, trg).Recur_().Exec();}
public IoEngine_xrg_xferDir CopyDir_cmd(Io_url src, Io_url trg) {return IoEngine_xrg_xferDir.copy_(src, trg);}
public void CopyDirSubs(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.copy_(src, trg).Exec();}
public void CopyDirDeep(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.copy_(src, trg).Recur_().Exec();}
public void DeleteDirIfEmpty(Io_url url) {
if (Array_.Len(QueryDir_fils(url)) == 0)
this.DeleteDirDeep(url);
}
public void AliasDir_sysEngine(String srcRoot, String trgRoot) {AliasDir(srcRoot, trgRoot, IoEngine_.SysKey);}
public void AliasDir(String srcRoot, String trgRoot, String engineKey) {IoUrlInfoRegy.Instance.Reg(IoUrlInfo_.alias_(srcRoot, trgRoot, engineKey));}
public IoStream OpenStreamRead(Io_url url) {return OpenStreamRead_args(url).ExecAsIoStreamOrFail();}
public IoEngine_xrg_openRead OpenStreamRead_args(Io_url url) {return IoEngine_xrg_openRead.new_(url);}
public String LoadFilStr(String url) {return LoadFilStr_args(Io_url_.new_fil_(url)).Exec();}
public String LoadFilStr(Io_url url) {return LoadFilStr_args(url).Exec();}
public IoEngine_xrg_loadFilStr LoadFilStr_args(Io_url url) {return IoEngine_xrg_loadFilStr.new_(url);}
public byte[] LoadFilBryOrNull(Io_url url) {return ExistsFil(url) ? LoadFilBry(url) : null;}
public byte[] LoadFilBry(String url) {return LoadFilBry_reuse(Io_url_.new_fil_(url), Bry_.Empty, Int_obj_ref.zero_());}
public byte[] LoadFilBry(Io_url url) {return LoadFilBry_reuse(url, Bry_.Empty, Int_obj_ref.zero_());}
public void LoadFilBryByBfr(Io_url url, Bry_bfr bfr) {
Int_obj_ref len = Int_obj_ref.zero_();
byte[] bry = LoadFilBry_reuse(url, Bry_.Empty, len);
bfr.Bfr_init(bry, len.Val());
}
public static final byte[] LoadFilBry_fail = Bry_.Empty;
public byte[] LoadFilBry_reuse(Io_url url, byte[] ary, Int_obj_ref aryLen) {
if (!ExistsFil(url)) {aryLen.Val_(0); return LoadFilBry_fail;}
IoStream stream = IoStream_.Null;
try {
stream = OpenStreamRead(url);
int streamLen = (int)stream.Len();
aryLen.Val_(streamLen);
if (streamLen > ary.length)
ary = new byte[streamLen];
stream.ReadAry(ary);
return ary;
}
catch (Exception e) {throw Err_.new_wo_type("failed to load file", "url", url.Xto_api(), "e", Err_.Message_lang(e));}
finally {stream.Rls();}
}
public byte[] LoadFilBry_loose(Io_url url) {return Bry_.new_u8(LoadFilStr_loose(url));}
public String LoadFilStr_loose(Io_url url) {
String rv = LoadFilStr_args(url).BomUtf8Convert_(Bool_.Y).MissingIgnored_(Bool_.Y).Exec();
if (String_.Has(rv, "\r\n"))
rv = String_.Replace(rv, "\r\n", "\n");
return rv;
}
public void AppendFilBfr(Io_url url, Bry_bfr bfr) {AppendFilByt(url, bfr.Bfr(), 0, bfr.Len()); bfr.ClearAndReset();}
public void AppendFilByt(Io_url url, byte[] val) {AppendFilByt(url, val, 0, val.length);}
public void AppendFilByt(Io_url url, byte[] val, int len) {AppendFilByt(url, val, 0, len);}
public void AppendFilByt(Io_url url, byte[] val, int bgn, int len) {
IoStream stream = IoStream_.Null;
try {
stream = OpenStreamWrite_args(url).Mode_(IoStream_.Mode_wtr_append).Exec();
stream.Write(val, bgn, len);
} finally {stream.Rls();}
}
public void SaveFilBfr(Io_url url, Bry_bfr bfr) {SaveFilBry(url, bfr.Bfr(), bfr.Len()); bfr.Clear();}
public void SaveFilBry(String urlStr, byte[] val) {SaveFilBry(Io_url_.new_fil_(urlStr), val);}
public void SaveFilBry(Io_url url, byte[] val) {SaveFilBry(url, val, val.length);}
public void SaveFilBry(Io_url url, byte[] val, int len) {SaveFilBry(url, val, 0, len);}
public void SaveFilBry(Io_url url, byte[] val, int bgn, int len) {
IoStream stream = IoStream_.Null;
try {
stream = OpenStreamWrite(url);
stream.Write(val, bgn, len);
} finally {stream.Rls();}
}
public IoEngine InitEngine_mem() {return IoEngine_.Mem_init_();}
public IoEngine InitEngine_mem_(String key) {
IoEngine engine = IoEngine_.mem_new_(key);
IoEnginePool.Instance.Add_if_dupe_use_nth(engine);
IoUrlInfoRegy.Instance.Reg(IoUrlInfo_.mem_(key, key));
return engine;
}
public boolean DownloadFil(String src, Io_url trg) {return IoEngine_xrg_downloadFil.new_(src, trg).Exec();}
public IoEngine_xrg_downloadFil DownloadFil_args(String src, Io_url trg) {return IoEngine_xrg_downloadFil.new_(src, trg);}
public static final Io_mgr Instance = new Io_mgr(); public Io_mgr() {}
public static final int Len_kb = 1024, Len_mb = 1048576, Len_gb = 1073741824, Len_gb_2 = 2147483647;
public static final long Len_mb_long = Len_mb;
public static final long Len_null = -1;
}
class Io_mgr_ {
public static int Delete_dir_empty(Io_url url) {
IoItmDir dir = Io_mgr.Instance.QueryDir_args(url).ExecAsDir();
int sub_dirs_len = dir.SubDirs().Count();
int deleted_dirs = 0;
for (int i = 0; i < sub_dirs_len; ++i) {
IoItmDir sub_dir = (IoItmDir)dir.SubDirs().Get_at(i);
deleted_dirs += Io_mgr.Instance.Delete_dir_empty(sub_dir.Url());
}
if ( dir.SubFils().Count() == 0
&& deleted_dirs == sub_dirs_len
) {
Io_mgr.Instance.DeleteDirIfEmpty(url);
return 1;
}
else
return 0;
}
}

View File

@@ -0,0 +1,100 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
import org.junit.*;
public class Io_mgr__tst {
@Before public void init() {fxt.Clear();} private final Io_mgr__fxt fxt = new Io_mgr__fxt();
@Test public void Dir_delete_empty__basic() {
fxt.Exec_itm_create("mem/dir/");
fxt.Exec_dir_delete_empty("mem/dir/");
fxt.Test_itm_exists_n("mem/dir/");
}
@Test public void Dir_delete_empty__no_delete() {
fxt.Exec_itm_create
( "mem/dir/"
, "mem/dir/fil.txt"
);
fxt.Exec_dir_delete_empty("mem/dir/");
fxt.Test_itm_exists_y("mem/dir/");
}
@Test public void Dir_delete_empty__nested_simple() {
fxt.Exec_itm_create
( "mem/dir/"
, "mem/dir/1/"
, "mem/dir/1/11/"
);
fxt.Exec_dir_delete_empty("mem/dir/");
fxt.Test_itm_exists_n("mem/dir/");
}
@Test public void Dir_delete_empty__nested_many() {
fxt.Exec_itm_create
( "mem/dir/"
, "mem/dir/1/"
, "mem/dir/1/11/"
, "mem/dir/2/22/"
, "mem/dir/2/22/222a/"
, "mem/dir/2/22/222b/"
);
fxt.Exec_dir_delete_empty("mem/dir/");
fxt.Test_itm_exists_n("mem/dir/");
}
@Test public void Dir_delete_empty__nested_some() {
fxt.Exec_itm_create
( "mem/dir/"
, "mem/dir/1/"
, "mem/dir/1/11/"
, "mem/dir/2/22/"
, "mem/dir/2/22/a.txt"
, "mem/dir/2/22/222a/"
, "mem/dir/2/22/222b/"
);
fxt.Exec_dir_delete_empty("mem/dir/");
fxt.Test_itm_exists_n
( "mem/dir/1/"
, "mem/dir/1/11/"
, "mem/dir/2/22/222a/"
, "mem/dir/2/22/222b/"
);
fxt.Test_itm_exists_y
( "mem/dir/"
, "mem/dir/2/22/"
);
}
}
class Io_mgr__fxt {
public void Clear() {Io_mgr.Instance.InitEngine_mem();}
public void Exec_itm_create(String... ary) {
for (String itm : ary) {
Io_url url = Io_url_.new_any_(itm);
if (url.Type_dir())
Io_mgr.Instance.CreateDir(url);
else
Io_mgr.Instance.SaveFilStr(url, url.NameAndExt());
}
}
public void Exec_dir_delete_empty(String url) {Io_mgr.Instance.Delete_dir_empty(Io_url_.mem_dir_(url));}
public void Test_itm_exists_n(String... ary) {Test_itm_exists(Bool_.N, ary);}
public void Test_itm_exists_y(String... ary) {Test_itm_exists(Bool_.Y, ary);}
public void Test_itm_exists(boolean expd, String... ary) {
for (String itm : ary) {
Io_url url = Io_url_.new_any_(itm);
boolean actl = url.Type_dir() ? Io_mgr.Instance.ExistsDir(url) : Io_mgr.Instance.ExistsFil(url);
Tfds.Eq(expd, actl, itm);
}
}
}

251
100_core/src/gplx/Tfds.java Normal file
View File

@@ -0,0 +1,251 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
import gplx.core.strings.*; import gplx.core.consoles.*;
public class Tfds { // URL:doc/gplx.tfds/Tfds.txt
public static boolean SkipDb = false;
public static void Eq_bool (boolean expd , boolean actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_bool (boolean expd , boolean actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq_byte (byte expd , byte actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq_int (int expd , int actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_int (int expd , int actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq_str (byte[] expd, byte[] actl, String fmt, Object... args) {Eq_exec_y(String_.new_u8(expd), String_.new_u8(actl), fmt, args);}
public static void Eq_str (byte[] expd, String actl, String fmt, Object... args) {Eq_exec_y(String_.new_u8(expd), actl, fmt, args);}
public static void Eq_str (String expd, byte[] actl, String fmt, Object... args) {Eq_exec_y(expd, String_.new_u8(actl), fmt, args);}
public static void Eq_str (String expd, String actl) {Eq_exec_y(expd, actl, "", Object_.Ary_empty);}
public static void Eq_str (String expd, String actl, String fmt, Object... args) {Eq_exec_y(expd, actl, fmt, args);}
public static void Eq(Object expd, Object actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_able(EqAble expd, EqAble actl) {Eq_able_wkr(expd, actl, true, EmptyStr);}
public static void Eq_able(EqAble expd, EqAble actl, String fmt, Object... args) {Eq_able_wkr(expd, actl, true, String_.Format(fmt, args));}
public static void Eq_byte(byte expd, byte actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_long(long expd, long actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_float(float expd, float actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_decimal(Decimal_adp expd, Decimal_adp actl) {Eq_wkr(expd.To_double(), actl.To_double(), true, EmptyStr);}
public static void Eq_date(DateAdp expd, DateAdp actl) {Eq_wkr(expd.XtoStr_gplx(), actl.XtoStr_gplx(), true, EmptyStr);}
public static void Eq_date(DateAdp expd, DateAdp actl, String fmt, Object... args){Eq_wkr(expd.XtoStr_gplx(), actl.XtoStr_gplx(), true, String_.Format(fmt, args));}
public static void Eq_url(Io_url expd, Io_url actl) {Eq_wkr(expd.Raw(), actl.Raw(), true, EmptyStr);}
public static void Eq_str(String expd, byte[] actl) {Eq_wkr(expd, String_.new_u8(actl), true, EmptyStr);}
public static void Eq_bry(String expd, byte[] actl) {Eq_wkr(expd, String_.new_u8(actl), true, EmptyStr);}
public static void Eq_bry(byte[] expd, byte[] actl) {Eq_wkr(String_.new_u8(expd), String_.new_u8(actl), true, EmptyStr);}
public static void Eq_str_intf(To_str_able expd, To_str_able actl, String msg) {Eq_wkr(expd.To_str(), actl.To_str(), true, msg);}
public static void Eq_str_intf(To_str_able expd, To_str_able actl) {Eq_wkr(expd.To_str(), actl.To_str(), true, String_.Empty);}
public static void Eq_str_lines(String lhs, String rhs) {Eq_str_lines(lhs, rhs, EmptyStr);}
public static void Eq_str_lines(String lhs, String rhs, String note) {
if (lhs == null) lhs = "";
if (rhs == null) rhs = "";
Eq_ary_wkr(String_.Split(lhs, Char_.NewLine), String_.Split(rhs, Char_.NewLine), false, note);
}
public static void Eq(Object expd, Object actl, String fmt, Object... args) {Eq_wkr(expd, actl, true, String_.Format(fmt, args));}
public static void Eq_rev(Object actl, Object expd) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_rev(Object actl, Object expd, String fmt, Object... args) {Eq_wkr(expd, actl, true, String_.Format(fmt, args));}
public static void Eq_true(Object actl) {Eq_wkr(true, actl, true, EmptyStr);}
public static void Eq_true(Object actl, String fmt, Object... args) {Eq_wkr(true, actl, true, String_.Format(fmt, args));}
public static void Eq_false(Object actl) {Eq_wkr(false, actl, true, EmptyStr);}
public static void Eq_false(Object actl, String fmt, Object... args) {Eq_wkr(false, actl, true, String_.Format(fmt, args));}
public static void Eq_null(Object actl) {Eq_wkr(null, actl, true, EmptyStr);}
public static void Eq_null(Object actl, String fmt, Object... args) {Eq_wkr(null, actl, true, String_.Format(fmt, args));}
public static void Eq_nullNot(Object actl) {Eq_wkr(null, actl, false, EmptyStr);}
public static void Eq_nullNot(Object actl, String fmt, Object... args) {Eq_wkr(null, actl, false, String_.Format(fmt, args));}
public static void Fail_expdError() {Eq_wkr(true, false, true, "fail expd error");}
public static void Fail(String fmt, Object... args) {Eq_wkr(true, false, true, String_.Format(fmt, args));}
public static void Eq_ary(Object lhs, Object rhs) {Eq_ary_wkr(lhs, rhs, true, EmptyStr);}
public static void Eq_ary(Object lhs, Object rhs, String fmt, Object... args){Eq_ary_wkr(lhs, rhs, true, String_.Format(fmt, args));}
public static void Eq_ary_str(Object lhs, Object rhs, String note) {Eq_ary_wkr(lhs, rhs, false, note);}
public static void Eq_ary_str(Object lhs, Object rhs) {Eq_ary_wkr(lhs, rhs, false, EmptyStr);}
public static void Eq_list(List_adp lhs, List_adp rhs) {Eq_list_wkr(lhs, rhs, TfdsEqListItmStr_cls_default.Instance, EmptyStr);}
public static void Eq_list(List_adp lhs, List_adp rhs, TfdsEqListItmStr xtoStr) {Eq_list_wkr(lhs, rhs, xtoStr, EmptyStr);}
private static void Eq_exec_y(Object lhs, Object rhs, String fmt, Object[] args) {
if (Object_.Eq(lhs, rhs)) return;
String msg = msgBldr.Eq_xtoStr(lhs, rhs, String_.Format(fmt, args));
throw Err_.new_wo_type(msg);
}
static void Eq_able_wkr(EqAble lhs, EqAble rhs, boolean expd, String customMsg) {
boolean actl = false;
if (lhs == null && rhs != null) actl = false;
else if (lhs != null && rhs == null) actl = false;
else actl = lhs.Eq(rhs);
if (expd == actl) return;
String msg = msgBldr.Eq_xtoStr(lhs, rhs, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_wkr(Object lhs, Object rhs, boolean expd, String customMsg) {
boolean actl = Object_.Eq(lhs, rhs);
if (expd == actl) return;
String msg = msgBldr.Eq_xtoStr(lhs, rhs, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_ary_wkr(Object lhsAry, Object rhsAry, boolean compareUsingEquals, String customMsg) {
List_adp list = List_adp_.new_(); boolean pass = true;
int lhsLen = Array_.Len(lhsAry), rhsLen = Array_.Len(rhsAry);
for (int i = 0; i < lhsLen; i++) {
Object lhs = Array_.Get_at(lhsAry, i);
Object rhs = i >= rhsLen ? "<<N/A>>" : Array_.Get_at(rhsAry, i);
String lhsString = msgBldr.Obj_xtoStr(lhs); String rhsString = msgBldr.Obj_xtoStr(rhs); // even if compareUsingEquals, method does ToStr on each itm for failMsg
boolean isEq = compareUsingEquals
? Object_.Eq(lhs, rhs)
: Object_.Eq(lhsString, rhsString);
Eq_ary_wkr_addItm(list, i, isEq, lhsString, rhsString);
if (!isEq) pass = false;
}
for (int i = lhsLen; i < rhsLen; i++) {
String lhsString = "<<N/A>>";
String rhsString = msgBldr.Obj_xtoStr(Array_.Get_at(rhsAry, i));
Eq_ary_wkr_addItm(list, i, false, lhsString, rhsString);
pass = false;
}
if (pass) return;
String msg = msgBldr.Eq_ary_xtoStr(list, lhsLen, rhsLen, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_list_wkr(List_adp lhsList, List_adp rhsList, TfdsEqListItmStr xtoStr, String customMsg) {
List_adp list = List_adp_.new_(); boolean pass = true;
int lhsLen = lhsList.Count(), rhsLen = rhsList.Count();
for (int i = 0; i < lhsLen; i++) {
Object lhs = lhsList.Get_at(i);
Object rhs = i >= rhsLen ? null : rhsList.Get_at(i);
String lhsStr = xtoStr.To_str(lhs, lhs);
String rhsStr = rhs == null ? "<<N/A>>" : xtoStr.To_str(rhs, lhs);
boolean isEq = Object_.Eq(lhsStr, rhsStr); if (!isEq) pass = false;
Eq_ary_wkr_addItm(list, i, isEq, lhsStr, rhsStr);
}
for (int i = lhsLen; i < rhsLen; i++) {
String lhsStr = "<<N/A>>";
Object rhs = rhsList.Get_at(i);
String rhsStr = xtoStr.To_str(rhs, null);
Eq_ary_wkr_addItm(list, i, false, lhsStr, rhsStr);
pass = false;
}
if (pass) return;
String msg = msgBldr.Eq_ary_xtoStr(list, lhsLen, rhsLen, customMsg);
throw Err_.new_wo_type(msg);
}
static void Eq_ary_wkr_addItm(List_adp list, int i, boolean isEq, String lhsString, String rhsString) {
TfdsEqAryItm itm = new TfdsEqAryItm().Idx_(i).Eq_(isEq).Lhs_(lhsString).Rhs_(rhsString);
list.Add(itm);
}
public static void Err_classMatch(Exception exc, Class<?> type) {
boolean match = Type_adp_.Eq_typeSafe(exc, type);
if (!match) throw Err_.new_("Tfds", "error types do not match", "expdType", Type_adp_.FullNameOf_type(type), "actlType", Type_adp_.NameOf_obj(exc), "actlMsg", Err_.Message_lang(exc));
}
public static void Eq_err(Err expd, Exception actlExc) {
Tfds.Eq(Err_.Message_gplx_full(expd), Err_.Message_gplx_full(actlExc));
}
public static void Err_has(Exception e, String hdr) {
Tfds.Eq_true(String_.Has(Err_.Message_gplx_full(e), hdr), "could not find '{0}' in '{1}'", hdr, Err_.Message_gplx_full(e));
}
static final String EmptyStr = TfdsMsgBldr.EmptyStr;
static TfdsMsgBldr msgBldr = TfdsMsgBldr.new_();
public static final Io_url RscDir = Io_url_.Usr().GenSubDir_nest("000", "200_dev", "190_tst");
public static DateAdp Now_time0_add_min(int minutes) {return time0.Add_minute(minutes);}
@gplx.Internal protected static boolean Now_enabled() {return now_enabled;} private static boolean now_enabled; private static boolean now_freeze;
public static void Now_enabled_n_() {now_enabled = false; now_freeze = false;}
public static void Now_set(DateAdp date) {now_enabled = true; nowTime = date;}
public static void Now_enabled_y_() {now_enabled = true; nowTime = time0;}
public static void Now_freeze_y_() {now_freeze = true;}
@gplx.Internal protected static DateAdp Now() {
DateAdp rv = nowTime;
if (!now_freeze) nowTime = rv.Add_minute(1);
return rv;
}
private static final DateAdp time0 = DateAdp_.parse_gplx("2001-01-01 00:00:00.000");
private static DateAdp nowTime; // NOTE: cannot set to time0 due to static initialization;
public static void WriteText(String text) {Console_adp__sys.Instance.Write_str(text);}
public static void Write(byte[] s, int b, int e) {Write(Bry_.Mid(s, b, e));}
public static void Write() {Write("tmp");}
public static void Write(Object... ary) {
String_bldr sb = String_bldr_.new_();
int aryLen = Array_.Len(ary);
for (int i = 0; i < aryLen; i++)
sb.Add_many("'", Object_.Xto_str_strict_or_null_mark(ary[i]), "'", " ");
WriteText(sb.To_str() + String_.CrLf);
}
}
class TfdsEqListItmStr_cls_default implements TfdsEqListItmStr {
public String To_str(Object cur, Object actl) {
return Object_.Xto_str_strict_or_null_mark(cur);
}
public static final TfdsEqListItmStr_cls_default Instance = new TfdsEqListItmStr_cls_default(); TfdsEqListItmStr_cls_default() {}
}
class TfdsEqAryItm {
public int Idx() {return idx;} public TfdsEqAryItm Idx_(int v) {idx = v; return this;} int idx;
public String Lhs() {return lhs;} public TfdsEqAryItm Lhs_(String v) {lhs = v; return this;} private String lhs;
public String Rhs() {return rhs;} public TfdsEqAryItm Rhs_(String v) {rhs = v; return this;} private String rhs;
public boolean Eq() {return eq;} public TfdsEqAryItm Eq_(boolean v) {eq = v; return this;} private boolean eq;
}
class TfdsMsgBldr {
public String Eq_xtoStr(Object expd, Object actl, String customMsg) {
String expdString = Obj_xtoStr(expd); String actlString = Obj_xtoStr(actl);
String detail = String_.Concat
( CustomMsg_xtoStr(customMsg)
, "\t\t", "expd: ", expdString, String_.CrLf
, "\t\t", "actl: ", actlString, String_.CrLf
);
return WrapMsg(detail);
}
public String Eq_ary_xtoStr(List_adp list, int lhsAryLen, int rhsAryLen, String customMsg) {
String_bldr sb = String_bldr_.new_();
sb.Add(CustomMsg_xtoStr(customMsg));
if (lhsAryLen != rhsAryLen)
sb.Add_fmt_line("{0}element counts differ: {1} {2}", "\t\t", lhsAryLen, rhsAryLen);
int lhsLenMax = 0, rhsLenMax = 0;
for (int i = 0; i < list.Count(); i++) {
TfdsEqAryItm itm = (TfdsEqAryItm)list.Get_at(i);
int lhsLen = String_.Len(itm.Lhs()), rhsLen = String_.Len(itm.Rhs());
if (lhsLen > lhsLenMax) lhsLenMax = lhsLen;
if (rhsLen > rhsLenMax) rhsLenMax = rhsLen;
}
for (int i = 0; i < list.Count(); i++) {
TfdsEqAryItm itm = (TfdsEqAryItm)list.Get_at(i);
sb.Add_fmt_line("{0}: {1} {2} {3}"
, Int_.To_str_pad_bgn_zero(itm.Idx(), 4)
, String_.PadBgn(itm.Lhs(), lhsLenMax, " ")
, itm.Eq() ? "==" : "!="
, String_.PadBgn(itm.Rhs(), rhsLenMax, " ")
);
}
// String compSym = isEq ? " " : "!=";
// String result = String_.Format("{0}: {1}{2} {3} {4}", Int_.To_str_pad_bgn_zero(i, 4), lhsString, String_.CrLf + "\t\t", compSym, rhsString);
// foreach (Object obj in list) {
// String itmComparison = (String)obj;
// sb.Add_fmt_line("{0}{1}", "\t\t", itmComparison);
// }
return WrapMsg(sb.To_str());
}
String CustomMsg_xtoStr(String customMsg) {
return (customMsg == EmptyStr)
? ""
: String_.Concat(customMsg, String_.CrLf);
}
public String Obj_xtoStr(Object obj) {
String s = String_.as_(obj);
if (s != null) return String_.Concat("'", s, "'"); // if Object is String, put quotes around it for legibility
To_str_able xtoStrAble = To_str_able_.as_(obj);
if (xtoStrAble != null) return xtoStrAble.To_str();
return Object_.Xto_str_strict_or_null_mark(obj);
}
String WrapMsg(String text) {
return String_.Concat(String_.CrLf
, "************************************************************************************************", String_.CrLf
, text
, "________________________________________________________________________________________________"
);
}
public static TfdsMsgBldr new_() {return new TfdsMsgBldr();} TfdsMsgBldr() {}
public static final String EmptyStr = "";
}

View 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;
public interface TfdsEqListItmStr {
String To_str(Object cur, Object actl);
}

View File

@@ -1,155 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys; import gplx.*; import gplx.core.*;
public class Bry_rdr {
public byte[] Src() {return src;} protected byte[] src;
public int Src_len() {return src_len;} protected int src_len;
public void Init(byte[] src) {this.Init(src, 0);}
public void Init(byte[] src, int pos) {
this.src = src; this.src_len = src.length; this.pos = pos;
}
public int Pos() {return pos;} public Bry_rdr Pos_(int v) {this.pos = v; return this;} protected int pos;
public void Pos_add(int v) {pos += v;}
public boolean Pos_is_eos() {return pos == src_len;}
public void Pos_add_one() {++pos;}
public int Or_int() {return or_int;} public void Or_int_(int v) {or_int = v;} private int or_int = Int_.Min_value;
public byte[] Or_bry() {return or_bry;} public void Or_bry_(byte[] v) {or_bry = v;} private byte[] or_bry;
public int Find_fwd(byte find) {return Bry_find_.Find_fwd(src, find, pos);}
public int Find_fwd_ws() {return Bry_find_.Find_fwd_until_ws(src, pos, src_len);}
public int Find_fwd__pos_at_lhs(byte[] find_bry) {return Find_fwd__pos_at(find_bry, Bool_.N);}
public int Find_fwd__pos_at_rhs(byte[] find_bry) {return Find_fwd__pos_at(find_bry, Bool_.Y);}
public int Find_fwd__pos_at(byte[] find_bry, boolean pos_at_rhs) {
int find_pos = Bry_find_.Find_fwd(src, find_bry, pos, src_len);
if (pos_at_rhs) find_pos += find_bry.length;
if (find_pos != Bry_find_.Not_found) pos = find_pos;
return find_pos;
}
public int Read_int_to_semic() {return Read_int_to(Byte_ascii.Semic);}
public int Read_int_to_comma() {return Read_int_to(Byte_ascii.Comma);}
public int Read_int_to_pipe() {return Read_int_to(Byte_ascii.Pipe);}
public int Read_int_to_nl() {return Read_int_to(Byte_ascii.Nl);}
public int Read_int_to_quote() {return Read_int_to(Byte_ascii.Quote);}
public int Read_int_to_non_num(){return Read_int_to(Byte_ascii.Null);}
public int Read_int_to(byte to_char) {
int bgn = pos;
int rv = 0;
int negative = 1;
while (pos < src_len) {
byte b = src[pos++];
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:
rv = (rv * 10) + (b - Byte_ascii.Num_0);
break;
case Byte_ascii.Dash:
if (negative == -1) // 2nd negative
return or_int; // return or_int
else // 1st negative
negative = -1; // flag negative
break;
default: {
boolean match = b == to_char;
if (to_char == Byte_ascii.Null) {// hack for Read_int_to_non_num
--pos;
match = true;
}
return match ? rv * negative : or_int;
}
}
}
return bgn == pos ? or_int : rv * negative;
}
public byte[] Read_bry_to_nl() {return Read_bry_to(Byte_ascii.Nl);}
public byte[] Read_bry_to_semic() {return Read_bry_to(Byte_ascii.Semic);}
public byte[] Read_bry_to_pipe() {return Read_bry_to(Byte_ascii.Pipe);}
public byte[] Read_bry_to_quote() {return Read_bry_to(Byte_ascii.Quote);}
public byte[] Read_bry_to_apos() {return Read_bry_to(Byte_ascii.Apos);}
public byte[] Read_bry_to(byte to_char) {
int bgn = pos;
while (pos < src_len) {
byte b = src[pos];
if (b == to_char)
return Bry_.Mid(src, bgn, pos++);
else
++pos;
}
return bgn == pos ? or_bry : Bry_.Mid(src, bgn, src_len);
}
public boolean Read_yn_to_pipe() {return Read_byte_to_pipe() == Byte_ascii.Ltr_y;}
public byte Read_byte_to_pipe() {
byte rv = src[pos];
pos += 2; // 1 for byte; 1 for pipe;
return rv;
}
public double Read_double_to_pipe() {return Read_double_to(Byte_ascii.Pipe);}
public double Read_double_to(byte to_char) {
byte[] double_bry = Read_bry_to(to_char);
return Double_.parse(String_.new_a7(double_bry)); // double will never have utf8
}
@gplx.Virtual public Bry_rdr Skip_ws() {
while (pos < src_len) {
switch (src[pos]) {
case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Space:
++pos;
break;
default:
return this;
}
}
return this;
}
public Bry_rdr Skip_alpha_num_under() {
while (pos < src_len) {
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:
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:
++pos;
break;
default:
return this;
}
}
return this;
}
public void Chk_bry_or_fail(byte[] bry) {
int bry_len = bry.length;
boolean match = Bry_.Match(src, pos, pos + bry_len, bry);
if (match) pos += bry_len;
else throw Err_.new_wo_type("bry.rdr:chk failed", "bry", bry, "pos", pos);
}
public void Chk_byte_or_fail(byte b) {
boolean match = pos < src_len ? src[pos] == b : false;
if (match) ++pos;
else throw Err_.new_wo_type("bry.rdr:chk failed", "byte", b, "pos", pos);
}
public byte[] Mid_by_len_safe(int len) {
int end = pos + len; if (end > src_len) end = src_len;
return Bry_.Mid(src, pos, end);
}
}

View File

@@ -48,6 +48,7 @@ public class Btrie_slim_mgr implements Btrie_mgr {
public Btrie_slim_mgr Add_bry(String key, String val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), Bry_.new_u8(val));}
public Btrie_slim_mgr Add_bry(String key, byte[] val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), val);}
public Btrie_slim_mgr Add_bry(byte[] v) {return (Btrie_slim_mgr)Add_obj(v, v);}
public Btrie_slim_mgr Add_str_str(String key, String val) {return (Btrie_slim_mgr)Add_obj(Bry_.new_u8(key), Bry_.new_u8(val));}
public Btrie_slim_mgr Add_bry_bry(byte[] key, byte[] val) {return (Btrie_slim_mgr)Add_obj(key, val);}
public Btrie_slim_mgr Add_bry_byte(byte b, byte val) {return (Btrie_slim_mgr)Add_obj(new byte[] {b}, Byte_obj_val.new_(val));}
public Btrie_slim_mgr Add_bry_byte(byte[] bry, byte val) {return (Btrie_slim_mgr)Add_obj(bry, Byte_obj_val.new_(val));}

View File

@@ -40,7 +40,7 @@ class Btrie_u8_itm {
else { // itm has asymmetric_bry; EX: "İ" was added to trie, must match "İ" and "i";
if (called_by_match) { // called by mgr.Match
return
( Bry_.Eq(src, c_bgn, c_end, rv.key) // key matches src; EX: "aİ"
( Bry_.Eq(src, c_bgn, c_end, rv.key) // key matches src; EX: "aİ"
|| Bry_.Eq(src, c_bgn, c_end, rv.asymmetric_bry) // asymmetric_bry matches src; EX: "ai"; note that "aI" won't match
)
? rv : null;

View File

@@ -16,7 +16,7 @@ You should have 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.criterias; import gplx.*; import gplx.core.*;
import gplx.texts.*; /*RegxPatn_cls_like*/
import gplx.core.texts.*; /*RegxPatn_cls_like*/
public class Criteria_ {
public static final Criteria All = new Criteria_const(true);
public static final Criteria None = new Criteria_const(false);

View File

@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.criterias; import gplx.*; import gplx.core.*;
import org.junit.*;
import gplx.ios.*;
import gplx.core.ios.*;
public class Criteria_ioItm_tst {
IoItmFil fil; Criteria crt; IoItm_fxt fx = IoItm_fxt.new_();
@Test public void IoType() {

View File

@@ -16,7 +16,7 @@ You should have 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.criterias; import gplx.*; import gplx.core.*;
import gplx.texts.*;
import gplx.core.texts.*;
public class Criteria_ioMatch implements Criteria { // EX: url IOMATCH '*.xml|*.txt'
public Criteria_ioMatch(boolean match, RegxPatn_cls_ioMatch pattern) {this.match = match; this.pattern = pattern;}
public byte Tid() {return Criteria_.Tid_iomatch;}

View File

@@ -16,7 +16,7 @@ You should have 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.criterias; import gplx.*; import gplx.core.*;
import gplx.texts.*; /*RegxPatn_cls_like*/
import gplx.core.texts.*; /*RegxPatn_cls_like*/
public class Criteria_like implements Criteria {
@gplx.Internal protected Criteria_like(boolean negated, RegxPatn_cls_like pattern) {
this.negated = negated; this.pattern = pattern;

View 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.core.encoders; import gplx.*; import gplx.core.*;
public class Base85_ {
public static String To_str(int val, int min_len) {return String_.new_u8(Set_bry(val, null, 0, min_len));}
public static byte[] To_bry(int val, int min_len) {return Set_bry(val, null, 0, min_len);}
public static byte[] Set_bry(int val, byte[] ary, int ary_pos, int min_len) {
int val_len = Bry_len(val);
int ary_len = val_len, pad_len = 0;
boolean pad = ary_len < min_len;
if (pad) {
pad_len = min_len - ary_len;
ary_len = min_len;
}
if (ary == null) ary = new byte[ary_len];
if (pad) {
for (int i = 0; i < pad_len; i++) // fill ary with pad_len
ary[i + ary_pos] = A7_offset;
}
for (int i = ary_len - pad_len; i > 0; i--) {
int div = Pow85[i - 1];
byte tmp = (byte)(val / div);
ary[ary_pos + ary_len - i] = (byte)(tmp + A7_offset);
val -= tmp * div;
}
return ary;
}
public static int To_int_by_str(String s) {
byte[] ary = Bry_.new_u8(s);
return To_int_by_bry(ary, 0, ary.length - 1);
}
public static int To_int_by_bry(byte[] ary, int bgn, int end) {
int rv = 0, factor = 1;
for (int i = end; i >= bgn; i--) {
rv += (ary[i] - A7_offset) * factor;
factor *= Radix;
}
return rv;
}
public static int Bry_len(int v) {
if (v == 0) return 1;
for (int i = Pow85_last; i > -1; i--)
if (v >= Pow85[i]) return i + 1;
throw Err_.new_wo_type("neg number not allowed", "v", v);
}
public static final int Len_int = 5;
private static final int Pow85_last = 4, Radix = 85; private static final byte A7_offset = 33;
public static final int Pow85_0 = 1, Pow85_1 = 85, Pow85_2 = 7225, Pow85_3 = 614125, Pow85_4 = 52200625;
public static int[] Pow85 = new int[]{Pow85_0, Pow85_1, Pow85_2, Pow85_3, Pow85_4}; // NOTE: ary constructed to match index to exponent; Pow85[1] = 85^1
}

View File

@@ -0,0 +1,61 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.encoders; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Base85__tst {
private final Base85__fxt fxt = new Base85__fxt();
@Test public void Log() {
fxt.Test_log( 0, 1);
fxt.Test_log( 84, 1);
fxt.Test_log( 85, 2);
fxt.Test_log( 7224, 2);
fxt.Test_log( 7225, 3);
fxt.Test_log( 614124, 3);
fxt.Test_log( 614125, 4);
fxt.Test_log( 52200624, 4);
fxt.Test_log( 52200625, 5);
fxt.Test_log(Int_.Max_value, 5);
}
@Test public void To_str() {
fxt.Test_to_str( 0, "!");
fxt.Test_to_str( 84, "u");
fxt.Test_to_str( 85, "\"!");
fxt.Test_to_str( 7224, "uu");
fxt.Test_to_str( 7225, "\"!!");
fxt.Test_to_str( 614124, "uuu");
fxt.Test_to_str( 614125, "\"!!!");
fxt.Test_to_str( 52200624, "uuuu");
fxt.Test_to_str( 52200625, "\"!!!!");
}
@Test public void XtoStrAry() {
byte[] ary = new byte[9];
fxt.Exec_to_str(ary, 0, 2); // !!#
fxt.Exec_to_str(ary, 3, 173); // !#$
fxt.Exec_to_str(ary, 6, 14709); // #$%
Tfds.Eq("!!#!#$#$%", String_.new_u8(ary));
}
}
class Base85__fxt {
public void Test_log(int val, int expd) {Tfds.Eq(expd, Base85_.Bry_len(val));}
public void Test_to_str(int val, String expd) {
String actl = Base85_.To_str(val, 0);
Tfds.Eq(expd, actl);
Tfds.Eq(val, Base85_.To_int_by_str(expd));
}
public void Exec_to_str(byte[] ary, int aryPos, int val) {Base85_.Set_bry(val, ary, aryPos, 3);}
}

View File

@@ -53,7 +53,7 @@ public class Utf16_ {
public static byte[] Encode_hex_to_bry(String raw) {return Encode_hex_to_bry(Bry_.new_a7(raw));}
public static byte[] Encode_hex_to_bry(byte[] raw) {
if (raw == null) return null;
int int_val = gplx.texts.HexDecUtl.parse_or(raw, Int_.Min_value);
int int_val = gplx.core.texts.HexDecUtl.parse_or(raw, Int_.Min_value);
return int_val == Int_.Min_value ? null : Encode_int_to_bry(int_val);
}
public static byte[] Encode_int_to_bry(int c) {

View File

@@ -0,0 +1,154 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.consoles.*; import gplx.core.criterias.*;
public interface IoEngine {
String Key();
boolean ExistsFil_api(Io_url url);
void SaveFilText_api(IoEngine_xrg_saveFilStr args);
String LoadFilStr(IoEngine_xrg_loadFilStr args);
void DeleteFil_api(IoEngine_xrg_deleteFil args);
void CopyFil(IoEngine_xrg_xferFil args);
void MoveFil(IoEngine_xrg_xferFil args);
IoItmFil QueryFil(Io_url url);
void UpdateFilAttrib(Io_url url, IoItmAttrib atr); // will fail if file does not exists
void UpdateFilModifiedTime(Io_url url, DateAdp modified);
IoStream OpenStreamRead(Io_url url);
IoStream OpenStreamWrite(IoEngine_xrg_openWrite args);
void XferFil(IoEngine_xrg_xferFil args);
void RecycleFil(IoEngine_xrg_recycleFil xrg);
boolean ExistsDir(Io_url url);
void CreateDir(Io_url url); // creates all folder levels (EX: C:\a\b\c\ will create C:\a\ and C:\a\b\). will not fail if called on already existing folders.
void DeleteDir(Io_url url);
void MoveDir(Io_url src, Io_url trg); // will fail if trg exists
void CopyDir(Io_url src, Io_url trg);
IoItmDir QueryDir(Io_url url);
void DeleteDirDeep(IoEngine_xrg_deleteDir args);
void MoveDirDeep(IoEngine_xrg_xferDir args); // will fail if trg exists
IoItmDir QueryDirDeep(IoEngine_xrg_queryDir args);
void XferDir(IoEngine_xrg_xferDir args);
boolean DownloadFil(IoEngine_xrg_downloadFil xrg);
Io_stream_rdr DownloadFil_as_rdr(IoEngine_xrg_downloadFil xrg);
}
class IoEngineUtl {
public int BufferLength() {return bufferLength;} public void BufferLength_set(int v) {bufferLength = v;} int bufferLength = 4096; // 0x1000
public void DeleteRecycleGplx(IoEngine engine, IoEngine_xrg_recycleFil xrg) {
Io_url recycleUrl = xrg.RecycleUrl();
if (recycleUrl.Type_fil())
engine.MoveFil(IoEngine_xrg_xferFil.move_(xrg.Url(), recycleUrl).Overwrite_(false).ReadOnlyFails_(true));
else
engine.MoveDirDeep(IoEngine_xrg_xferDir.move_(xrg.Url(), recycleUrl).Overwrite_(false).ReadOnlyFails_(true));
}
public void DeleteDirDeep(IoEngine engine, Io_url dirUrl, IoEngine_xrg_deleteDir args) {
Console_adp usrDlg = args.UsrDlg();
IoItmDir dir = engine.QueryDir(dirUrl); if (!dir.Exists()) return;
for (Object subDirObj : dir.SubDirs()) {
IoItmDir subDir = (IoItmDir)subDirObj;
if (!args.SubDirScanCrt().Matches(subDir)) continue;
if (args.Recur()) DeleteDirDeep(engine, subDir.Url(), args);
}
for (Object subFilObj : dir.SubFils()) {
IoItmFil subFil = (IoItmFil)subFilObj;
if (!args.MatchCrt().Matches(subFil)) continue;
Io_url subFilUrl = subFil.Url();
try {engine.DeleteFil_api(IoEngine_xrg_deleteFil.new_(subFilUrl).ReadOnlyFails_(args.ReadOnlyFails()));}
catch (Exception exc) {usrDlg.Write_fmt_w_nl(Err_.Message_lang(exc));}
}
// all subs deleted; now delete dir
if (!args.MatchCrt().Matches(dir)) return;
try {engine.DeleteDir(dir.Url());}
catch (Exception exc) {usrDlg.Write_fmt_w_nl(Err_.Message_lang(exc));}
}
public void XferDir(IoEngine srcEngine, Io_url src, IoEngine trgEngine, Io_url trg, IoEngine_xrg_xferDir args) {
trgEngine.CreateDir(trg);
IoItmDir srcDir = QueryDirDeep(srcEngine, IoEngine_xrg_queryDir.new_(src).Recur_(false));
for (Object subSrcObj : srcDir.SubDirs()) {
IoItmDir subSrc = (IoItmDir)subSrcObj;
if (!args.SubDirScanCrt().Matches(subSrc)) continue;
if (!args.MatchCrt().Matches(subSrc)) continue;
Io_url subTrg = trg.GenSubDir_nest(subSrc.Url().NameOnly()); //EX: C:\abc\def\ -> C:\123\ + def\
if (args.Recur()) XferDir(srcEngine, subSrc.Url(), trgEngine, subTrg, args);
}
IoItmList srcFils = IoItmList.list_(src.Info().CaseSensitive());
for (Object srcFilObj : srcDir.SubFils()) {
IoItmFil srcFil = (IoItmFil)srcFilObj;
if (args.MatchCrt().Matches(srcFil)) srcFils.Add(srcFil);
}
for (Object srcFilObj : srcFils) {
IoItmFil srcFil = (IoItmFil)srcFilObj;
Io_url srcFilPath = srcFil.Url();
Io_url trgFilPath = trg.GenSubFil(srcFilPath.NameAndExt()); //EX: C:\abc\fil.txt -> C:\123\ + fil.txt
IoEngine_xrg_xferFil xferArgs = args.Type_move() ? IoEngine_xrg_xferFil.move_(srcFilPath, trgFilPath).Overwrite_(args.Overwrite()) : IoEngine_xrg_xferFil.copy_(srcFilPath, trgFilPath).Overwrite_(args.Overwrite());
XferFil(srcEngine, xferArgs);
}
if (args.Type_move()) srcEngine.DeleteDirDeep(IoEngine_xrg_deleteDir.new_(src).Recur_(args.Recur()).ReadOnlyFails_(args.ReadOnlyFails()));// this.DeleteDirDeep(srcEngine, src, IoEngine_xrg_deleteItm.new_(src).Recur_(args.Recur()).ReadOnlyIgnored_(args.ReadOnlyIgnored()));
}
public void XferFil(IoEngine srcEngine, IoEngine_xrg_xferFil args) {
Io_url src = args.Src(), trg = args.Trg();
if (String_.Eq(srcEngine.Key(), trg.Info().EngineKey())) {
if (args.Type_move())
srcEngine.MoveFil(args);
else
srcEngine.CopyFil(args);
}
else {
TransferStream(src, trg);
if (args.Type_move()) srcEngine.DeleteFil_api(IoEngine_xrg_deleteFil.new_(src));
}
}
public IoItmDir QueryDirDeep(IoEngine engine, IoEngine_xrg_queryDir args) {
IoItmDir rv = IoItmDir_.top_(args.Url());
rv.Exists_set(QueryDirDeepCore(rv, args.Url(), engine, args.Recur(), args.SubDirScanCrt(), args.DirCrt(), args.FilCrt(), args.UsrDlg(), args.DirInclude()));
return rv;
}
static boolean QueryDirDeepCore(IoItmDir ownerDir, Io_url url, IoEngine engine, boolean recur, Criteria subDirScanCrt, Criteria dirCrt, Criteria filCrt, Console_adp usrDlg, boolean dirInclude) {
if (usrDlg.Canceled_chk()) return false;
if (usrDlg.Enabled()) usrDlg.Write_tmp(String_.Concat("scan: ", url.Raw()));
IoItmDir scanDir = engine.QueryDir(url);
for (Object subDirObj : scanDir.SubDirs()) {
IoItmDir subDir = (IoItmDir)subDirObj;
if (!subDirScanCrt.Matches(subDir)) continue;
if (dirCrt.Matches(subDir)) {
ownerDir.SubDirs().Add(subDir); // NOTE: always add subDir; do not use dirCrt here, else its subFils will be added to non-existent subDir
}
if (recur)
QueryDirDeepCore(subDir, subDir.Url(), engine, recur, subDirScanCrt, dirCrt, filCrt, usrDlg, dirInclude);
}
for (Object subFilObj : scanDir.SubFils()) {
IoItmFil subFil = (IoItmFil)subFilObj;
if (filCrt.Matches(subFil)) ownerDir.SubFils().Add(subFil);
}
return scanDir.Exists();
}
void TransferStream(Io_url src, Io_url trg) {
IoStream srcStream = null;
IoStream trgStream = null;
try {
srcStream = IoEnginePool.Instance.Get_by(src.Info().EngineKey()).OpenStreamRead(src);
trgStream = IoEngine_xrg_openWrite.new_(trg).Exec();
srcStream.Transfer(trgStream, bufferLength);
}
finally {
if (srcStream != null) srcStream.Rls();
if (trgStream != null) trgStream.Rls();
}
}
public static IoEngineUtl new_() {return new IoEngineUtl();} IoEngineUtl() {}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEnginePool {
private final Hash_adp hash = Hash_adp_.new_();
public void Add_if_dupe_use_nth(IoEngine engine) {
hash.Del(engine.Key());
hash.Add(engine.Key(), engine);
}
public IoEngine Get_by(String key) {
IoEngine rv = (IoEngine)hash.Get_by(key);
return rv == null ? IoEngine_.Mem : rv; // rv == null when url is null or empty; return Mem which should be a noop; DATE:2013-06-04
}
public static final IoEnginePool Instance = new IoEnginePool();
IoEnginePool() {
this.Add_if_dupe_use_nth(IoEngine_.Sys);
this.Add_if_dupe_use_nth(IoEngine_.Mem);
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_ {
public static final String SysKey = "sys";
public static final String MemKey = "mem";
public static final IoEngine Sys = IoEngine_system.new_();
public static final IoEngine_memory Mem = IoEngine_memory.new_(MemKey);
public static IoEngine Mem_init_() {
Mem.Clear();
return Mem;
}
public static IoEngine mem_new_(String key) {return IoEngine_memory.new_(key);}
}

View File

@@ -0,0 +1,57 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public abstract class IoEngine_base implements IoEngine {
public abstract String Key();
public abstract boolean ExistsFil_api(Io_url url);
public abstract void SaveFilText_api(IoEngine_xrg_saveFilStr args);
public abstract String LoadFilStr(IoEngine_xrg_loadFilStr args);
public abstract void DeleteFil_api(IoEngine_xrg_deleteFil args);
public abstract void CopyFil(IoEngine_xrg_xferFil args);
public abstract void MoveFil(IoEngine_xrg_xferFil args);
public abstract IoItmFil QueryFil(Io_url url);
public abstract void UpdateFilAttrib(Io_url url, IoItmAttrib atr); // will fail if file does not exists
public abstract void UpdateFilModifiedTime(Io_url url, DateAdp modified);
public abstract IoStream OpenStreamRead(Io_url url);
public abstract IoStream OpenStreamWrite(IoEngine_xrg_openWrite args);
public abstract void XferFil(IoEngine_xrg_xferFil args);
public abstract boolean ExistsDir(Io_url url);
public abstract void CreateDir(Io_url url); // creates all folder levels (EX: C:\a\b\c\ will create C:\a\ and C:\a\b\). will not fail if called on already existing folders.
public abstract void DeleteDir(Io_url url);
public abstract void MoveDir(Io_url src, Io_url trg); // will fail if trg exists
public abstract void CopyDir(Io_url src, Io_url trg);
public abstract IoItmDir QueryDir(Io_url url);
public abstract void DeleteDirDeep(IoEngine_xrg_deleteDir args);
public abstract void MoveDirDeep(IoEngine_xrg_xferDir args); // will fail if trg exists
public abstract IoItmDir QueryDirDeep(IoEngine_xrg_queryDir args);
public abstract void XferDir(IoEngine_xrg_xferDir args);
public abstract boolean DownloadFil(IoEngine_xrg_downloadFil xrg);
public abstract Io_stream_rdr DownloadFil_as_rdr(IoEngine_xrg_downloadFil xrg);
public void RecycleFil(IoEngine_xrg_recycleFil xrg) {
Io_url recycleUrl = xrg.RecycleUrl();
if (recycleUrl.Type_fil()) {
this.MoveFil(IoEngine_xrg_xferFil.move_(xrg.Url(), recycleUrl).Overwrite_(false).ReadOnlyFails_(true).MissingFails_(xrg.MissingFails()));
IoRecycleBin.Instance.Regy_add(xrg);
}
else
this.MoveDirDeep(IoEngine_xrg_xferDir.move_(xrg.Url(), recycleUrl).Overwrite_(false).ReadOnlyFails_(true));
}
}

View File

@@ -0,0 +1,200 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_memory extends IoEngine_base {
@Override public String Key() {return key;} private String key = IoEngine_.MemKey;
@Override public boolean ExistsFil_api(Io_url url) {return FetchFil(url) != IoItmFil_mem.Null;}
@Override public void DeleteFil_api(IoEngine_xrg_deleteFil args) {
Io_url url = args.Url();
IoItmDir dir = FetchDir(url.OwnerDir()); if (dir == null) return; // url doesn't exist; just exit
IoItmFil fil = IoItmFil_.as_(dir.SubFils().Get_by(url.NameAndExt()));
if (fil != null && fil.ReadOnly() && args.ReadOnlyFails()) throw IoErr.FileIsReadOnly(url);
dir.SubFils().Del(url);
}
void DeleteFil(Io_url url) {DeleteFil_api(IoEngine_xrg_deleteFil.new_(url));}
@Override public void XferFil(IoEngine_xrg_xferFil args) {utl.XferFil(this, args);}
@Override public void MoveFil(IoEngine_xrg_xferFil args) {
Io_url src = args.Src(), trg = args.Trg(); boolean overwrite = args.Overwrite();
if (String_.Eq(src.Xto_api(), trg.Xto_api())) throw Err_.new_wo_type("move failed; src is same as trg", "raw", src.Raw());
CheckTransferArgs("move", src, trg, overwrite);
if (overwrite) DeleteFil(trg);
IoItmFil_mem curFil = FetchFil(src); curFil.Name_(trg.NameAndExt());
AddFilToDir(trg.OwnerDir(), curFil);
DeleteFil(src);
}
@Override public void CopyFil(IoEngine_xrg_xferFil args) {
Io_url src = args.Src(), trg = args.Trg(); boolean overwrite = args.Overwrite();
CheckTransferArgs("copy", src, trg, overwrite);
if (overwrite) DeleteFil(trg);
IoItmFil_mem srcFil = FetchFil(src);
IoItmFil_mem curFil = srcFil.Clone(); curFil.Name_(trg.NameAndExt());
AddFilToDir(trg.OwnerDir(), curFil);
}
@Override public IoItmDir QueryDirDeep(IoEngine_xrg_queryDir args) {return utl.QueryDirDeep(this, args);}
@Override public void UpdateFilAttrib(Io_url url, IoItmAttrib atr) {FetchFil(url).ReadOnly_(atr.ReadOnly());}
@Override public void UpdateFilModifiedTime(Io_url url, DateAdp modified) {FetchFil(url).ModifiedTime_(modified);}
@Override public IoItmFil QueryFil(Io_url url) {return FetchFil(url);}
@Override public void SaveFilText_api(IoEngine_xrg_saveFilStr args) {
Io_url url = args.Url();
IoItmDir dir = FetchDir(url.OwnerDir());
if (dir != null) {
IoItmFil fil = IoItmFil_.as_(dir.SubFils().Get_by(url.NameAndExt()));
if (fil != null && fil.ReadOnly()) throw IoErr.FileIsReadOnly(url);
}
if (args.Append())
AppendFilStr(args);
else
SaveFilStr(args.Url(), args.Text());
}
@Override public String LoadFilStr(IoEngine_xrg_loadFilStr args) {
return FetchFil(args.Url()).Text();
}
void SaveFilStr(Io_url url, String text) {
DateAdp time = DateAdp_.Now();
IoItmFil_mem fil = IoItmFil_mem.new_(url, String_.Len(text), time, text);
AddFilToDir(url.OwnerDir(), fil);
}
void AppendFilStr(IoEngine_xrg_saveFilStr args) {
Io_url url = args.Url(); String text = args.Text();
if (ExistsFil_api(url)) {
IoItmFil_mem fil = FetchFil(url);
fil.ModifiedTime_(DateAdp_.Now());
fil.Text_set(fil.Text() + text);
}
else
SaveFilStr(args.Url(), args.Text());
}
@Override public IoStream OpenStreamRead(Io_url url) {
IoItmFil_mem fil = FetchFil(url);
fil.Stream().Position_set(0);
return fil.Stream();
}
@Override public IoStream OpenStreamWrite(IoEngine_xrg_openWrite args) {
Io_url url = args.Url();
IoItmFil_mem fil = FetchFil(url);
if (fil == IoItmFil_mem.Null) { // file doesn't exist; create new one
SaveFilStr(url, "");
fil = FetchFil(url);
}
else {
if (args.Mode() == IoStream_.Mode_wtr_create)
fil.Text_set(""); // NOTE: clear text b/c it still has pointer to existing stream
}
return fil.Stream();
}
@Override public boolean ExistsDir(Io_url url) {return FetchDir(url) != null;}
@Override public void CreateDir(Io_url url) {
IoItmDir dir = FetchDir(url); if (dir != null) return; // dir exists; exit
dir = IoItmDir_.top_(url);
dirs.Add(dir);
IoItmDir ownerDir = FetchDir(url.OwnerDir());
if (ownerDir == null && !url.OwnerDir().Eq(Io_url_.Empty)) { // no owner dir && not "driveDir" -> create
CreateDir(url.OwnerDir()); // recursive
ownerDir = FetchDir(url.OwnerDir());
}
if (ownerDir != null)
ownerDir.SubDirs().Add(dir);
}
@Override public void DeleteDir(Io_url url) {
FetchDir(url); // force creation if exists?
dirs.Del(url);
IoItmDir ownerDir = FetchDir(url.OwnerDir()); if (ownerDir == null) return; // no ownerDir; no need to unregister
ownerDir.SubDirs().Del(url);
}
@Override public void XferDir(IoEngine_xrg_xferDir args) {Io_url trg = args.Trg(); utl.XferDir(this, args.Src(), IoEnginePool.Instance.Get_by(trg.Info().EngineKey()), trg, args);}
@Override public void MoveDirDeep(IoEngine_xrg_xferDir args) {Io_url trg = args.Trg(); utl.XferDir(this, args.Src(), IoEnginePool.Instance.Get_by(trg.Info().EngineKey()), trg, args);}
@Override public void MoveDir(Io_url src, Io_url trg) {if (ExistsDir(trg)) throw Err_.new_wo_type("trg already exists", "trg", trg);
IoItmDir dir = FetchDir(src); dir.Name_(trg.NameAndExt());
for (Object filObj : dir.SubFils()) { // move all subFiles
IoItmFil fil = (IoItmFil)filObj;
fil.OwnerDir_set(dir);
}
dirs.Add(dir);
DeleteDir(src);
}
@Override public IoItmDir QueryDir(Io_url url) {
IoItmDir dir = FetchDir(url);
IoItmDir rv = IoItmDir_.top_(url); // always return copy b/c caller may add/del itms directly
if (dir == null) {
rv.Exists_set(false);
return rv;
}
for (Object subDirObj : dir.SubDirs()) {
IoItmDir subDir = (IoItmDir)subDirObj;
rv.SubDirs().Add(IoItmDir_.scan_(subDir.Url()));
}
for (Object subFilObj : dir.SubFils()) {
IoItmFil subFil = (IoItmFil)subFilObj;
rv.SubFils().Add(subFil);
}
return rv;
}
@Override public void DeleteDirDeep(IoEngine_xrg_deleteDir args) {utl.DeleteDirDeep(this, args.Url(), args);}
@Override public void CopyDir(Io_url src, Io_url trg) {
IoEngine_xrg_xferDir.copy_(src, trg).Recur_().Exec();
}
void AddFilToDir(Io_url dirPath, IoItmFil fil) {
IoItmDir dir = FetchDir(dirPath);
if (dir == null) {
CreateDir(dirPath);
dir = FetchDir(dirPath);
}
dir.SubFils().Del(fil.Url());
dir.SubFils().Add(fil);
}
IoItmDir FetchDir(Io_url url) {return IoItmDir_.as_(dirs.Get_by(url));}
IoItmFil_mem FetchFil(Io_url url) {
IoItmDir ownerDir = FetchDir(url.OwnerDir());
if (ownerDir == null) return IoItmFil_mem.Null;
IoItmFil_mem rv = IoItmFil_mem.as_(ownerDir.SubFils().Get_by(url.NameAndExt()));
if (rv == null) rv = IoItmFil_mem.Null;
return rv;
}
void CheckTransferArgs(String op, Io_url src, Io_url trg, boolean overwrite) {
if (!ExistsFil_api(src)) throw Err_.new_wo_type("src does not exist", "src", src);
if (ExistsFil_api(trg) && !overwrite) throw Err_.new_invalid_op("trg already exists").Args_add("op", op, "overwrite", false, "src", src, "trg", trg);
}
public void Clear() {dirs.Clear();}
@Override public boolean DownloadFil(IoEngine_xrg_downloadFil xrg) {
Io_url src = Io_url_.mem_fil_(xrg.Src());
if (!ExistsFil_api(src)) {
xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_file_not_found);
return false;
}
XferFil(IoEngine_xrg_xferFil.copy_(src, xrg.Trg()).Overwrite_());
return true;
}
@Override public Io_stream_rdr DownloadFil_as_rdr(IoEngine_xrg_downloadFil xrg) {
Io_url src = Io_url_.mem_fil_(xrg.Src());
if (!ExistsFil_api(src)) {
xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_file_not_found);
return Io_stream_rdr_.Noop;
}
byte[] bry = Bry_.new_u8(FetchFil(Io_url_.mem_fil_(xrg.Src())).Text());
return Io_stream_rdr_.mem_(bry);
}
IoItmHash dirs = IoItmHash.new_();
IoEngineUtl utl = IoEngineUtl.new_();
@gplx.Internal protected static IoEngine_memory new_(String key) {
IoEngine_memory rv = new IoEngine_memory();
rv.key = key;
return rv;
} IoEngine_memory() {}
}

View File

@@ -0,0 +1,636 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.*;
import java.nio.channels.*;
import java.util.Date;
import javax.print.FlavorException;
import javax.tools.JavaCompiler;
import gplx.core.criterias.*;
public class IoEngine_system extends IoEngine_base {
@Override public String Key() {return IoEngine_.SysKey;}
@Override public void DeleteDirDeep(IoEngine_xrg_deleteDir args) {utl.DeleteDirDeep(this, args.Url(), args);}
@Override public void XferDir(IoEngine_xrg_xferDir args) {Io_url trg = args.Trg(); utl.XferDir(this, args.Src(), IoEnginePool.Instance.Get_by(trg.Info().EngineKey()), trg, args);}
@Override public void XferFil(IoEngine_xrg_xferFil args) {utl.XferFil(this, args);}
@Override public IoItmDir QueryDirDeep(IoEngine_xrg_queryDir args) {return utl.QueryDirDeep(this, args);}
@Override public void CopyDir(Io_url src, Io_url trg) {IoEngine_xrg_xferDir.copy_(src, trg).Recur_().Exec();}
@Override public void MoveDirDeep(IoEngine_xrg_xferDir args) {Io_url trg = args.Trg(); utl.XferDir(this, args.Src(), IoEnginePool.Instance.Get_by(trg.Info().EngineKey()), trg, args);}
@Override public void DeleteFil_api(IoEngine_xrg_deleteFil args) {
Io_url url = args.Url();
File fil = Fil_(url);
if (!Fil_Exists(fil)) return;
MarkFileWritable(fil, url, args.ReadOnlyFails(), "DeleteFile");
DeleteFil_lang(fil, url);
}
@Override public boolean ExistsFil_api(Io_url url) {
File f = new File(url.Xto_api());
return f.exists();
}
@Override public void SaveFilText_api(IoEngine_xrg_saveFilStr mpo) {
Io_url url = mpo.Url();
// encode string
byte[] textBytes = null;
textBytes = Bry_.new_u8(mpo.Text());
FileChannel fc = null; FileOutputStream fos = null;
if (!ExistsDir(url.OwnerDir())) CreateDir(url.OwnerDir());
try {
// open file
try {fos = new FileOutputStream(url.Xto_api(), mpo.Append());}
catch (FileNotFoundException e) {throw Err_Fil_NotFound(e, url);}
fc = fos.getChannel();
// write text
try {fc.write(ByteBuffer.wrap(textBytes));}
catch (IOException e) {
Closeable_close(fc, url, false);
Closeable_close(fos, url, false);
throw Err_.new_exc(e, "io", "write data to file failed", "url", url.Xto_api());
}
if (!Op_sys.Cur().Tid_is_drd()) {
File fil = new File(url.Xto_api());
IoEngine_system_xtn.SetExecutable(fil, true);
}
}
finally {
// cleanup
Closeable_close(fc, url, false);
Closeable_close(fos, url, false);
}
}
@Override public String LoadFilStr(IoEngine_xrg_loadFilStr args) {
Io_url url = args.Url(); String url_str = url.Xto_api();
boolean file_exists = ExistsFil_api(url); // check if file exists first to avoid throwing exception; note that most callers pass Missing_ignored; DATE:2015-02-24
if (!file_exists) {
if (args.MissingIgnored()) return "";
else throw Err_Fil_NotFound(url);
}
// get reader for file
InputStream stream = null;
try {stream = new FileInputStream(url_str);}
catch (FileNotFoundException e) {
if (args.MissingIgnored()) return "";
throw Err_Fil_NotFound(e, url);
}
return Load_from_stream_as_str(stream, url_str);
}
@SuppressWarnings("resource") public static String Load_from_stream_as_str(InputStream stream, String url_str) {
InputStreamReader reader = null;
try {reader = new InputStreamReader(stream, IoEngineArgs.Instance.LoadFilStr_Encoding);}
catch (UnsupportedEncodingException e) {
Closeable_close(stream, url_str, false);
throw Err_text_unsupported_encoding(IoEngineArgs.Instance.LoadFilStr_Encoding, "", url_str, e);
}
// make other objects
char[] readerBuffer = new char[IoEngineArgs.Instance.LoadFilStr_BufferSize];
int pos = 0;
StringWriter sw = new StringWriter();
// transfer data
while (true) {
try {pos = reader.read(readerBuffer);}
catch (IOException e) {
try {
stream.close();
reader.close();
}
catch (IOException e2) {}
throw Err_.new_exc(e, "io", "read data from file failed", "url", url_str, "pos", pos);
}
if (pos == -1) break;
sw.write(readerBuffer, 0, pos);
}
// cleanup
Closeable_close(stream, url_str, false);
Closeable_close(reader, url_str, false);
return sw.toString();
}
@Override public boolean ExistsDir(Io_url url) {return new File(url.Xto_api()).exists();}
@Override public void CreateDir(Io_url url) {new File(url.Xto_api()).mkdirs();}
@Override public void DeleteDir(Io_url url) {
File dir = new File(url.Xto_api());
if (!dir.exists()) return;
boolean rv = dir.delete();
if (!rv) throw Err_.new_(IoEngineArgs.Instance.Err_IoException, "delete dir failed", "url", url.Xto_api());
}
@Override public IoItmDir QueryDir(Io_url url) {
IoItmDir rv = IoItmDir_.scan_(url);
File dirInfo = new File(url.Xto_api());
if (!dirInfo.exists()) {
rv.Exists_set(false);
return rv;
}
IoUrlInfo urlInfo = url.Info();
File[] subItmAry = dirInfo.listFiles();
if (subItmAry == null) return rv; // directory has no files
for (int i = 0; i < subItmAry.length; i++) {
File subItm = subItmAry[i];
if (subItm.isFile()) {
IoItmFil subFil = QueryMkr_fil(urlInfo, subItm);
rv.SubFils().Add(subFil);
}
else {
IoItmDir subDir = QueryMkr_dir(urlInfo, subItm);
rv.SubDirs().Add(subDir);
}
}
return rv;
}
IoItmFil QueryMkr_fil(IoUrlInfo urlInfo, File apiFil) {
Io_url filUrl = Io_url_.new_inf_(apiFil.getPath(), urlInfo); // NOTE: may throw PathTooLongException when url is > 248 (exception messages states 260)
long fil_len = apiFil.exists() ? apiFil.length() : IoItmFil.Size_invalid; // NOTE: if file doesn't exist, set len to -1; needed for "boolean Exists() {return size != Size_Invalid;}"; DATE:2014-06-21
IoItmFil rv = IoItmFil_.new_(filUrl, fil_len, DateAdp_.MinValue, DateAdp_.unixtime_lcl_ms_(apiFil.lastModified()));
rv.ReadOnly_(!apiFil.canWrite());
return rv;
}
IoItmDir QueryMkr_dir(IoUrlInfo urlInfo, File apiDir) {
Io_url dirUrl = Io_url_.new_inf_(apiDir.getPath() + urlInfo.DirSpr(), urlInfo); // NOTE: may throw PathTooLongException when url is > 248 (exception messages states 260)
return IoItmDir_.scan_(dirUrl);
}
@Override public IoItmFil QueryFil(Io_url url) {
File fil = new File(url.Xto_api());
return QueryMkr_fil(url.Info(), fil);
}
@Override public void UpdateFilAttrib(Io_url url, IoItmAttrib atr) {
File f = new File(url.Xto_api());
boolean rv = true;
if (atr.ReadOnly() != Fil_ReadOnly(f)) {
if (atr.ReadOnly())
rv = f.setReadOnly();
else {
if (!Op_sys.Cur().Tid_is_drd())
IoEngine_system_xtn.SetWritable(f, true);
}
if (!rv) throw Err_.new_(IoEngineArgs.Instance.Err_IoException, "set file attribute failed", "attribute", "readOnly", "cur", Fil_ReadOnly(f), "new", atr.ReadOnly(), "url", url.Xto_api());
}
if (atr.Hidden() != f.isHidden()) {
//Runtime.getRuntime().exec("attrib +H myHiddenFile.java");
}
}
@Override public void UpdateFilModifiedTime(Io_url url, DateAdp modified) {
File f = new File(url.Xto_api());
long timeInt = modified.UnderDateTime().getTimeInMillis();
// if (timeInt < 0) {
// UsrDlg_._.Notify("{0} {1}", url.Xto_api(), timeInt);
// return;
// }
if (!f.setLastModified(timeInt)) {
if (Fil_ReadOnly(f)) {
boolean success = false;
try {
UpdateFilAttrib(url, IoItmAttrib.normal_());
success = f.setLastModified(timeInt);
}
finally {
UpdateFilAttrib(url, IoItmAttrib.readOnly_());
}
if (!success) throw Err_.new_wo_type("could not update file modified time", "url", url.Xto_api(), "modifiedTime", modified.XtoStr_gplx_long());
}
}
}
@Override public IoStream OpenStreamRead(Io_url url) {return IoStream_base.new_(url, IoStream_.Mode_rdr);}
@Override public IoStream OpenStreamWrite(IoEngine_xrg_openWrite args) {
Io_url url = args.Url();
if (!ExistsFil_api(url)) SaveFilText_api(IoEngine_xrg_saveFilStr.new_(url, ""));
return IoStream_base.new_(url, args.Mode());
}
@SuppressWarnings("resource")
@Override public void CopyFil(IoEngine_xrg_xferFil args) {
// TODO:JAVA6 hidden property ignored; 1.6 does not allow OS-independent way of setting isHidden (wnt only possible through jni)
boolean overwrite = args.Overwrite();
Io_url srcUrl = args.Src(), trgUrl = args.Trg();
File srcFil = new File(srcUrl.Xto_api()), trgFil = new File(trgUrl.Xto_api());
if (trgFil.isFile()) { // trgFil exists; check if overwrite set and trgFil is writable
Chk_TrgFil_Overwrite(overwrite, trgUrl);
MarkFileWritable(trgFil, trgUrl, args.ReadOnlyFails(), "copy");
}
else { // trgFil doesn't exist; must create file first else fileNotFound exception thrown
// if (overwrite) throw Err_
boolean rv = true; //Exception exc = null;
if (!ExistsDir(trgUrl.OwnerDir())) CreateDir(trgUrl.OwnerDir());
try {
trgFil.createNewFile();
if (!Op_sys.Cur().Tid_is_drd())
IoEngine_system_xtn.SetExecutable(trgFil, true);
}
catch (IOException e) {
// exc = e;
rv = false;
}
if (!rv)
throw Err_.new_wo_type("create file failed", "trg", trgUrl.Xto_api());
}
FileInputStream srcStream = null; FileOutputStream trgStream = null;
FileChannel srcChannel = null, trgChannel = null;
try {
// make objects
try {srcStream = new FileInputStream(srcFil);}
catch (FileNotFoundException e) {throw IoErr.FileNotFound("copy", srcUrl);}
try {trgStream = new FileOutputStream(trgFil);}
catch (FileNotFoundException e) {
trgStream = TryToUnHideFile(trgFil, trgUrl);
if (trgStream == null)
throw IoErr.FileNotFound("copy", trgUrl);
// else
// wasHidden = true;
}
srcChannel = srcStream.getChannel();
trgChannel = trgStream.getChannel();
// transfer data
long pos = 0, count = 0, read = 0;
try {count = srcChannel.size();}
catch (IOException e) {throw Err_.new_exc(e, "io", "size failed", "src", srcUrl.Xto_api());}
int totalBufferSize = IoEngineArgs.Instance.LoadFilStr_BufferSize;
long transferSize = (count > totalBufferSize) ? totalBufferSize : count; // transfer as much as fileSize, but limit to LoadFilStr_BufferSize
while (pos < count) {
try {read = trgChannel.transferFrom(srcChannel, pos, transferSize);}
catch (IOException e) {
Closeable_close(srcChannel, srcUrl, false);
Closeable_close(trgChannel, trgUrl, false);
Closeable_close(srcStream, srcUrl, false);
Closeable_close(trgStream, srcUrl, false);
throw Err_.new_exc(e, "io", "transfer data failed", "src", srcUrl.Xto_api(), "trg", trgUrl.Xto_api());
}
if (read == -1) break;
pos += read;
}
// if (wasHidden)
//
}
finally {
// cleanup
Closeable_close(srcChannel, srcUrl, false);
Closeable_close(trgChannel, trgUrl, false);
Closeable_close(srcStream, srcUrl, false);
Closeable_close(trgStream, srcUrl, false);
}
UpdateFilModifiedTime(trgUrl, QueryFil(srcUrl).ModifiedTime()); // must happen after file is closed
}
FileOutputStream TryToUnHideFile(File trgFil, Io_url trgUrl) {
FileOutputStream trgStream = null;
if (trgFil.exists()) { // WORKAROUND: java fails when writing to hidden files; unmark hidden and try again
Process p = null;
try {
String d = "attrib -H \"" + trgUrl.Xto_api() + "\"";
p = Runtime.getRuntime().exec(d);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
p.waitFor();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {trgStream = new FileOutputStream(trgFil);}
catch (FileNotFoundException e) {
return null;
}
}
return trgStream;
}
@Override public void MoveFil(IoEngine_xrg_xferFil args) {
Io_url srcUrl = args.Src(), trgUrl = args.Trg();
String src_api = srcUrl.Xto_api(), trg_api = trgUrl.Xto_api();
if (String_.Eq(src_api, trg_api)) return; // ignore command if src and trg is same; EX: C:\a.txt -> C:\a.txt should be noop
File srcFil = new File(src_api), trgFil = new File(trg_api);
// if drive is same, then rename file
if (String_.Eq(srcUrl.OwnerRoot().Raw(), trgUrl.OwnerRoot().Raw())) {
boolean overwrite = args.Overwrite();
if (!srcFil.exists() && args.MissingFails()) throw IoErr.FileNotFound("move", srcUrl);
if (trgFil.exists()) {
Chk_TrgFil_Overwrite(overwrite, trgUrl);
MarkFileWritable(trgFil, trgUrl, args.ReadOnlyFails(), "move");
DeleteFil_lang(trgFil, args.Trg()); // overwrite is specified and file is writable -> delete
}
if (!ExistsDir(trgUrl.OwnerDir())) CreateDir(trgUrl.OwnerDir());
srcFil.renameTo(trgFil);
}
// else copy fil and delete
else {
if (!srcFil.exists() && !args.MissingFails()) return;
CopyFil(args);
DeleteFil_lang(srcFil, srcUrl);
}
}
void Chk_TrgFil_Overwrite(boolean overwrite, Io_url trg) {
if (!overwrite)
throw Err_.new_invalid_op("trgFile exists but overwriteFlag not set").Args_add("trg", trg.Xto_api());
}
@Override public void MoveDir(Io_url src, Io_url trg) {
String srcStr = src.Xto_api(), trgStr = trg.Xto_api();
File srcFil = new File(srcStr), trgFil = new File(trgStr);
if (trgFil.exists()) {throw Err_.new_invalid_op("cannot move dir if trg exists").Args_add("src", src, "trg", trg);}
if (String_.Eq(src.OwnerRoot().Raw(), trg.OwnerRoot().Raw())) {
srcFil.renameTo(trgFil);
}
else {
XferDir(IoEngine_xrg_xferDir.copy_(src, trg));
}
}
protected static void Closeable_close(Closeable closeable, Io_url url, boolean throwErr) {Closeable_close(closeable, url.Xto_api(), throwErr);}
protected static void Closeable_close(Closeable closeable, String url_str, boolean throwErr) {
if (closeable == null) return;
try {closeable.close();}
catch (IOException e) {
if (throwErr)
throw Err_.new_exc(e, "io", "close object failed", "class", Type_adp_.NameOf_obj(closeable), "url", url_str);
// else
// UsrDlg_._.Finally("failed to close FileChannel", "url", url, "apiErr", Err_.Message_err_arg(e));
}
}
File Fil_(Io_url url) {return new File(url.Xto_api());}
boolean Fil_Exists(File fil) {return fil.exists();}
boolean Fil_ReadOnly(File fil) {return !fil.canWrite();}
boolean Fil_Delete(File fil) {return fil.delete();}
void Fil_Writable(File fil) {
if (!Op_sys.Cur().Tid_is_drd())
IoEngine_system_xtn.SetWritable(fil, true);
}
private static Err Err_text_unsupported_encoding(String encodingName, String text, String url_str, Exception e) {
return Err_.new_exc(e, "io", "text is in unsupported encoding").Args_add("encodingName", encodingName, "text", text, "url", url_str);
}
boolean user_agent_needs_resetting = true;
@Override public Io_stream_rdr DownloadFil_as_rdr(IoEngine_xrg_downloadFil xrg) {
Io_stream_rdr_http rdr = new Io_stream_rdr_http(xrg);
rdr.Open();
return rdr;
}
@Override public boolean DownloadFil(IoEngine_xrg_downloadFil xrg) {
IoStream trg_stream = null;
java.io.BufferedInputStream src_stream = null;
java.net.URL src_url = null;
HttpURLConnection src_conn = null;
if (user_agent_needs_resetting) {user_agent_needs_resetting = false; System.setProperty("http.agent", "");}
boolean exists = Io_mgr.Instance.ExistsDir(xrg.Trg().OwnerDir());
Gfo_usr_dlg prog_dlg = null;
String src_str = xrg.Src();
Io_download_fmt xfer_fmt = xrg.Download_fmt();
prog_dlg = xfer_fmt.Usr_dlg();
if (!Web_access_enabled) {
if (prog_dlg != null) {
if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt");
prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download disabled: src='~{0}' trg='~{1}'", xrg.Src(), xrg.Trg().Raw());
}
return false;
}
try {
trg_stream = Io_mgr.Instance.OpenStreamWrite(xrg.Trg());
src_url = new java.net.URL(src_str);
src_conn = (HttpURLConnection)src_url.openConnection();
// src_conn.setReadTimeout(5000); // do not set; if file does not exist, will wait 5 seconds before timing out; want to fail immediately
String user_agent = xrg.User_agent(); if (user_agent != null) src_conn.setRequestProperty("User-Agent", user_agent);
long content_length = Long_.parse_or(src_conn.getHeaderField("Content-Length"), IoItmFil.Size_invalid_int);
xrg.Src_content_length_(content_length);
if (xrg.Src_last_modified_query()) // NOTE: only files will have last modified (api calls will not); if no last_modified, then src_conn will throw get nullRef; avoid nullRef
xrg.Src_last_modified_(DateAdp_.unixtime_lcl_ms_(src_conn.getLastModified()));
if (xrg.Exec_meta_only()) return true;
src_stream = new java.io.BufferedInputStream(src_conn.getInputStream());
if (!exists) {
Io_mgr.Instance.CreateDir(xrg.Trg().OwnerDir()); // dir must exist for OpenStreamWrite; create dir at last possible moment in case stream does not exist.
}
byte[] download_bfr = new byte[Download_bfr_len]; // NOTE: download_bfr was originally member variable; DATE:2013-05-03
xfer_fmt.Bgn(content_length);
int count = 0;
while ((count = src_stream.read(download_bfr, 0, Download_bfr_len)) != -1) {
if (xrg.Prog_cancel()) {
src_stream.close();
trg_stream.Rls();
Io_mgr.Instance.DeleteFil(xrg.Trg());
}
xfer_fmt.Prog(count);
trg_stream.Write(download_bfr, 0, count);
}
if (prog_dlg != null) {
xfer_fmt.Term();
if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt");
prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download pass: src='~{0}' trg='~{1}'", src_str, xrg.Trg().Raw());
}
return true;
}
catch (Exception exc) {
xrg.Rslt_err_(exc);
if (Type_adp_.Eq_typeSafe(exc, java.net.UnknownHostException.class)) xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_host_not_found);
else if (Type_adp_.Eq_typeSafe(exc, java.io.FileNotFoundException.class)) xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_file_not_found);
else xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_unknown);
if (prog_dlg != null && !xrg.Prog_cancel()) {
if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt");
prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download fail: src='~{0}' trg='~{1}' error='~{2}'", src_str, xrg.Trg().Raw(), Err_.Message_lang(exc));
}
if (trg_stream != null) {
try {
trg_stream.Rls();
DeleteFil_api(IoEngine_xrg_deleteFil.new_(xrg.Trg()));
}
catch (Exception e2) {Err_.Noop(e2);}
}
return false;
}
finally {
xrg.Prog_running_(false);
try {
if (src_stream != null) src_stream.close();
if (src_conn != null) src_conn.disconnect();
src_conn.getInputStream().close();
} catch (Exception exc) {
Err_.Noop(exc);
}
if (trg_stream != null) trg_stream.Rls();
}
} Io_url session_fil; Bry_bfr prog_fmt_bfr;
byte[] download_bfr; static final int Download_bfr_len = Io_mgr.Len_kb * 128;
public static Err Err_Fil_NotFound(Io_url url) {
return Err_.new_(IoEngineArgs.Instance.Err_FileNotFound, "file not found", "url", url.Xto_api()).Trace_ignore_add_1_();
}
public static Err Err_Fil_NotFound(Exception e, Io_url url) {
return Err_.new_exc(e, "io", "file not found", "url", url.Xto_api()).Trace_ignore_add_1_();
}
void MarkFileWritable(File fil, Io_url url, boolean readOnlyFails, String op) {
if (Fil_ReadOnly(fil)) {
if (readOnlyFails) // NOTE: java will always allow final files to be deleted; programmer api is responsible for check
throw Err_.new_(IoEngineArgs.Instance.Err_ReadonlyFileNotWritable, "writable operation attempted on readOnly file", "op", op, "url", url.Xto_api());
else
Fil_Writable(fil);
}
}
void DeleteFil_lang(File fil, Io_url url) {
boolean rv = Fil_Delete(fil);
if (!rv)
throw Err_.new_(IoEngineArgs.Instance.Err_IoException, "file not deleted", "url", url.Xto_api());
}
IoEngineUtl utl = IoEngineUtl.new_();
public static IoEngine_system new_() {return new IoEngine_system();} IoEngine_system() {}
static final String GRP_KEY = "Io_engine";
public static boolean Web_access_enabled = true;
}
class IoEngineArgs {
public int LoadFilStr_BufferSize = 4096 * 256;
public String LoadFilStr_Encoding = "UTF-8";
public String Err_ReadonlyFileNotWritable = "gplx.core.ios.ReadonlyFileNotWritable";
public String Err_FileNotFound = "gplx.core.ios.FileNotFound";
public String Err_IoException = "gplx.core.ios.IoException";
public static final IoEngineArgs Instance = new IoEngineArgs();
}
class IoEngine_system_xtn {
// PATCH.DROID:VerifyError if file.setExecutable is referenced directly in IoEngine_system. However, if placed in separate class
public static void SetExecutable(java.io.File file, boolean v) {file.setExecutable(v);}
public static void SetWritable(java.io.File file, boolean v) {file.setWritable(v);}
}
class Io_download_http {
public static boolean User_agent_reset_needed = true;
public static void User_agent_reset() {
User_agent_reset_needed = false;
System.setProperty("http.agent", ""); // need to set http.agent to '' in order for "User-agent" to take effect
}
public static void Save_to_fsys(IoEngine_xrg_downloadFil xrg) {
Io_stream_rdr_http rdr = new Io_stream_rdr_http(xrg);
IoStream trg_stream = null;
try {
boolean exists = Io_mgr.Instance.ExistsDir(xrg.Trg().OwnerDir());
if (!exists)
Io_mgr.Instance.CreateDir(xrg.Trg().OwnerDir()); // dir must exist for OpenStreamWrite; create dir at last possible moment in case stream does not exist.
trg_stream = Io_mgr.Instance.OpenStreamWrite(xrg.Trg());
byte[] bfr = new byte[Download_bfr_len];
rdr.Open();
while (rdr.Read(bfr, 0, Download_bfr_len) != Read_done) {
}
}
finally {
rdr.Rls();
if (trg_stream != null) trg_stream.Rls();
}
if (xrg.Rslt() != IoEngine_xrg_downloadFil.Rslt_pass)
Io_mgr.Instance.DeleteFil_args(xrg.Trg()).MissingFails_off().Exec();
}
public static final int Read_done = -1;
public static final int Download_bfr_len = Io_mgr.Len_kb * 128;
}
class Io_stream_rdr_http implements Io_stream_rdr {
public Io_stream_rdr_http(IoEngine_xrg_downloadFil xrg) {
this.xrg = xrg;
} private IoEngine_xrg_downloadFil xrg;
public byte Tid() {return Io_stream_.Tid_raw;}
public boolean Exists() {return exists;} private boolean exists = false;
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 = IoItmFil.Size_invalid; // NOTE: must default size to -1; DATE:2014-06-21
private String src_str; private HttpURLConnection src_conn; private java.io.BufferedInputStream src_stream;
private Io_download_fmt xfer_fmt; private Gfo_usr_dlg prog_dlg;
private boolean read_done = true, read_failed = false;
public Io_stream_rdr Open() {
if (Io_download_http.User_agent_reset_needed) Io_download_http.User_agent_reset();
if (!IoEngine_system.Web_access_enabled) {
read_done = read_failed = true;
if (prog_dlg != null)
prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download disabled: src='~{0}' trg='~{1}'", xrg.Src(), xrg.Trg().Raw());
return this;
}
src_str = xrg.Src();
xfer_fmt = xrg.Download_fmt(); prog_dlg = xfer_fmt.Usr_dlg();
try {
src_conn = (HttpURLConnection)new java.net.URL(src_str).openConnection();
String user_agent = xrg.User_agent();
if (user_agent != null) src_conn.setRequestProperty("User-Agent", user_agent); // NOTE: must be set right after openConnection
// src_conn.setReadTimeout(5000); // do not set; if file does not exist, will wait 5 seconds before timing out; want to fail immediately
long content_length = Long_.parse_or(src_conn.getHeaderField("Content-Length"), IoItmFil.Size_invalid_int);
xrg.Src_content_length_(content_length);
this.len = content_length;
if (xrg.Src_last_modified_query()) // NOTE: only files will have last modified (api calls will not); if no last_modified, then src_conn will throw get nullRef; avoid nullRef
xrg.Src_last_modified_(DateAdp_.unixtime_lcl_ms_(src_conn.getLastModified()));
if (xrg.Exec_meta_only()) {
read_done = true;
return this;
}
read_done = false;
this.exists = Int_.In(src_conn.getResponseCode(), 200, 301); // ASSUME: response code of 200 (OK) or 301 (Redirect) means that file exists; note that content_length seems to always be -1; DATE:2015-05-20
src_stream = new java.io.BufferedInputStream(src_conn.getInputStream());
xfer_fmt.Bgn(content_length);
}
catch (Exception e) {Err_handle(e);}
return this;
}
public void Open_mem(byte[] v) {}
public Object Under() {return src_stream;}
public int Read(byte[] bry, int bgn, int len) {
if (read_done) return Io_download_http.Read_done;
if (xrg.Prog_cancel()) {read_failed = true; return Io_download_http.Read_done;}
try {
int read = src_stream.read(bry, bgn, len);
xfer_fmt.Prog(read);
return read;
}
catch (Exception e) {
Err_handle(e);
return Io_download_http.Read_done;
}
}
private Io_url session_fil = null;
private boolean rls_done = false;
public long Skip(long len) {return 0;}
public void Rls() {
if (rls_done) return;
try {
read_done = true;
if (prog_dlg != null) {
xfer_fmt.Term();
}
if (session_fil == null && prog_dlg != null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt");
if (read_failed) {
}
else {
if (prog_dlg != null)
prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download pass: src='~{0}' trg='~{1}'", src_str, xrg.Trg().Raw());
xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_pass);
}
xrg.Prog_running_(false);
}
catch (Exception e) {Err_.Noop(e);} // ignore close errors; also Err_handle calls Rls() so it would be circular
finally {
try {if (src_stream != null) src_stream.close();}
catch (Exception e) {Err_.Noop(e);} // ignore failures when cleaning up
if (src_conn != null) src_conn.disconnect();
src_stream = null;
src_conn = null;
rls_done = true;
}
}
private void Err_handle(Exception exc) {
read_done = read_failed = true;
len = -1;
xrg.Rslt_err_(exc);
if (Type_adp_.Eq_typeSafe(exc, java.net.UnknownHostException.class)) xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_host_not_found);
else if (Type_adp_.Eq_typeSafe(exc, java.io.FileNotFoundException.class)) xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_file_not_found);
else xrg.Rslt_(IoEngine_xrg_downloadFil.Rslt_fail_unknown);
if (prog_dlg != null && !xrg.Prog_cancel()) {
if (session_fil == null) session_fil = prog_dlg.Log_wkr().Session_dir().GenSubFil("internet.txt");
prog_dlg.Log_wkr().Log_msg_to_url_fmt(session_fil, "download fail: src='~{0}' trg='~{1}' error='~{2}'", src_str, xrg.Trg().Raw(), Err_.Message_lang(exc));
}
this.Rls();
}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.consoles.*; import gplx.core.criterias.*;
public class IoEngine_xrg_deleteDir {
public Io_url Url() {return url;} public IoEngine_xrg_deleteDir Url_(Io_url val) {url = val; return this;} Io_url url;
public boolean Recur() {return recur;} public IoEngine_xrg_deleteDir Recur_() {return Recur_(true);} public IoEngine_xrg_deleteDir Recur_(boolean v) {recur = v; return this;} private boolean recur = false;
public boolean ReadOnlyFails() {return readOnlyFails;} public IoEngine_xrg_deleteDir ReadOnlyFails_off() {return ReadOnlyFails_(false);} public IoEngine_xrg_deleteDir ReadOnlyFails_(boolean v) {readOnlyFails = v; return this;} private boolean readOnlyFails = true;
public boolean MissingIgnored() {return missingIgnored;} public IoEngine_xrg_deleteDir MissingIgnored_() {return MissingIgnored_(true);} public IoEngine_xrg_deleteDir MissingIgnored_(boolean v) {missingIgnored = v; return this;} private boolean missingIgnored = true;
public Criteria MatchCrt() {return matchCrt;} public IoEngine_xrg_deleteDir MatchCrt_(Criteria v) {matchCrt = v; return this;} Criteria matchCrt = Criteria_.All;
public Criteria SubDirScanCrt() {return subDirScanCrt;} public IoEngine_xrg_deleteDir SubDirScanCrt_(Criteria v) {subDirScanCrt = v; return this;} Criteria subDirScanCrt = Criteria_.All;
public Console_adp UsrDlg() {return usrDlg;} public IoEngine_xrg_deleteDir UsrDlg_(Console_adp v) {usrDlg = v; return this;} Console_adp usrDlg = Console_adp_.Noop;
public void Exec() {IoEnginePool.Instance.Get_by(url.Info().EngineKey()).DeleteDirDeep(this);}
public static IoEngine_xrg_deleteDir new_(Io_url url) {
IoEngine_xrg_deleteDir rv = new IoEngine_xrg_deleteDir();
rv.url = url;
return rv;
} IoEngine_xrg_deleteDir() {}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_xrg_deleteFil extends IoEngine_xrg_fil_affects1_base {
@gplx.New public IoEngine_xrg_deleteFil Url_(Io_url val) {Url_set(val); return this;}
public IoEngine_xrg_deleteFil ReadOnlyFails_off() {return ReadOnlyFails_(false);} public IoEngine_xrg_deleteFil ReadOnlyFails_(boolean v) {ReadOnlyFails_set(v); return this;}
public IoEngine_xrg_deleteFil MissingFails_off() {return MissingFails_(false);} public IoEngine_xrg_deleteFil MissingFails_(boolean v) {MissingFails_set(v); return this;}
@Override public void Exec() {IoEnginePool.Instance.Get_by(this.Url().Info().EngineKey()).DeleteFil_api(this);}
public static IoEngine_xrg_deleteFil proto_() {return new IoEngine_xrg_deleteFil();}
public static IoEngine_xrg_deleteFil new_(Io_url url) {
IoEngine_xrg_deleteFil rv = new IoEngine_xrg_deleteFil();
rv.Url_set(url);
return rv;
} IoEngine_xrg_deleteFil() {}
}

View File

@@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_xrg_downloadFil {
public String Src() {return src;} public IoEngine_xrg_downloadFil Src_(String v) {src = v; return this;} private String src;
public Io_url Trg() {return trg;} public IoEngine_xrg_downloadFil Trg_(Io_url v) {trg = v; return this;} private Io_url trg;
public byte Rslt() {return rslt;} public IoEngine_xrg_downloadFil Rslt_(byte v) {rslt = v; return this;} private byte rslt = Rslt_pass;
public Exception Rslt_err() {return rslt_err;} public IoEngine_xrg_downloadFil Rslt_err_(Exception v) {rslt_err = v; return this;} private Exception rslt_err;
public String Rslt_err_str() {
return rslt_err == null ? "none" : Err_.Message_gplx_full(rslt_err);
}
public String User_agent() {return user_agent;} public IoEngine_xrg_downloadFil User_agent_(String v) {user_agent = v; return this;} private String user_agent;
public Gfo_usr_dlg Prog_dlg() {return prog_dlg;} public IoEngine_xrg_downloadFil Prog_dlg_(Gfo_usr_dlg v) {prog_dlg = v; download_fmt.Ctor(prog_dlg); return this;} private Gfo_usr_dlg prog_dlg;
public Bry_fmtr Prog_fmtr() {return prog_fmtr;} private final Bry_fmtr prog_fmtr = Bry_fmtr.new_("~{download_header}: ~{download_read} of ~{download_length} kb;", "download_header", "download_url", "download_read", "download_length");
public String Prog_fmt_hdr() {return prog_fmt_hdr;} public IoEngine_xrg_downloadFil Prog_fmt_hdr_(String v) {prog_fmt_hdr = v; return this;} private String prog_fmt_hdr = ""; // NOTE: must init to "", else null ref when building String
public boolean Prog_cancel() {return prog_cancel;} public IoEngine_xrg_downloadFil Prog_cancel_y_() {prog_cancel = true; return this;} private volatile boolean prog_cancel;
public boolean Prog_running() {return prog_running;} public IoEngine_xrg_downloadFil Prog_running_(boolean v) {prog_running = v; return this;} private boolean prog_running;
public long Src_content_length() {return src_content_length;} public IoEngine_xrg_downloadFil Src_content_length_(long v) {src_content_length = v; return this;} private long src_content_length;
public DateAdp Src_last_modified() {return src_last_modified;} public IoEngine_xrg_downloadFil Src_last_modified_(DateAdp v) {src_last_modified = v; return this;} private DateAdp src_last_modified;
public boolean Src_last_modified_query() {return src_last_modified_query;} public IoEngine_xrg_downloadFil Src_last_modified_query_(boolean v) {src_last_modified_query = v; return this;} private boolean src_last_modified_query;
public String Trg_engine_key() {return trg_engine_key;} public IoEngine_xrg_downloadFil Trg_engine_key_(String v) {trg_engine_key = v; return this;} private String trg_engine_key = IoEngine_.SysKey;
public Io_download_fmt Download_fmt() {return download_fmt;} private final Io_download_fmt download_fmt = new Io_download_fmt();
public boolean Exec() {return IoEnginePool.Instance.Get_by(trg.Info().EngineKey()).DownloadFil(this);}
public Io_stream_rdr Exec_as_rdr() {return IoEnginePool.Instance.Get_by(IoEngine_.SysKey).DownloadFil_as_rdr(this);}
public boolean Exec_meta_only() {return exec_meta_only;} private boolean exec_meta_only;
public byte[] Exec_as_bry(String src) {
this.Src_(src); this.Trg_(trg_mem);
download_fmt.Download_init(src, prog_fmt_hdr); // NOTE: must set src else NULL error
boolean pass = IoEnginePool.Instance.Get_by(trg_engine_key).DownloadFil(this);
return pass ? Io_mgr.Instance.LoadFilBry(trg_mem) : null;
} private Io_url trg_mem = Io_url_.mem_fil_("mem/download.tmp");
public boolean Exec_meta(String src) {
this.Src_(src); this.Trg_(trg_mem); // NOTE: set Trg_ else error in download proc
download_fmt.Download_init(src, prog_fmt_hdr); // NOTE: must set src else NULL error
exec_meta_only = true;
boolean rv = IoEnginePool.Instance.Get_by(trg_engine_key).DownloadFil(this);
exec_meta_only = false;
return rv;
}
public void Init(String src, Io_url trg) {
this.src = src; this.trg = trg;
prog_cancel = false;
rslt_err = null;
rslt = Rslt_pass;
prog_running = true;
download_fmt.Download_init(src, "downloading ~{src_name}: ~{prog_left} left (@ ~{prog_rate}); ~{prog_done} of ~{src_len} (~{prog_pct}%)");
}
public static IoEngine_xrg_downloadFil new_(String src, Io_url trg) {
IoEngine_xrg_downloadFil rv = new IoEngine_xrg_downloadFil();
rv.src = src; rv.trg = trg;
return rv;
} IoEngine_xrg_downloadFil() {}
public static final byte Rslt_pass = 0, Rslt_fail_host_not_found = 1, Rslt_fail_file_not_found = 2, Rslt_fail_unknown = 3;
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_xrg_fil_affects1_base {
public Io_url Url() {return url;} public void Url_set(Io_url v) {url = v;} Io_url url;
public IoEngine_xrg_fil_affects1_base Url_(Io_url v) {url = v; return this;}
public boolean MissingFails() {return missingFails;} public void MissingFails_set(boolean v) {missingFails = v;} private boolean missingFails = true;
public boolean ReadOnlyFails() {return readOnlyFails;} public void ReadOnlyFails_set(boolean v) {readOnlyFails = v;} private boolean readOnlyFails = true;
@gplx.Virtual public void Exec() {}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.texts.*;
public class IoEngine_xrg_loadFilStr {
public Io_url Url() {return url;} public IoEngine_xrg_loadFilStr Url_(Io_url val) {url = val; return this;} Io_url url;
public boolean MissingIgnored() {return missingIgnored;} public IoEngine_xrg_loadFilStr MissingIgnored_() {return MissingIgnored_(true);} public IoEngine_xrg_loadFilStr MissingIgnored_(boolean v) {missingIgnored = v; return this;} private boolean missingIgnored = false;
public boolean BomUtf8Convert() {return bomUtf8Convert;} public IoEngine_xrg_loadFilStr BomUtf8Convert_(boolean v) {bomUtf8Convert = v; return this;} private boolean bomUtf8Convert = true;
public String Exec() {
String s = IoEnginePool.Instance.Get_by(url.Info().EngineKey()).LoadFilStr(this);
if (bomUtf8Convert && String_.Len(s) > 0 && String_.CodePointAt(s, 0) == Bom_Utf8) {
s = String_.Mid(s, 1);
UsrDlg_.Instance.Warn(UsrMsg.new_("UTF8 BOM removed").Add("url", url.Xto_api()));
}
return s;
}
public String[] ExecAsStrAry() {return String_.Split(Exec(), String_.CrLf);}
public String[] ExecAsStrAryLnx() {
String raw = Exec();
if (String_.Len(raw) == 0) return String_.Ary_empty;
return String_.Split(raw, Op_sys.Dir_spr_char_lnx, false);
}
int Bom_Utf8 = 65279; // U+FEFF; see http://en.wikipedia.org/wiki/Byte_order_mark
public static IoEngine_xrg_loadFilStr new_(Io_url url) {
IoEngine_xrg_loadFilStr rv = new IoEngine_xrg_loadFilStr();
rv.url = url;
return rv;
} IoEngine_xrg_loadFilStr() {}
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_xrg_openRead {
public Io_url Url() {return url;} Io_url url;
public String ErrMsg() {return errMsg;} private String errMsg;
public IoStream ExecAsIoStreamOrFail() {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).OpenStreamRead(url);}
public IoStream ExecAsIoStreamOrNull() {
try {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).OpenStreamRead(url);}
catch (Exception exc) {
errMsg = Err_.Message_lang(exc);
return IoStream_.Null;
}
}
public static IoEngine_xrg_openRead new_(Io_url url) {
IoEngine_xrg_openRead rv = new IoEngine_xrg_openRead();
rv.url = url;
return rv;
} IoEngine_xrg_openRead() {}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_xrg_openWrite {
public Io_url Url() {return url;} public IoEngine_xrg_openWrite Url_(Io_url val) {url = val; return this;} Io_url url;
public boolean ReadOnlyIgnored() {return readOnlyIgnored;} public IoEngine_xrg_openWrite ReadOnlyIgnored_() {return ReadOnlyIgnored_(true);} public IoEngine_xrg_openWrite ReadOnlyIgnored_(boolean v) {readOnlyIgnored = v; return this;} private boolean readOnlyIgnored = false;
public boolean MissingIgnored() {return missingIgnored;} public IoEngine_xrg_openWrite MissingIgnored_() {return MissingIgnored_(true);} public IoEngine_xrg_openWrite MissingIgnored_(boolean v) {missingIgnored = v; return this;} private boolean missingIgnored = false;
public byte Mode() {return mode;} public IoEngine_xrg_openWrite Mode_(byte v) {mode = v; return this;} private byte mode = IoStream_.Mode_wtr_create;
public IoEngine_xrg_openWrite Mode_update_() {return Mode_(IoStream_.Mode_wtr_update);}
public IoStream Exec() {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).OpenStreamWrite(this);}
public static IoEngine_xrg_openWrite new_(Io_url url) {
IoEngine_xrg_openWrite rv = new IoEngine_xrg_openWrite();
rv.url = url;
return rv;
} IoEngine_xrg_openWrite() {}
}

View 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.ios; import gplx.*; import gplx.core.*;
import gplx.core.consoles.*; import gplx.core.criterias.*;
public class IoEngine_xrg_queryDir {
public Io_url Url() {return url;} public IoEngine_xrg_queryDir Url_(Io_url val) {url = val; return this;} Io_url url;
public boolean Recur() {return recur;} public IoEngine_xrg_queryDir Recur_() {return Recur_(true);} public IoEngine_xrg_queryDir Recur_(boolean val) {recur = val; return this;} private boolean recur = false;
public boolean DirInclude() {return dirInclude;} public IoEngine_xrg_queryDir DirInclude_() {return DirInclude_(true);} public IoEngine_xrg_queryDir DirInclude_(boolean val) {dirInclude = val; return this;} private boolean dirInclude = false;
public Criteria FilCrt() {return filCrt;} public IoEngine_xrg_queryDir FilCrt_(Criteria val) {filCrt = val; return this;} Criteria filCrt;
public Criteria DirCrt() {return dirCrt;} public IoEngine_xrg_queryDir DirCrt_(Criteria val) {dirCrt = val; return this;} Criteria dirCrt;
public Criteria SubDirScanCrt() {return subDirScanCrt;} public IoEngine_xrg_queryDir SubDirScanCrt_(Criteria val) {subDirScanCrt = val; return this;} Criteria subDirScanCrt;
public IoEngine_xrg_queryDir DirOnly_() {
DirInclude_(true);
filCrt = Criteria_.None;
return this;
}
public Console_adp UsrDlg() {return usrDlg;} public IoEngine_xrg_queryDir UsrDlg_(Console_adp val) {usrDlg = val; return this;} Console_adp usrDlg = Console_adp_.Noop;
public IoEngine_xrg_queryDir FilPath_(String val) {
Criteria_ioMatch crt = Criteria_ioMatch.parse(true, val, url.Info().CaseSensitive());
filCrt = Criteria_fld.new_(IoItm_base_.Prop_Path, crt);
return this;
}
public IoItmDir ExecAsDir() {return IoEnginePool.Instance.Get_by(url.Info().EngineKey()).QueryDirDeep(this);}
public Io_url[] ExecAsUrlAry() {return ExecAsItmHash().XtoIoUrlAry();}
public IoItmHash ExecAsItmHash() {
Criteria crt = dirInclude ? Criteria_.All : Criteria_fld.new_(IoItm_base_.Prop_Type, Criteria_.eq_(IoItmFil.Type_Fil));
IoItmHash list = ExecAsDir().XtoIoItmList(crt);
list.Sort_by(IoItmBase_comparer_nest.Instance);
return list;
}
public static IoEngine_xrg_queryDir new_(Io_url url) {
IoEngine_xrg_queryDir rv = new IoEngine_xrg_queryDir();
rv.url = url;
rv.filCrt = Criteria_fld.new_(IoItm_base_.Prop_Path, Criteria_.All);
rv.dirCrt = Criteria_fld.new_(IoItm_base_.Prop_Path, Criteria_.All);
rv.subDirScanCrt = Criteria_fld.new_(IoItm_base_.Prop_Path, Criteria_.All);
return rv;
} IoEngine_xrg_queryDir() {}
}

View File

@@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class IoEngine_xrg_recycleFil extends IoEngine_xrg_fil_affects1_base {
public IoEngine_xrg_recycleFil MissingFails_off() {return MissingFails_(false);} public IoEngine_xrg_recycleFil MissingFails_(boolean v) {MissingFails_set(v); return this;}
public int Mode() {return mode;} public IoEngine_xrg_recycleFil Mode_(int v) {mode = v; return this;} int mode;
public String AppName() {return appName;} public IoEngine_xrg_recycleFil AppName_(String val) {appName = val; return this;} private String appName = "unknown_app";
public Guid_adp Uuid() {return uuid;} public IoEngine_xrg_recycleFil Uuid_(Guid_adp val) {uuid = val; return this;} Guid_adp uuid;
public boolean Uuid_include() {return uuid_include;} public IoEngine_xrg_recycleFil Uuid_include_() {uuid_include = true; return this;} private boolean uuid_include;
public DateAdp Time() {return time;} public IoEngine_xrg_recycleFil Time_(DateAdp val) {time = val; return this;} DateAdp time;
public List_adp RootDirNames() {return rootDirNames;} public IoEngine_xrg_recycleFil RootDirNames_(List_adp val) {rootDirNames = val; return this;} List_adp rootDirNames;
public Io_url RecycleUrl() {
String dayName = time.XtoStr_fmt("yyyyMMdd"), timeName = time.XtoStr_fmt("hhmmssfff");
String rootDirStr = ConcatWith_ary(this.Url().Info().DirSpr(), rootDirNames);
Io_url recycleDir = this.Url().OwnerRoot().GenSubDir_nest(rootDirStr, dayName);
String uuidStr = uuid_include ? uuid.To_str() : "";
return recycleDir.GenSubFil_ary(appName, ";", timeName, ";", uuidStr, ";", String_.LimitToFirst(this.Url().NameAndExt(), 128));
}
String ConcatWith_ary(String separator, List_adp ary) {
String_bldr sb = String_bldr_.new_();
int aryLen = ary.Count();
for (int i = 0; i < aryLen; i++) {
if (i != 0) sb.Add(separator);
Object val = ary.Get_at(i);
sb.Add_obj(Object_.Xto_str_strict_or_empty(val));
}
return sb.To_str();
}
@Override public void Exec() {
IoEnginePool.Instance.Get_by(this.Url().Info().EngineKey()).RecycleFil(this);
}
public IoEngine_xrg_recycleFil(int v) {
mode = v;
time = DateAdp_.Now();
uuid = Guid_adp_.new_();
rootDirNames = List_adp_.new_(); rootDirNames.Add("z_trash");
}
public static IoEngine_xrg_recycleFil sysm_(Io_url url) {return new IoEngine_xrg_recycleFil(SysmConst);}
public static IoEngine_xrg_recycleFil gplx_(Io_url url) {IoEngine_xrg_recycleFil rv = new IoEngine_xrg_recycleFil(GplxConst); rv.Url_set(url); return rv;}
public static IoEngine_xrg_recycleFil proto_() {return gplx_(Io_url_.Empty);}
public static final int GplxConst = 0, SysmConst = 1;
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.texts.*;
public class IoEngine_xrg_saveFilStr {
public Io_url Url() {return url;} public IoEngine_xrg_saveFilStr Url_(Io_url val) {url = val; return this;} Io_url url;
public String Text() {return text;} public IoEngine_xrg_saveFilStr Text_(String val) {text = val; return this;} private String text = "";
public boolean Append() {return append;} public IoEngine_xrg_saveFilStr Append_() {return Append_(true);} public IoEngine_xrg_saveFilStr Append_(boolean val) {append = val; return this;} private boolean append = false;
public void Exec() {
if (String_.Eq(text, "") && append) return; // no change; don't bother writing to disc
IoEnginePool.Instance.Get_by(url.Info().EngineKey()).SaveFilText_api(this);
}
public static IoEngine_xrg_saveFilStr new_(Io_url url, String text) {
IoEngine_xrg_saveFilStr rv = new IoEngine_xrg_saveFilStr();
rv.url = url; rv.text = text;
return rv;
} IoEngine_xrg_saveFilStr() {}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.criterias.*;
public class IoEngine_xrg_xferDir {
public boolean Type_move() {return move;} public boolean Type_copy() {return !move;} private boolean move = false;
public Io_url Src() {return src;} public IoEngine_xrg_xferDir Src_(Io_url val) {src = val; return this;} Io_url src;
public Io_url Trg() {return trg;} public IoEngine_xrg_xferDir Trg_(Io_url val) {trg = val; return this;} Io_url trg;
public boolean Recur() {return recur;} public IoEngine_xrg_xferDir Recur_() {recur = true; return this;} private boolean recur = false;
public boolean Overwrite() {return overwrite;} public IoEngine_xrg_xferDir Overwrite_() {return Overwrite_(true);} public IoEngine_xrg_xferDir Overwrite_(boolean v) {overwrite = v; return this;} private boolean overwrite = false;
public boolean ReadOnlyFails() {return readOnlyFails;} public IoEngine_xrg_xferDir ReadOnlyFails_() {return ReadOnlyFails_(true);} public IoEngine_xrg_xferDir ReadOnlyFails_(boolean v) {readOnlyFails = v; return this;} private boolean readOnlyFails = false;
public Criteria MatchCrt() {return matchCrt;} public IoEngine_xrg_xferDir MatchCrt_(Criteria v) {matchCrt = v; return this;} Criteria matchCrt = Criteria_.All;
public Criteria SubDirScanCrt() {return subDirScanCrt;} public IoEngine_xrg_xferDir SubDirScanCrt_(Criteria v) {subDirScanCrt = v; return this;} Criteria subDirScanCrt = Criteria_.All;
public void Exec() {IoEnginePool.Instance.Get_by(src.Info().EngineKey()).XferDir(this);}
public static IoEngine_xrg_xferDir move_(Io_url src, Io_url trg) {return new_(src, trg, true);}
public static IoEngine_xrg_xferDir copy_(Io_url src, Io_url trg) {return new_(src, trg, false);}
static IoEngine_xrg_xferDir new_(Io_url src, Io_url trg, boolean move) {
IoEngine_xrg_xferDir rv = new IoEngine_xrg_xferDir();
rv.src = src; rv.trg = trg; rv.move = move;
return rv;
} IoEngine_xrg_xferDir() {}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoEngine_xrg_xferFil {
public boolean Type_move() {return move;} private boolean move = false;
public Io_url Src() {return src;} Io_url src;
public Io_url Trg() {return trg;} Io_url trg;
public boolean Overwrite() {return overwrite;} public IoEngine_xrg_xferFil Overwrite_() {return Overwrite_(true);} public IoEngine_xrg_xferFil Overwrite_(boolean v) {overwrite = v; return this;} private boolean overwrite = false;
public boolean ReadOnlyFails() {return readOnlyFails;} public IoEngine_xrg_xferFil ReadOnlyFails_off() {return ReadOnlyFails_(false);} public IoEngine_xrg_xferFil ReadOnlyFails_(boolean v) {readOnlyFails = v; return this;} private boolean readOnlyFails = true;
public boolean MissingFails() {return missingFails;} public IoEngine_xrg_xferFil MissingFails_off() {return MissingFails_(false);} public IoEngine_xrg_xferFil MissingFails_(boolean v) {missingFails = v; return this;} private boolean missingFails = true;
public void Exec() {IoEnginePool.Instance.Get_by(src.Info().EngineKey()).XferFil(this);}
public static IoEngine_xrg_xferFil move_(Io_url src, Io_url trg) {return new_(src, trg, true);}
public static IoEngine_xrg_xferFil copy_(Io_url src, Io_url trg) {return new_(src, trg, false);}
static IoEngine_xrg_xferFil new_(Io_url src, Io_url trg, boolean move) {
IoEngine_xrg_xferFil rv = new IoEngine_xrg_xferFil();
rv.src = src; rv.trg = trg; rv.move = move;
return rv;
} IoEngine_xrg_xferFil() {}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoErr {
public static String Namespace = "gplx.core.ios.";
public static String FileIsReadOnly_key = Namespace + "FileIsReadOnlyError";
public static String FileNotFound_key = Namespace + "FileNotFoundError";
public static Err FileIsReadOnly(Io_url url) {
return Err_.new_(FileIsReadOnly_key, "file is read-only", "url", url.Xto_api()).Trace_ignore_add_1_();
}
public static Err FileNotFound(String op, Io_url url) {
// file is missing -- op='copy' file='C:\a.txt' copyFile_target='D:\a.txt'
return Err_.new_(FileNotFound_key, "file not found", "op", op, "file", url.Xto_api()).Trace_ignore_add_1_();
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public class IoItmAttrib {
public boolean ReadOnly() {return readOnly;} public IoItmAttrib ReadOnly_() {return ReadOnly_(true);} public IoItmAttrib ReadOnly_(boolean val) {readOnly = val; return this;} private boolean readOnly;
public boolean Hidden() {return hidden;} public IoItmAttrib Hidden_() {return Hidden_(true);} public IoItmAttrib Hidden_(boolean val) {hidden = val; return this;} private boolean hidden;
public static IoItmAttrib readOnly_() {return new IoItmAttrib().ReadOnly_();}
public static IoItmAttrib hidden_() {return new IoItmAttrib().Hidden_();}
public static IoItmAttrib normal_() {return new IoItmAttrib().ReadOnly_(false).Hidden_(false);}
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoItmClassXtn extends ClassXtn_base implements ClassXtn {
public String Key() {return Key_const;} public static final String Key_const = "ioItemType";
@Override public Class<?> UnderClass() {return int.class;}
public Object DefaultValue() {return IoItmDir.Type_Dir;}
public boolean Eq(Object lhs, Object rhs) {return ((IoItm_base)lhs).compareTo(rhs) == CompareAble_.Same;}
@Override public Object ParseOrNull(String raw) {
String rawLower = String_.Lower(raw);
if (String_.Eq(rawLower, "dir")) return IoItmDir.Type_Dir;
else if (String_.Eq(rawLower, "fil")) return IoItmFil.Type_Fil;
else throw Err_.new_unhandled(raw);
}
@Override public Object XtoDb(Object obj) {return Int_.cast(obj);}
public static final IoItmClassXtn Instance = new IoItmClassXtn(); IoItmClassXtn() {}
}

View File

@@ -0,0 +1,71 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.criterias.*;
public class IoItmDir extends IoItm_base {
public boolean Exists() {return exists;} public void Exists_set(boolean v) {exists = v;} private boolean exists = true;
@Override public int TypeId() {return Type_Dir;} @Override public boolean Type_dir() {return true;} @Override public boolean Type_fil() {return false;} public static final int Type_Dir = 1;
@gplx.New public IoItmDir XtnProps_set(String key, Object val) {return (IoItmDir)super.XtnProps_set(key, val);}
public IoItmList SubDirs() {return subDirs;} IoItmList subDirs;
public IoItmList SubFils() {return subFils;} IoItmList subFils;
public IoItmHash XtoIoItmList(Criteria crt) {
IoItmHash rv = IoItmHash.list_(this.Url());
XtoItmList_recur(rv, this, crt);
return rv;
}
Io_url[] XtoIoUrlAry() {
IoItmHash list = this.XtoIoItmList(Criteria_.All);
//#plat_wce list.Sort(); // NOTE: on wce, subFils retrieved in unexpected order; createTime vs pathString
int count = list.Count();
Io_url[] rv = new Io_url[count];
for (int i = 0; i < count; i++)
rv[i] = list.Get_at(i).Url();
return rv;
}
public IoItmDir FetchDeepOrNull(Io_url findDirUrl) {
String dirSpr = this.Url().Info().DirSpr(); int dirSprLen = String_.Len(dirSpr);
String currDirStr = this.Url().Raw();
String findDirStr = findDirUrl.Raw();
if (!String_.Has_at_bgn(findDirStr, currDirStr)) return null; // findUrl must start with currUrl;
String findName = String_.DelEnd(currDirStr, dirSprLen); // seed findName for String_.MidByLen below;
IoItmDir curDir = this;
while (true) {
findDirStr = String_.DelBgn(findDirStr, String_.Len(findName) + dirSprLen); // NOTE: findName will never have trailingDirSpr; subDirs.Get_by() takes NameOnly; ex: "dir" not "dir\"
int nextDirSprPos = String_.FindFwd(findDirStr, dirSpr); if (nextDirSprPos == String_.Find_none) nextDirSprPos = String_.Len(findDirStr);
findName = String_.MidByLen(findDirStr, 0, nextDirSprPos);
if (String_.Eq(findDirStr, "")) return curDir; // findDirStr completely removed; all parts match; return curDir
curDir = IoItmDir_.as_(curDir.subDirs.Get_by(findName)); // try to find dir
if (curDir == null) return null; // dir not found; exit; NOTE: if dir found, loop restarts; with curDir as either findDir, or owner of findDir
}
}
void XtoItmList_recur(IoItmHash list, IoItmDir curDir, Criteria dirCrt) {
for (Object subFilObj : curDir.SubFils()) {
IoItmFil subFil = (IoItmFil)subFilObj;
list.Add(subFil);
}
for (Object subDirObj : curDir.SubDirs()) {
IoItmDir subDir = (IoItmDir)subDirObj;
if (dirCrt.Matches(subDir)) list.Add(subDir);
XtoItmList_recur(list, subDir, dirCrt);
}
}
@gplx.Internal protected IoItmDir(boolean caseSensitive) {
subDirs = IoItmList.new_(this, caseSensitive);
subFils = IoItmList.new_(this, caseSensitive);
}
}

View 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.ios; import gplx.*; import gplx.core.*;
public class IoItmDir_ {
public static IoItmDir as_(Object obj) {return obj instanceof IoItmDir ? (IoItmDir)obj : null;}
public static final IoItmDir Null = null_();
public static IoItmDir top_(Io_url url) {return scan_(url);}
public static IoItmDir scan_(Io_url url) {
IoItmDir rv = new IoItmDir(url.Info().CaseSensitive());
rv.ctor_IoItmBase_url(url);
return rv;
}
public static IoItmDir sub_(String name) {
IoItmDir rv = new IoItmDir(Bool_.Y);
rv.ctor_IoItmBase_url(Io_url_.mem_dir_("mem/" + name));
return rv;
}
static IoItmDir null_() {
IoItmDir rv = new IoItmDir(true); // TODO: NULL should be removed
rv.ctor_IoItmBase_url(Io_url_.Empty);
rv.Exists_set(false);
return rv;
}
public static void Make(IoItmDir dir) {
Io_mgr.Instance.CreateDir(dir.Url());
int len = dir.SubDirs().Count();
for (int i = 0; i < len; ++i) {
IoItmDir sub_dir = (IoItmDir)dir.SubDirs().Get_at(i);
Make(sub_dir);
}
len = dir.SubFils().Count();
for (int i = 0; i < len; ++i) {
IoItmFil sub_fil = (IoItmFil)dir.SubFils().Get_at(i);
String text = String_.Repeat("a", (int)sub_fil.Size());
Io_url sub_url = sub_fil.Url();
Io_mgr.Instance.SaveFilStr(sub_url, text);
Io_mgr.Instance.UpdateFilModifiedTime(sub_url, sub_fil.ModifiedTime());
}
}
}

View 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.ios; import gplx.*; import gplx.core.*;
public class IoItmFil extends IoItm_base {
@Override public int TypeId() {return IoItmFil.Type_Fil;} @Override public boolean Type_dir() {return false;} @Override public boolean Type_fil() {return true;} public static final int Type_Fil = 2;
public boolean Exists() {return size != Size_invalid;} // NOTE: questionable logic, but preserved for historical reasons; requires that length be set to -1 if !.exists
public DateAdp ModifiedTime() {return modifiedTime;}
public IoItmFil ModifiedTime_(DateAdp val) {modifiedTime = val; return this;} DateAdp modifiedTime;
public IoItmFil ModifiedTime_(String val) {return ModifiedTime_(DateAdp_.parse_gplx(val));}
@gplx.Virtual public long Size() {return size;} public IoItmFil Size_(long val) {size = val; return this;} private long size;
public IoItmAttrib Attrib() {return attrib;} public IoItmFil Attrib_(IoItmAttrib val) {attrib = val; return this;} IoItmAttrib attrib = IoItmAttrib.normal_();
public boolean ReadOnly() {return attrib.ReadOnly();} public IoItmFil ReadOnly_(boolean val) {attrib.ReadOnly_(val); return this;}
@gplx.New public IoItmFil XtnProps_set(String key, Object val) {return (IoItmFil)super.XtnProps_set(key, val);}
@gplx.Internal protected IoItmFil ctor_IoItmFil(Io_url url, long size, DateAdp modifiedTime) {
ctor_IoItmBase_url(url); this.size = size; this.modifiedTime = modifiedTime;
return this;
}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, IoItmFil_.Prop_Size)) return size;
else if (ctx.Match(k, IoItmFil_.Prop_Modified)) return modifiedTime;
else return super.Invk(ctx, ikey, k, m);
}
@gplx.Internal protected IoItmFil() {}
public static final long Size_invalid = -1;
public static final int Size_invalid_int = -1;
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoItmFil_ {
public static IoItmFil as_(Object obj) {return obj instanceof IoItmFil ? (IoItmFil)obj : null;}
public static final String
Prop_Size = "size"
, Prop_Modified = "modified";
public static IoItmFil new_(Io_url url, long size, DateAdp created, DateAdp modified) {return new IoItmFil().ctor_IoItmFil(url, size, modified);}
public static IoItmFil sub_(String name, long size, DateAdp modified) {
IoItmFil rv = new IoItmFil();
rv.ctor_IoItmFil(Io_url_.mem_fil_("mem/" + name), size, modified);
rv.Name_(name);
return rv;
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.ios.*; /*IoStream_mem*/ import gplx.core.texts.*; /*Encoding_*/
class IoItmFil_mem extends IoItmFil { public static IoItmFil_mem as_(Object obj) {return obj instanceof IoItmFil_mem ? (IoItmFil_mem)obj : null;}
@gplx.Internal protected IoStream_mem Stream() {return stream;} IoStream_mem stream; // NOTE: using stream instead of Text, b/c no events for IoStream.Dispose; ex: stream.OpenStreamWrite; stream.Write("hi"); stream.Dispose(); "hi" would not be saved if Text is member variable
@Override public long Size() {return (int)stream.Len();}
public String Text() {return Text_get();} public void Text_set(String v) {stream = IoStream_mem.rdr_txt_(this.Url(), v);}
String Text_get() {
int len = (int)stream.Len();
byte[] buffer = new byte[len];
stream.Position_set(0);
stream.Read(buffer, 0, len);
return String_.new_u8(buffer);
}
public IoItmFil_mem Clone() {return new_(this.Url(), this.Size(), this.ModifiedTime(), this.Text());}
public static IoItmFil_mem new_(Io_url filPath, long size, DateAdp modified, String text) {
IoItmFil_mem rv = new IoItmFil_mem();
rv.ctor_IoItmFil(filPath, size, modified);
rv.stream = IoStream_mem.rdr_txt_(filPath, text);
return rv;
}
public static final IoItmFil_mem Null = new_(Io_url_.Empty, -1, DateAdp_.MinValue, ""); // NOTE: size must be -1 for .Exists to be false; DATE:2015-05-16
}

View File

@@ -0,0 +1,43 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoItmHash extends Ordered_hash_base {
public Io_url Url() {return url;} Io_url url;
public void Add(IoItm_base itm) {Add_base(MakeKey(itm.Url()), itm);}
public void Del(Io_url url) {Del(MakeKey(url));}
public IoItm_base Get_by(Io_url url) {return IoItm_base_.as_(Fetch_base(MakeKey(url)));}
@gplx.New public IoItm_base Get_at(int i) {return IoItm_base_.as_(Get_at_base(i));}
public Io_url[] XtoIoUrlAry() {
int count = this.Count();
Io_url[] rv = new Io_url[count];
for (int i = 0; i < count; i++)
rv[i] = this.Get_at(i).Url();
return rv;
}
String MakeKey(Io_url url) {return url.XtoCaseNormalized();}
public static IoItmHash new_() {
IoItmHash rv = new IoItmHash();
rv.url = null;//Io_url_.Empty;
return rv;
} IoItmHash() {}
public static IoItmHash list_(Io_url url) {
IoItmHash rv = new IoItmHash();
rv.url = url;
return rv;
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
import gplx.lists.*; /*Ordered_hash_base*/
public class IoItmList extends Ordered_hash_base {
public boolean Has(Io_url url) {return Has_base(MakeKey(url));}
public void Add(IoItm_base itm) {
if (ownerDir != null) itm.OwnerDir_set(ownerDir);
Add_base(MakeKey(itm.Url()), itm);
}
public void Del(Io_url url) {
String key = MakeKey(url);
IoItm_base itm = IoItm_base_.as_(Fetch_base(key)); if (itm == null) return;
itm.OwnerDir_set(null);
super.Del(key);
}
public Io_url[] XtoIoUrlAry() {
int count = this.Count();
Io_url[] rv = new Io_url[count];
for (int i = 0; i < count; i++)
rv[i] = IoItm_base_.as_(i).Url();
return rv;
}
@Override public void Sort() {Sort_by(IoItmBase_comparer_nest.Instance);}
@Override protected Object Fetch_base(Object keyObj) {
String key = MakeKey((String)keyObj);
return super.Fetch_base(key);
}
@Override public void Del(Object keyObj) {
String key = MakeKey((String)keyObj);
super.Del(key);
}
String MakeKey(Io_url url) {
String itmName = url.Type_dir() ? url.NameOnly() : url.NameAndExt();
return MakeKey(itmName);
}
String MakeKey(String s) {
return caseSensitive ? s : String_.Lower(s);
}
IoItmDir ownerDir; boolean caseSensitive;
@gplx.Internal protected static IoItmList new_(IoItmDir v, boolean caseSensitive) {
IoItmList rv = new IoItmList();
rv.ownerDir = v; rv.caseSensitive = caseSensitive;
return rv;
}
@gplx.Internal protected static IoItmList list_(boolean caseSensitive) {return new_(null, caseSensitive);}
}
class IoItmBase_comparer_nest implements ComparerAble {
public int compare(Object lhsObj, Object rhsObj) {
IoItm_base lhsItm = (IoItm_base)lhsObj, rhsItm = (IoItm_base)rhsObj;
Io_url lhsUrl = lhsItm.Url(), rhsUrl = rhsItm.Url();
return String_.Eq(lhsUrl.OwnerDir().Raw(), rhsUrl.OwnerDir().Raw()) // is same dir
? CompareAble_.Compare_obj(lhsUrl.NameAndExt(), rhsUrl.NameAndExt()) // same dir: compare name
: CompareAble_.Compare_obj(DepthOf(lhsItm), DepthOf(rhsItm)); // diff dir: compare by depth; ex: c:\fil.txt < c:\dir\fil.txt
}
int DepthOf(IoItm_base itm) {
Io_url url = itm.Url();
return String_.Count(url.OwnerDir().Raw(), url.Info().DirSpr()); // use OwnerDir, else dir.Raw will return extra dirSeparator
}
public static final IoItmBase_comparer_nest Instance = new IoItmBase_comparer_nest(); IoItmBase_comparer_nest() {}
}

View File

@@ -0,0 +1,53 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public abstract class IoItm_base implements GfoInvkAble, CompareAble {
public abstract int TypeId(); public abstract boolean Type_dir(); public abstract boolean Type_fil();
public Io_url Url() {return ownerDir == null ? url : ownerDir.Url().GenSubFil(name); /*NOTE: must call .Url*/} Io_url url;
public IoItmDir OwnerDir() {return ownerDir;} IoItmDir ownerDir;
public void OwnerDir_set(IoItmDir v) {if (v == this) throw Err_.new_wo_type("dir cannot be its own owner", "url", v.url.Raw());
url = v == null && ownerDir != null
? ownerDir.url.GenSubFil(name) // create url, since ownerDir will soon be null; NOTE: must call .url
: Io_url_.Empty; // delete url, since ownerDir will be avail
ownerDir = v;
}
public String Name() {return name;} private String name;
public IoItm_base Name_(String v) {
name = v;
if (ownerDir == null) url = url.OwnerDir().GenSubFil(name);
return this;
}
public Object XtnProps_get(String key) {return props.Get_by(key);} Hash_adp props = Hash_adp_.Noop;
public IoItm_base XtnProps_set(String key, Object val) {
if (props == Hash_adp_.Noop) props = Hash_adp_.new_();
props.Del(key);
props.Add(key, val);
return this;
}
public int compareTo(Object comp) {return url.compareTo(((IoItm_base)comp).url);} // NOTE: needed for comic importer (sort done on IoItmHash which contains IoItm_base)
// public Object Data_get(String name) {return GfoInvkAble_.InvkCmd(this, name);}
@gplx.Virtual public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, IoItm_base_.Prop_Type)) return this.TypeId();
else if (ctx.Match(k, IoItm_base_.Prop_Path)) return this.Url();
else if (ctx.Match(k, IoItm_base_.Prop_Title)) return this.Url().NameOnly(); // needed for gfio script criteria;
else if (ctx.Match(k, IoItm_base_.Prop_Ext)) return this.Url().Ext(); // needed for gfio script criteria; EX: where "ext LIKE '.java'"
else return GfoInvkAble_.Rv_unhandled;
}
@gplx.Internal protected void ctor_IoItmBase_url(Io_url url) {this.url = url; this.name = url.NameAndExt();}
@gplx.Internal protected void ctor_IoItmBase_name(String name) {this.name = name;}
}

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoItm_base_ {
public static IoItm_base as_(Object obj) {return obj instanceof IoItm_base ? (IoItm_base)obj : null;}
public static final String
Prop_Type = "type"
, Prop_Path = "url"
, Prop_Title = "title"
, Prop_Ext = "ext";
}

View File

@@ -0,0 +1,60 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class IoRecycleBin {
public void Send(Io_url url) {Send_xrg(url).Exec();}
public IoEngine_xrg_recycleFil Send_xrg(Io_url url) {return IoEngine_xrg_recycleFil.gplx_(url);}
public void Recover(Io_url url) {
String_bldr sb = String_bldr_.new_();
List_adp list = Regy_search(url, sb);
int listCount = list.Count(); if (listCount > 1) throw Err_.new_wo_type("found more than 1 url", "count", list.Count());
Io_url trgUrl = (Io_url)list.Get_at(0);
IoEngine_xrg_xferFil.move_(url, trgUrl).ReadOnlyFails_(true).Overwrite_(false).Exec();
IoEngine_xrg_saveFilStr.new_(FetchRegistryUrl(url), sb.To_str()).Exec();
}
public void Regy_add(IoEngine_xrg_recycleFil xrg) {
Io_url url = xrg.RecycleUrl();
Io_url regyUrl = FetchRegistryUrl(url);
String text = String_.Concat_with_obj("|", url.NameAndExt_noDirSpr(), xrg.Url().GenRelUrl_orEmpty(url.OwnerRoot()), xrg.Uuid().To_str(), xrg.AppName(), xrg.Time());
IoEngine_xrg_saveFilStr.new_(regyUrl, text).Append_().Exec();
}
public List_adp Regy_search(Io_url url, String_bldr sb) {
List_adp list = List_adp_.new_();
Io_url regyUrl = FetchRegistryUrl(url);
String[] lines = IoEngine_xrg_loadFilStr.new_(regyUrl).ExecAsStrAry();
int linesLen = Array_.Len(lines);
String nameAndExt = url.NameAndExt_noDirSpr() + "|";
for (int i = linesLen; i > 0; i--) {
String line = lines[i - 1];
if (String_.Has_at_bgn(line, nameAndExt)) {
String[] terms = String_.Split(line, "|");
Io_url origUrl = url.OwnerRoot().GenSubFil(terms[1]);
list.Add(origUrl);
}
else
sb.Add_str_w_crlf(line);
}
return list;
}
Io_url FetchRegistryUrl(Io_url url) {
String sourceApp = String_.GetStrBefore(url.NameAndExt_noDirSpr(), ";");
return url.OwnerDir().GenSubFil_ary(sourceApp, ".recycle.csv");
}
public static final IoRecycleBin Instance = new IoRecycleBin(); IoRecycleBin() {}
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public interface IoStream extends RlsAble {
Object UnderRdr();
Io_url Url();
long Pos();
long Len();
int ReadAry(byte[] array);
int Read(byte[] array, int offset, int count);
long Seek(long pos);
void WriteAry(byte[] ary);
void Write(byte[] array, int offset, int count);
void Transfer(IoStream trg, int bufferLength);
void Flush();
void Write_and_flush(byte[] bry, int bgn, int end);
}

View File

@@ -0,0 +1,180 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
public class IoStream_ {
public static final IoStream Null = new IoStream_null();
public static IoStream mem_txt_(Io_url url, String v) {return IoStream_mem.rdr_txt_(url, v);}
public static IoStream ary_(byte[] v) {return IoStream_mem.rdr_ary_(Io_url_.Empty, v);}
public static final byte Mode_rdr = 0, Mode_wtr_create = 1, Mode_wtr_append = 2, Mode_wtr_update = 3;
public static IoStream stream_rdr_() {return new IoStream_stream_rdr();}
public static IoStream stream_input_(Io_url url) {return new IoStream_stream_rdr().UnderRdr_(input_stream_(url));}
public static Object input_stream_(Io_url url) {
try {
return new java.io.FileInputStream(url.Raw());
} catch (Exception e) {throw Err_.new_wo_type("file not found", "url", url.Raw());}
}
}
class IoStream_null implements IoStream {
public Object UnderRdr() {return null;}
public Io_url Url() {return Io_url_.Empty;}
public long Pos() {return -1;}
public long Len() {return -1;}
public int ReadAry(byte[] array) {return -1;}
public int Read(byte[] array, int offset, int count) {return -1;}
public long Seek(long pos) {return -1;}
public void WriteAry(byte[] ary) {}
public void Write(byte[] array, int offset, int count) {}
public void Transfer(IoStream trg, int bufferLength) {}
public void Flush() {}
public void Write_and_flush(byte[] bry, int bgn, int end) {}
public void Rls() {}
}
class IoStream_base implements IoStream {
@gplx.Virtual public Io_url Url() {return url;} Io_url url = Io_url_.Empty;
public void Transfer(IoStream trg, int bufferLength) {
byte[] buffer = new byte[bufferLength];
int read = -1;
while (read != 0) {
read = this.Read(buffer, 0, bufferLength);
trg.Write(buffer, 0, read);
}
trg.Flush();
}
public int ReadAry(byte[] ary) {return this.Read(ary, 0, ary.length);}
public void WriteAry(byte[] ary) {this.Write(ary, 0, ary.length);}
@gplx.Virtual public Object UnderRdr() {return under;}
@gplx.Virtual public void UnderRdr_(Object v) {this.under = (RandomAccessFile)v;}
@gplx.Virtual public long Pos() {return pos;} long pos;
@gplx.Virtual public long Len() {return length;} long length;
@gplx.Virtual public int Read(byte[] array, int offset, int count) {
try {
int rv = under.read(array, offset, count);
return rv == -1 ? 0 : rv; // NOTE: fis returns -1 if nothing read; .NET returned 0; Hash will fail if -1 returned (will try to create array of 0 length)
} // NOTE: fis keeps track of offset, only need to pass in array (20110606: this NOTE no longer seems to make sense; deprecate)
catch (IOException e) {throw Err_.new_exc(e, "io", "file read failed", "url", url);}
}
public long Seek(long seek_pos) {
try {
under.seek(seek_pos);
pos = under.getFilePointer();
return pos;
}
catch (IOException e) {throw Err_.new_exc(e, "io", "seek failed", "url", url);}
}
@gplx.Virtual public void Write(byte[] array, int offset, int count) {bfr.Add_mid(array, offset, offset + count); this.Flush();} Bry_bfr bfr = Bry_bfr.reset_(16);
public void Write_and_flush(byte[] bry, int bgn, int end) {
// ConsoleAdp._.WriteLine(bry.length +" " + bgn + " " + end);
Flush();// flush anything already in buffer
int buffer_len = Io_mgr.Len_kb * 16;
byte[] buffer = new byte[buffer_len];
int buffer_bgn = bgn; boolean loop = true;
while (loop) {
int buffer_end = buffer_bgn + buffer_len;
if (buffer_end > end) {
buffer_end = end;
buffer_len = end - buffer_bgn;
loop = false;
}
for (int i = 0; i < buffer_len; i++)
buffer[i] = bry[i + buffer_bgn];
try {under.write(buffer, 0, buffer_len);}
catch (IOException e) {throw Err_.new_exc(e, "io", "write failed", "url", url);}
buffer_bgn = buffer_end;
}
// this.Rls();
// OutputStream output_stream = null;
// try {
// output_stream = new FileOutputStream(url.Xto_api());
// bry = ByteAry_.Mid(bry, bgn, end);
// output_stream.write(bry, 0, bry.length);
// }
// catch (IOException e) {throw Err_.err_key_(e, IoEngineArgs._.Err_IoException, "write failed").Add("url", url);}
// finally {
// if (output_stream != null) {
// try {output_stream.close();}
// catch (IOException ignore) {}
// }
// }
}
@gplx.Virtual public void Flush() {
try {
if (mode_is_append) under.seek(under.length());
// else under.seek(0);
}
catch (IOException e) {throw Err_.new_exc(e, "io", "seek failed", "url", url);}
try {under.write(bfr.Bfr(), 0, bfr.Len());}
catch (IOException e) {throw Err_.new_exc(e, "io", "write failed", "url", url);}
bfr.Clear();
}
@gplx.Virtual public void Rls() {
IoEngine_system.Closeable_close(under, url, true);
}
RandomAccessFile under; boolean mode_is_append; byte mode;
public static IoStream_base rdr_wrapper_() {return new IoStream_base();}
public static IoStream_base new_(Io_url url, int mode) {
IoStream_base rv = new IoStream_base();
rv.url = url;
rv.mode = (byte)mode;
File file = new File(url.Xto_api());
String ctor_mode = "";
switch (mode) { // mode; SEE:NOTE_1
case IoStream_.Mode_wtr_append:
rv.mode_is_append = mode == IoStream_.Mode_wtr_append;
ctor_mode = "rws";
break;
case IoStream_.Mode_wtr_create:
ctor_mode = "rws";
break;
case IoStream_.Mode_rdr:
ctor_mode = "r";
break;
}
try {rv.under = new RandomAccessFile(file, ctor_mode);}
catch (FileNotFoundException e) {throw Err_.new_exc(e, "io", "file open failed", "url", url);}
if (mode == IoStream_.Mode_wtr_create) {
try {rv.under.setLength(0);}
catch (IOException e) {throw Err_.new_exc(e, "io", "file truncate failed", "url", url);}
}
rv.length = file.length();
return rv;
}
public static IoStream_base new_(Object stream) {
IoStream_base rv = new IoStream_base();
// rv.stream = (System.IO.Stream)stream;
rv.url = Io_url_.Empty;
return rv;
}
}
/*
NOTE_1:stream mode
my understanding of mode
rw: read/write async?
rws: read/write sync; write content + metadata changes
rwd: read/write sync; write content
*/
//#}

View File

@@ -0,0 +1,70 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.texts.*; /*Encoding_*/
class IoStream_mem extends IoStream_base {
@Override public Io_url Url() {return url;} Io_url url;
@Override public Object UnderRdr() {throw Err_.new_unimplemented();} // NOTE: should not use System.IO.MemoryStream, b/c resized data will not be captured in this instance's buffer
@Override public long Len() {return Array_.Len(buffer);}
public int Position() {return position;} public void Position_set(int v) {position = v;} int position;
public byte[] Buffer() {return buffer;} private byte[] buffer = new byte[0];
@Override public int Read(byte[] array, int offset, int count) {
int read = 0;
int len = Array_.Len(buffer);
for (int i = 0; i < count; i++) {
if (position + i >= len) break;
array[offset + i] = buffer[position + i];
read++;
}
position += read;
return read;
}
@Override public void Write(byte[] array, int offset, int count) {
// expand buffer if needed; necessary to emulate fileStream writing; ex: FileStream fs = new FileStream(); fs.Write(data); where data may be unknown length
int length = (int)position + count + -offset;
int bufLen = Array_.Len(buffer);
if (bufLen < length) buffer = Bry_.Resize(buffer, length);
for (int i = 0; i < count; i++)
buffer[position + i] = array[offset + i];
position += count +-offset;
}
@Override public long Pos() {return position;}
@Override public long Seek(long pos) {
this.position = (int)pos;
return pos;
}
@Override public void Flush() {}
@Override public void Rls() {}
public static IoStream_mem rdr_txt_(Io_url url, String v) {return rdr_ary_(url, Bry_.new_u8(v));}
public static IoStream_mem rdr_ary_(Io_url url, byte[] v) {
IoStream_mem rv = new IoStream_mem();
rv.buffer = v;
rv.url = url;
return rv;
}
public static IoStream_mem wtr_data_(Io_url url, int length) {
IoStream_mem rv = new IoStream_mem();
rv.buffer = new byte[length];
rv.url = url;
return rv;
}
IoStream_mem() {}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import org.junit.*; //using System.IO; /*Stream*/
public class IoStream_mem_tst {
@Test public void Write() { // confirm that changes written to Stream acquired via .AdpObj are written to IoStream_mem.Buffer
IoStream_mem stream = IoStream_mem.wtr_data_(Io_url_.Empty, 0);
byte[] data = Bry_.new_ints(1);
stream.Write(data, 0, Array_.Len(data));
Tfds.Eq(1L , stream.Len());
Tfds.Eq((byte)1 , stream.Buffer()[0]);
stream.Rls();
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public class IoStream_mock implements IoStream {
public byte[] Data_bry() {return data_bry;} public IoStream_mock Data_bry_(byte[] v) {data_bry = v; data_bry_len = v.length; return this;} private byte[] data_bry; int data_bry_len;
public int Data_bry_pos() {return data_bry_pos;} int data_bry_pos;
public void Reset() {data_bry_pos = 0;}
public IoStream_mock Read_limit_(int v) {read_limit = v; return this;} int read_limit;
public int Read(byte[] bfr, int bfr_bgn, int bfr_len) {
int bytes_read = bfr_len;
if (bytes_read > read_limit) bytes_read = read_limit; // stream may limit maximum read; EX: bfr_len of 16k but only 2k will be filled
int bytes_left = data_bry_len - data_bry_pos;
if (bytes_read > bytes_left) bytes_read = bytes_left; // not enough bytes left in data_bry; bytes_read = whatever is left
Bry_.Copy_by_pos(data_bry, data_bry_pos, data_bry_pos + bytes_read, bfr, bfr_bgn);
data_bry_pos += bytes_read;
return bytes_read;
}
public Object UnderRdr() {return null;}
public Io_url Url() {return Io_url_.Empty;}
public long Pos() {return -1;}
public long Len() {return -1;}
public int ReadAry(byte[] array) {return -1;}
public long Seek(long pos) {return -1;}
public void WriteAry(byte[] ary) {}
public void Write(byte[] array, int offset, int count) {}
public void Transfer(IoStream trg, int bufferLength) {}
public void Flush() {}
public void Write_and_flush(byte[] bry, int bgn, int end) {}
public void Rls() {}
}

View File

@@ -0,0 +1,48 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import org.junit.*;
public class IoStream_mock_tst {
@Before public void init() {fxt.Clear();} IoStream_mock_fxt fxt = new IoStream_mock_fxt();
@Test public void Basic() {
fxt.Init_src_str_("abcde").Init_trg_len_(5).Init_rdr_limit_(2).Init_read_len_(2);
fxt.Test_read("ab").Test_read("cd").Test_read("e");
}
@Test public void Read_limit() {
fxt.Init_src_str_("abcde").Init_trg_len_(5).Init_rdr_limit_(2).Init_read_len_(4);
fxt.Test_read("ab").Test_read("cd").Test_read("e");
}
}
class IoStream_mock_fxt {
public void Clear() {
if (rdr == null)
rdr = new IoStream_mock();
rdr.Reset();
trg_bgn = 0;
} IoStream_mock rdr; byte[] trg_bry;
public IoStream_mock_fxt Init_src_str_(String v) {rdr.Data_bry_(Bry_.new_a7(v)); return this;}
public IoStream_mock_fxt Init_trg_len_(int v) {trg_bry = new byte[v]; return this;}
public IoStream_mock_fxt Init_read_len_(int v) {read_len = v; return this;} int read_len;
public IoStream_mock_fxt Init_rdr_limit_(int v) {rdr.Read_limit_(v); return this;}
public IoStream_mock_fxt Test_read(String expd) {
int bytes_read = rdr.Read(trg_bry, trg_bgn, read_len);
Tfds.Eq(expd, String_.new_a7(trg_bry, trg_bgn, trg_bgn + bytes_read));
trg_bgn += bytes_read;
return this;
} int trg_bgn;
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public class IoStream_stream_rdr implements IoStream {
public int Read(byte[] bfr, int bfr_bgn, int bfr_len) {
try {
return stream.read(bfr, bfr_bgn, bfr_len);
}
catch (Exception e) {throw Err_.new_exc(e, "core", "failed to read from stream");}
}
public IoStream UnderRdr_(Object v) {this.stream = (java.io.InputStream)v; return this;} java.io.InputStream stream;
public Object UnderRdr() {return stream;}
public Io_url Url() {return Io_url_.Empty;}
public long Pos() {return -1;}
public long Len() {return -1;}
public int ReadAry(byte[] array) {return -1;}
public long Seek(long pos) {return -1;}
public void WriteAry(byte[] ary) {}
public void Write(byte[] array, int offset, int count) {}
public void Transfer(IoStream trg, int bufferLength) {}
public void Flush() {}
public void Write_and_flush(byte[] bry, int bgn, int end) {}
public void Rls() {}
}

View File

@@ -0,0 +1,244 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public interface IoUrlInfo {
String Key();
byte DirSpr_byte();
String DirSpr();
boolean CaseSensitive();
String EngineKey();
boolean Match(String raw);
boolean IsDir(String raw);
String Xto_api(String raw);
String OwnerDir(String raw);
String OwnerRoot(String raw);
String NameAndExt(String raw);
String NameOnly(String raw);
String Ext(String raw);
String XtoRootName(String raw, int rawLen);
}
class IoUrlInfo_nil implements IoUrlInfo {
public String Key() {return KeyConst;} public static final String KeyConst = String_.Null_mark;
public String EngineKey() {return "<<INVALID>>";}
public String DirSpr() {return "<<INVALID>>";}
public byte DirSpr_byte() {return Byte_ascii.Slash;}
public String VolSpr() {return "<<INVALID>>";}
public boolean CaseSensitive() {return false;}
public boolean Match(String raw) {return false;}
public boolean IsDir(String raw) {return false;}
public String Xto_api(String raw) {return "";}
public String OwnerDir(String raw) {return IoUrlInfo_base.NullString;}
public String OwnerRoot(String raw) {return IoUrlInfo_base.NullString;}
public String NameAndExt(String raw) {return "";}
public String NameOnly(String raw) {return "";}
public String Ext(String raw) {return "";}
public String XtoRootName(String raw, int rawLen) {return "";}
public static final IoUrlInfo_nil Instance = new IoUrlInfo_nil(); IoUrlInfo_nil() {}
}
abstract class IoUrlInfo_base implements IoUrlInfo {
@gplx.Internal protected static final int DirSprLen = 1;
@gplx.Internal protected static final String NullString = "", ExtSeparator = ".";
public abstract String Key();
public abstract byte DirSpr_byte();
public abstract String DirSpr();
public abstract boolean CaseSensitive();
public abstract boolean Match(String raw);
public abstract String EngineKey();
public boolean IsDir(String raw) {return String_.Has_at_end(raw, DirSpr());}
public abstract String XtoRootName(String raw, int rawLen);
@gplx.Virtual public String Xto_api(String raw) {
return IsDir(raw)
? String_.DelEnd(raw, IoUrlInfo_base.DirSprLen) // if Dir, remove trailing DirSpr, since most api will not expect it (ex: .Delete will malfunction)
: raw;
}
public String OwnerDir(String raw) {
int rawLen = String_.Len(raw);
int ownerDirSprPos = OwnerDirPos(raw, rawLen);
if (ownerDirSprPos <= OwnerDirPos_hasNoOwner) return IoUrlInfo_base.NullString; // no ownerDir found; return Null; only (a) NullUrls (b) RootUrls ("C:\") (c) relative ("fil.txt")
return String_.MidByLen(raw, 0, ownerDirSprPos + 1); // +1 to include backslash
}
@gplx.Virtual public String OwnerRoot(String raw) {
String temp = raw, rv = raw;
while (true) {
temp = OwnerDir(temp);
if (String_.Eq(temp, IoUrlInfo_base.NullString)) break;
rv = temp;
}
return rv;
}
public String NameAndExt(String raw) { // if Dir, will return \ as last char
int rawLen = String_.Len(raw);
int ownerDirSprPos = OwnerDirPos(raw, rawLen);
if (ownerDirSprPos == OwnerDirPos_isNull) return IoUrlInfo_base.NullString; // NullUrl and RootUrl return Null;
return ownerDirSprPos == OwnerDirPos_hasNoOwner || ownerDirSprPos == OwnerDirPos_isRoot
? raw // no PathSeparator b/c (a) RootDir ("C:\"); (b) relative ("fil.txt")
: String_.DelBgn(raw, ownerDirSprPos + 1); // +1 to skip backslash
}
public String NameOnly(String raw) {
String nameAndExt = NameAndExt(raw);
if (IsDir(raw)) {
String rootName = XtoRootName(raw, String_.Len(raw)); // C:\ -> C; / -> root
return rootName == null
? String_.DelEnd(nameAndExt, IoUrlInfo_base.DirSprLen)
: rootName;
}
int pos = String_.FindBwd(nameAndExt, IoUrlInfo_base.ExtSeparator);
return pos == String_.Find_none
? nameAndExt // Ext not found; return entire NameAndExt
: String_.MidByLen(nameAndExt, 0, pos);
}
public String Ext(String raw) { // if Dir, return DirSpr; if Fil, return . as first char; ex: .txt; .png
if (IsDir(raw)) return this.DirSpr();
String nameAndExt = NameAndExt(raw);
int pos = String_.FindBwd(nameAndExt, IoUrlInfo_base.ExtSeparator);
return pos == String_.Find_none ? "" : String_.DelBgn(nameAndExt, pos);
}
int OwnerDirPos(String raw, int rawLen) {
if (rawLen == 0) return OwnerDirPos_isNull;
else if (XtoRootName(raw, rawLen) != null) return OwnerDirPos_isRoot;
else {// NullUrls and RootUrls have no owners
int posAdj = IsDir(raw) ? IoUrlInfo_base.DirSprLen : 0; // Dir ends with DirSpr, adjust lastIndex by DirSprLen
return String_.FindBwd(raw, this.DirSpr(), rawLen - 1 - posAdj); // -1 to adjust for LastIdx
}
}
static final int
OwnerDirPos_hasNoOwner = -1 // List_adp_.NotFound
, OwnerDirPos_isNull = -2
, OwnerDirPos_isRoot = -3;
}
class IoUrlInfo_wnt extends IoUrlInfo_base {
@Override public String Key() {return "wnt";}
@Override public String EngineKey() {return IoEngine_.SysKey;}
@Override public String DirSpr() {return Op_sys.Wnt.Fsys_dir_spr_str();}
@Override public byte DirSpr_byte() {return Byte_ascii.Backslash;}
@Override public boolean CaseSensitive() {return Op_sys.Wnt.Fsys_case_match();}
@Override public boolean Match(String raw) {return String_.Len(raw) > 1 && String_.CharAt(raw, 1) == ':';} // 2nd char is :; assumes 1 letter drives
@Override public String XtoRootName(String raw, int rawLen) {
return rawLen == 3 && String_.CharAt(raw, 1) == ':' // only allow single letter drives; ex: C:\; note, CharAt(raw, 1) to match Match
? Char_.To_str(String_.CharAt(raw, 0))
: null;
}
public static final IoUrlInfo_wnt Instance = new IoUrlInfo_wnt(); IoUrlInfo_wnt() {}
}
class IoUrlInfo_lnx extends IoUrlInfo_base {
@Override public String Key() {return "lnx";}
@Override public String EngineKey() {return IoEngine_.SysKey;}
@Override public String DirSpr() {return DirSprStr;} static final String DirSprStr = Op_sys.Lnx.Fsys_dir_spr_str();
@Override public byte DirSpr_byte() {return Byte_ascii.Slash;}
@Override public boolean CaseSensitive() {return Op_sys.Lnx.Fsys_case_match();}
@Override public boolean Match(String raw) {return String_.Has_at_bgn(raw, DirSprStr);} // anything that starts with /
@Override public String XtoRootName(String raw, int rawLen) {
return rawLen == 1 && String_.Eq(raw, DirSprStr)
? "root"
: null;
}
@Override public String OwnerRoot(String raw) {return DirSprStr;} // drive is always /
@Override public String Xto_api(String raw) {
return String_.Eq(raw, DirSprStr) // is root
? DirSprStr
: super.Xto_api(raw); // NOTE: super.Xto_api will strip off last /
}
public static final IoUrlInfo_lnx Instance = new IoUrlInfo_lnx(); IoUrlInfo_lnx() {}
}
class IoUrlInfo_rel extends IoUrlInfo_base {
@Override public String Key() {return "rel";}
@Override public String EngineKey() {return IoEngine_.SysKey;}
@Override public String DirSpr() {return info.DirSpr();}
@Override public byte DirSpr_byte() {return info.DirSpr_byte();}
@Override public boolean CaseSensitive() {return info.CaseSensitive();}
@Override public String XtoRootName(String raw, int rawLen) {return info.XtoRootName(raw, rawLen);}
@Override public boolean Match(String raw) {return true;} // relPath is always lastResort; return true
IoUrlInfo info;
public static IoUrlInfo_rel new_(IoUrlInfo info) {
IoUrlInfo_rel rv = new IoUrlInfo_rel();
rv.info = info;
return rv;
} IoUrlInfo_rel() {}
}
class IoUrlInfo_mem extends IoUrlInfo_base {
@Override public String Key() {return key;} private String key;
@Override public String EngineKey() {return engineKey;} private String engineKey;
@Override public String DirSpr() {return "/";}
@Override public byte DirSpr_byte() {return Byte_ascii.Slash;}
@Override public boolean CaseSensitive() {return false;}
@Override public String XtoRootName(String raw, int rawLen) {
return String_.Eq(raw, key) ? String_.DelEnd(key, 1) : null;
}
@Override public boolean Match(String raw) {return String_.Has_at_bgn(raw, key);}
public static IoUrlInfo_mem new_(String key, String engineKey) {
IoUrlInfo_mem rv = new IoUrlInfo_mem();
rv.key = key; rv.engineKey = engineKey;
return rv;
} IoUrlInfo_mem() {}
}
class IoUrlInfo_alias extends IoUrlInfo_base {
@Override public String Key() {return srcDir;}
@Override public String EngineKey() {return engineKey;} private String engineKey;
@Override public String DirSpr() {return srcDirSpr;}
@Override public byte DirSpr_byte() {return srcDirSpr_byte;} private byte srcDirSpr_byte;
@Override public boolean CaseSensitive() {return false;}
@Override public String XtoRootName(String raw, int rawLen) {
return String_.Eq(raw, srcRootDir) ? srcRootName : null;
}
@Override public boolean Match(String raw) {return String_.Has_at_bgn(raw, srcDir);}
@Override public String Xto_api(String raw) {
String rv = String_.Replace(raw, srcDir, trgDir); // replace src with trg
if (!String_.Eq(srcDirSpr, trgDirSpr)) rv = String_.Replace(rv, srcDirSpr, trgDirSpr); // replace dirSprs
return IsDir(raw)
? String_.DelEnd(rv, IoUrlInfo_base.DirSprLen) // remove trailingSeparator, else Directory.Delete will not work properly
: rv;
}
void SrcDir_set(String v) {
srcDir = v;
boolean lnx = DirSpr_lnx(v);
if (srcDirSpr == null) {
if (lnx) {
srcDirSpr = Op_sys.Lnx.Fsys_dir_spr_str();
srcDirSpr_byte = Op_sys.Lnx.Fsys_dir_spr_byte();
}
else {
srcDirSpr = Op_sys.Wnt.Fsys_dir_spr_str();
srcDirSpr_byte = Op_sys.Wnt.Fsys_dir_spr_byte();
}
}
if (srcRootName == null) srcRootName = lnx ? "root" : String_.Mid(srcDir, 0, String_.FindFwd(srcDir, ":"));
if (srcRootDir == null) srcRootDir = lnx ? "/" : srcDir;
}
void TrgDir_set(String v) {
trgDir = v;
boolean lnx = DirSpr_lnx(v);
if (trgDirSpr == null) trgDirSpr = lnx ? Op_sys.Lnx.Fsys_dir_spr_str() : Op_sys.Wnt.Fsys_dir_spr_str();
}
boolean DirSpr_lnx(String s) {return String_.Has(s, Op_sys.Lnx.Fsys_dir_spr_str());}
void EngineKey_set(String v) {engineKey = v;}
String srcDir, trgDir, srcDirSpr, trgDirSpr, srcRootDir, srcRootName;
public static IoUrlInfo_alias new_(String srcDir, String trgDir, String engineKey) {
IoUrlInfo_alias rv = new IoUrlInfo_alias();
rv.SrcDir_set(srcDir);
rv.TrgDir_set(trgDir);
rv.EngineKey_set(engineKey);
return rv;
}
public static final IoUrlInfo_alias KEYS = new IoUrlInfo_alias();
public final String
Data_EngineKey = "engineKey"
, Data_SrcDir = "srcDir"
, Data_TrgDir = "trgDir"
;
}

View File

@@ -0,0 +1,52 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoUrlInfoRegy implements GfoInvkAble {
public void Reg(IoUrlInfo info) {hash.Add_if_dupe_use_nth(info.Key(), info);}
public IoUrlInfo Match(String raw) {
if (String_.Len(raw) == 0) return IoUrlInfo_.Nil;
for (int i = hash.Count(); i > 0; i--) {
IoUrlInfo info = (IoUrlInfo)hash.Get_at(i - 1);
if (info.Match(raw)) return info;
}
throw Err_.new_wo_type("could not match ioPathInfo", "raw", raw, "count", hash.Count());
}
public void Reset() {
hash.Clear();
Reg(IoUrlInfo_rel.new_(Op_sys.Cur().Tid_is_wnt() ? (IoUrlInfo)IoUrlInfo_wnt.Instance : (IoUrlInfo)IoUrlInfo_lnx.Instance));
Reg(IoUrlInfo_.Mem);
Reg(IoUrlInfo_lnx.Instance);
Reg(IoUrlInfo_wnt.Instance);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_Add)) {
String srcDirStr = m.ReadStr("srcDir");
String trgDirStr = m.ReadStr("trgDir");
String engineKey = m.ReadStrOr("engineKey", IoEngine_.SysKey);
if (ctx.Deny()) return this;
IoUrlInfo_alias alias = IoUrlInfo_alias.new_(srcDirStr, trgDirStr, engineKey);
IoUrlInfoRegy.Instance.Reg(alias);
}
return this;
} public static final String Invk_Add = "Add";
Ordered_hash hash = Ordered_hash_.New();
public static final IoUrlInfoRegy Instance = new IoUrlInfoRegy();
IoUrlInfoRegy() {
this.Reset();
}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class IoUrlInfo_ {
public static final IoUrlInfo Nil = IoUrlInfo_nil.Instance;
public static final IoUrlInfo Wnt = IoUrlInfo_wnt.Instance;
public static final IoUrlInfo Lnx = IoUrlInfo_lnx.Instance;
public static final IoUrlInfo Mem = IoUrlInfo_mem.new_("mem", IoEngine_.MemKey);
public static IoUrlInfo mem_(String key, String engineKey) {return IoUrlInfo_mem.new_(key, engineKey);}
public static IoUrlInfo alias_(String srcRoot, String trgRoot, String engineKey) {return IoUrlInfo_alias.new_(srcRoot, trgRoot, engineKey);}
}
/*
wnt C:\dir\fil.txt
wce \dir\fil.txt
lnx /dir/fil.txt
mem mem/dir/fil.txt
alias app:\dir\fil.txt
*/

View 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.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class IoUrlTypeRegy implements GfoInvkAble {
public String[] FetchAryOr(String key, String... or) {
IoUrlTypeGrp itm = (IoUrlTypeGrp)hash.Get_by(key);
return itm == null ? or : itm.AsAry();
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_Get)) {
String key = m.ReadStr(k);
if (ctx.Deny()) return this;
IoUrlTypeGrp itm = (IoUrlTypeGrp)hash.Get_by(key);
if (itm == null) {
itm = new IoUrlTypeGrp(key);
hash.Add(key, itm);
}
return itm;
}
else return GfoInvkAble_.Rv_unhandled;
// return this;
} public static final String Invk_Get = "Get";
Ordered_hash hash = Ordered_hash_.New();
public static final IoUrlTypeRegy Instance = new IoUrlTypeRegy(); IoUrlTypeRegy() {}
}
class IoUrlTypeGrp implements GfoInvkAble {
public String[] AsAry() {
String[] rv = new String[list.Count()];
for (int i = 0; i < list.Count(); i++)
rv[i] = (String)list.Get_at(i);
return rv;
}
Ordered_hash list = Ordered_hash_.New();
public IoUrlTypeGrp(String key) {this.key = key;} private String key;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_AddMany)) {
if (ctx.Deny()) return this;
for (int i = 0; i < m.Args_count(); i++) {
String s = m.ReadStr("v");
if (list.Has(s)) {
ctx.Write_warn(UsrMsg.new_("itm already has filter").Add("key", key).Add("filter", s).To_str());
list.Del(s);
}
list.Add(s, s);
}
}
else if (ctx.Match(k, Invk_Print)) {
if (ctx.Deny()) return this;
String_bldr sb = String_bldr_.new_();
sb.Add(key).Add("{");
for (int i = 0; i < list.Count(); i++)
sb.Add_spr_unless_first((String)list.Get_at(i), " ", i);
sb.Add("}");
return sb.To_str();
}
else if (ctx.Match(k, Invk_Clear)) {if (ctx.Deny()) return this; list.Clear();}
else return GfoInvkAble_.Rv_unhandled;
return this;
} public static final String Invk_AddMany = "Add_many", Invk_Clear = "Clear", Invk_Print = "Print";
}

View 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.ios; import gplx.*; import gplx.core.*;
import gplx.stores.*; /*GfoNdeRdr_*/
public class IoZipWkr {
public Io_url ExeUrl() {return (Io_url)GfoRegy.Instance.FetchValOrFail(Regy_ExeUrl);}
public String ExeArgFmt() {return (String)GfoRegy.Instance.FetchValOrFail(Regy_ExeArgFmt);}
public void Expand(Io_url srcUrl, Io_url trgUrl) {
String exeArgs = Expand_genCmdString(srcUrl, trgUrl);
process.Exe_url_(this.ExeUrl()).Args_str_(exeArgs);
process.Run_wait();
}
@gplx.Internal protected String Expand_genCmdString(Io_url srcUrl, Io_url trgUrl) {
return String_.Format(this.ExeArgFmt(), srcUrl.Xto_api(), trgUrl.Xto_api());
}
ProcessAdp process = new ProcessAdp();
public static IoZipWkr regy_() {return new IoZipWkr();}
static final String Regy_ExeUrl = "gplx.core.ios.IoZipWkr.ExeUrl", Regy_ExeArgFmt = "gplx.core.ios.IoZipWkr.ExeArgFmt";
public static IoZipWkr new_(Io_url exeUrl, String expandArgs) {
GfoRegy.Instance.RegObj(Regy_ExeUrl, exeUrl);
GfoRegy.Instance.RegObj(Regy_ExeArgFmt, expandArgs);
IoZipWkr rv = new IoZipWkr();
return rv;
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
import org.junit.*;
public class IoZipWkr_tst {
@Test public void Basic() {
wkr = IoZipWkr.new_(Io_url_.Empty, "e \"{0}\" -o\"{1}\" -y");
tst_Expand_genCmdString(Io_url_.wnt_fil_("C:\\fil1.zip"), Io_url_.wnt_dir_("D:\\out\\"), "e \"C:\\fil1.zip\" -o\"D:\\out\" -y"); // NOTE: not "D:\out\" because .Xto_api
} IoZipWkr wkr;
void tst_Expand_genCmdString(Io_url srcUrl, Io_url trgUrl, String expd) {
Tfds.Eq(expd, wkr.Expand_genCmdString(srcUrl, trgUrl));
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
import gplx.brys.*;
public class Io_download_fmt {
private final Io_size_fmtr_arg size_fmtr_arg = new Io_size_fmtr_arg(), rate_fmtr_arg = new Io_size_fmtr_arg().Suffix_(Bry_.new_a7("ps"));
private final Bry_fmtr_arg_time prog_left_fmtr_arg = new Bry_fmtr_arg_time(); private final Bry_fmtr_arg_decimal_int prog_pct_fmtr_arg = new Bry_fmtr_arg_decimal_int().Places_(2);
private long time_checkpoint_interval = 250;
private long time_checkpoint = 0;
private long time_prv = 0;
public Io_download_fmt() {
this.src_name = prog_msg_hdr = ""; // NOTE: set to "" else prog_mgr will fail with null ref
}
private final Bry_bfr prog_bfr = Bry_bfr.new_(); Bry_fmtr prog_fmtr = Bry_fmtr.new_().Fail_when_invalid_escapes_(false); // NOTE: prog_fmtr can be passed file_names with ~ which are not easy to escape; DATE:2013-02-19
public long Time_bgn() {return time_bgn;} private long time_bgn;
public long Time_now() {return time_now;} private long time_now;
public long Time_dif() {return time_dif;} private long time_dif;
public long Time_end() {return time_end;} private long time_end;
public String Src_url() {return src_url;} private String src_url;
public String Src_name() {return src_name;} private String src_name;
public long Src_len() {return src_len;} private long src_len;
public long Prog_done() {return prog_done;} private long prog_done;
public long Prog_rate() {return prog_rate;} private long prog_rate;
public long Prog_left() {return prog_left;} private long prog_left;
public long Prog_pct() {return prog_pct;} private long prog_pct;
public String Prog_msg_hdr() {return prog_msg_hdr;} private String prog_msg_hdr;
public int Prog_num_units() {return prog_num_units;} private int prog_num_units = Io_mgr.Len_kb;
public String Prog_num_fmt() {return prog_num_fmt;} private String prog_num_fmt = "#,##0";
public String Prog_msg() {return prog_msg;} private String prog_msg;
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} private Gfo_usr_dlg usr_dlg;
public void Ctor(Gfo_usr_dlg usr_dlg) {
this.usr_dlg = usr_dlg;
}
public void Download_init(String src_url, String prog_msg_hdr) {
this.src_url = src_url;
this.src_name = String_.Extract_after_bwd(src_url, "/");
this.prog_msg_hdr = prog_msg_hdr;
}
public void Bgn(long src_len) {
this.src_len = src_len;
prog_fmtr.Fmt_(prog_msg_hdr).Keys_("src_name", "src_len").Bld_bfr_many_and_set_fmt(src_name, size_fmtr_arg.Val_(src_len));
prog_fmtr.Keys_("prog_done", "prog_pct", "prog_rate", "prog_left");
prog_done = 0;
prog_pct = 0;
prog_rate = 0;
prog_left = 0;
time_bgn = time_prv = Env_.TickCount();
time_checkpoint = 0;
}
public void Prog(int prog_read) {
time_now = Env_.TickCount();
time_dif = time_now - time_bgn; if (time_dif == 0) time_dif = 1; // avoid div by zero error below
prog_done += prog_read;
time_checkpoint += time_now - time_prv;
time_prv = time_now;
if ((time_checkpoint < time_checkpoint_interval)) return; // NOTE: using time_checkpoint instead of size_checkpoint b/c WMF dump servers transfer in spurts (sends 5 packets, and then waits);
time_checkpoint = 0;
prog_rate = (prog_done * 1000) / (time_dif);
prog_pct = (prog_done * 10000) / src_len; // 100 00 to get 2 decimal places; EX: .1234 -> 1234 -> 12.34%
prog_left = (1000 * (src_len - prog_done)) / prog_rate;
prog_fmtr.Bld_bfr_many(prog_bfr
, size_fmtr_arg.Val_(prog_done)
, prog_pct_fmtr_arg.Val_((int)prog_pct)
, rate_fmtr_arg.Val_(prog_rate)
, prog_left_fmtr_arg.Seconds_(prog_left / 1000)
);
prog_msg = prog_bfr.To_str_and_clear();
if (usr_dlg != null)
usr_dlg.Prog_none("", "prog", prog_msg);
}
public void Term() {
time_end = Env_.TickCount();
// prog_rate = (prog_done * 1000) / (time_dif);
// prog_pct = (prog_done * 10000) / src_len; // 100 00 to get 2 decimal places; EX: .1234 -> 1234 -> 12.34%
// prog_left = (1000 * (src_len - prog_done)) / prog_rate;
// if (usr_dlg != null) usr_dlg.Prog_none(GRP_KEY, "clear", "");
}
public static final Io_download_fmt Null = null;
}

View File

@@ -0,0 +1,73 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Io_download_fmt_tst {
Io_download_fmt_fxt fxt = new Io_download_fmt_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Fmt() {
fxt.Clear().Ini("downloading ~{src_name}: ~{prog_left} left (@ ~{prog_rate}); ~{prog_done} of ~{src_len} (~{prog_pct}%)", "http://a.org/b.png", Io_mgr.Len_kb * 10);
fxt.Now_add_f(1000).Prog_done_(1 * Io_mgr.Len_kb).Prog_pct_(1 * 1000).Prog_rate_(Io_mgr.Len_kb).Prog_left_(9 * 1000)
.Prog_msg_("downloading b.png: 09s left (@ 1.000 KBps); 1.000 KB of 10.000 KB (10.00%)")
.Download_(Io_mgr.Len_kb);
fxt.Now_add_f(1000).Prog_done_(2 * Io_mgr.Len_kb).Prog_pct_(2 * 1000).Prog_rate_(Io_mgr.Len_kb).Prog_left_(8 * 1000)
.Prog_msg_("downloading b.png: 08s left (@ 1.000 KBps); 2.000 KB of 10.000 KB (20.00%)")
.Download_(Io_mgr.Len_kb)
;
fxt.Now_add_f(2000).Prog_done_(3 * Io_mgr.Len_kb).Prog_pct_(3 * 1000).Prog_rate_(768).Prog_left_(9333)
.Prog_msg_("downloading b.png: 09s left (@ 768.000 Bps); 3.000 KB of 10.000 KB (30.00%)")
.Download_(Io_mgr.Len_kb)
;
}
@Test public void Tilde() {
fxt.Clear().Ini("a~b", "http://a.org/b.png", Io_mgr.Len_kb * 10);
}
}
class Io_download_fmt_fxt {
public Io_download_fmt_fxt Clear() {
if (fmt == null) {
fmt = new Io_download_fmt();
}
Env_.TickCount_Test = 0;
prog_done = prog_rate = prog_pct = prog_left = -1;
prog_msg = null;
return this;
} Io_download_fmt fmt;
public Io_download_fmt_fxt Now_add_f(int v) {Env_.TickCount_Test += v; return this;}
public Io_download_fmt_fxt Prog_done_(int v) {prog_done = v; return this;} long prog_done = -1;
public Io_download_fmt_fxt Prog_pct_ (int v) {prog_pct = v; return this;} long prog_pct = -1;
public Io_download_fmt_fxt Prog_rate_(int v) {prog_rate = v; return this;} long prog_rate = -1;
public Io_download_fmt_fxt Prog_left_(int v) {prog_left = v; return this;} long prog_left = -1;
public Io_download_fmt_fxt Prog_msg_(String v) {
prog_msg = v; return this;
} String prog_msg;
public Io_download_fmt_fxt Download_(int v) {
fmt.Prog(v);
if (prog_done != -1) Tfds.Eq(prog_done, fmt.Prog_done(), "prog_done");
if (prog_pct != -1) Tfds.Eq(prog_pct , fmt.Prog_pct(), "prog_pct");
if (prog_rate != -1) Tfds.Eq(prog_rate, fmt.Prog_rate(), "prog_rate");
if (prog_left != -1) Tfds.Eq(prog_left, fmt.Prog_left(), "prog_left");
if (prog_msg != null) Tfds.Eq(prog_msg, fmt.Prog_msg(), "prog_msg");
return this;
}
public Io_download_fmt_fxt Ini(String prog_msg_hdr, String src_url, int src_len) {
fmt.Download_init(src_url, prog_msg_hdr);
fmt.Bgn(src_len);
return this;
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public class Io_fil implements gplx.CompareAble {
public Io_fil(Io_url url, String data) {this.url = url; this.data = data;}
public Io_url Url() {return url;} public Io_fil Url_(Io_url v) {url = v; return this;} Io_url url;
public String Data() {return data;} public Io_fil Data_(String v) {data = v; return this;} private String data;
public int compareTo(Object obj) {
return gplx.CompareAble_.Compare(url.Raw(), ((Io_fil)obj).Url().Raw());
}
public static Io_fil[] new_ary_(Io_url[] url_ary) {
int url_ary_len = url_ary.length;
Io_fil[] rv = new Io_fil[url_ary_len];
for (int i = 0; i < url_ary_len; i++) {
Io_url url = url_ary[i];
String data = Io_mgr.Instance.LoadFilStr(url);
Io_fil fil = new Io_fil(url, data);
rv[i] = fil;
}
return rv;
}
public static final Io_fil[] Ary_empty = new Io_fil[0];
}

View File

@@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class Io_fil_mkr {
private final List_adp list = List_adp_.new_();
public Io_fil_mkr Add(String url, String data) {return Add(Io_url_.mem_fil_(url), data);}
public Io_fil_mkr Add(Io_url url, String data) {list.Add(new Io_fil(url, data)); return this;}
public Io_fil[] To_ary() {return (Io_fil[])list.To_ary(Io_fil.class);}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public class Io_size_ {
public static String To_str(long val) {
long cur = val; int pow = 0;
while (cur >= 1024) {
cur /= 1024;
pow++;
}
long div = (long)Math_.Pow((long)1024, (long)pow);
Decimal_adp valDecimal = Decimal_adp_.divide_(val, div);
String[] unit = Io_size_.Units[pow];
return valDecimal.To_str("#,##0.000") + " " + String_.PadBgn(unit[0], 2, " ");
}
public static String To_str(long val, int exp_1024, String val_fmt, String unit_pad, boolean round_0_to_1) {
long exp_val = (long)Math_.Pow(1024, exp_1024);
Decimal_adp val_as_decimal = Decimal_adp_.divide_(val, exp_val);
if (round_0_to_1 && val_as_decimal.Comp_lt(1)) val_as_decimal = Decimal_adp_.One;
String[] unit = Io_size_.Units[exp_1024];
return val_as_decimal.To_str(val_fmt) + " " + String_.PadBgn(unit[0], 2, unit_pad);
}
public static long parse_or(String raw, long or) {
if (raw == null || raw == String_.Empty) return or;
String[] terms = String_.Split(raw, " ");
int termsLen = Array_.Len(terms); if (termsLen > 2) return or;
Decimal_adp val = null;
try {val = Decimal_adp_.parse(terms[0]);} catch (Exception exc) {Err_.Noop(exc); return or;}
int unitPow = 0;
if (termsLen > 1) {
String unitStr = String_.Upper(terms[1]);
unitPow = parse_unitPow_(unitStr); if (unitPow == -1) return or;
}
int curPow = unitPow;
while (curPow > 0) {
val = val.Multiply(1024);
curPow--;
}
// DELETED:do not check for fractional bytes; EX: 10.7 GB DATE:2015-01-06
// Decimal_adp comp = val.Op_truncate_decimal();
// if (!val.Eq(comp)) return or;
return val.To_long();
}
private static int parse_unitPow_(String unitStr) {
int unitLen = Array_.Len(Units);
int unitPow = -1;
for (int i = 0; i < unitLen; i++) {
if (String_.Eq(unitStr, String_.Upper(Units[i][0]))) return i;
if (String_.Eq(unitStr, String_.Upper(Units[i][1]))) return i;
}
return unitPow;
}
private static final String[][] Units = new String[][]
{ String_.Ary("B", "BYTE")
, String_.Ary("KB", "KILOBYTE")
, String_.Ary("MB", "MEGABYTE")
, String_.Ary("GB", "GIGABYTE")
, String_.Ary("TB", "TERABYTE")
, String_.Ary("PB", "PETABYTE")
, String_.Ary("EB", "EXABYTE")
};
public static final byte[][] Units_bry = new byte[][]
{ Bry_.new_a7("B")
, Bry_.new_a7("KB")
, Bry_.new_a7("MB")
, Bry_.new_a7("GB")
, Bry_.new_a7("TB")
, Bry_.new_a7("PB")
, Bry_.new_a7("EB")
};
public static int Load_int_(GfoMsg m) {return (int)Load_long_(m);}
public static long Load_long_(GfoMsg m) {
String v = m.ReadStr("v");
long rv = parse_or(v, Long_.Min_value); if (rv == Long_.Min_value) throw Err_.new_wo_type("invalid val", "val", v);
return rv;
}
public static String To_str_mb(long v) {return Long_.To_str(v / Io_mgr.Len_mb_long);}
public static long To_long_by_int_mb(int v) {return (long)v * Io_mgr.Len_mb_long;}
public static long To_long_by_msg_mb(GfoMsg m, long cur) {
long val = m.ReadLongOr("v", Int_.Min_value);
return val == Int_.Min_value ? cur : (val * Io_mgr.Len_mb_long);
}
}
class Io_size_fmtr_arg implements Bry_fmtr_arg {
public long Val() {return val;} public Io_size_fmtr_arg Val_(long v) {val = v; return this;} long val;
public byte[] Suffix() {return suffix;} public Io_size_fmtr_arg Suffix_(byte[] v) {suffix = v; return this;} private byte[] suffix;
public void Fmt__do(Bry_bfr bfr) {
long cur = val; int pow = 0;
while (cur >= 1024) {
cur /= 1024;
pow++;
}
long div = (long)Math_.Pow((long)1024, (long)pow);
Decimal_adp val_decimal = Decimal_adp_.divide_(val, div);
bfr.Add_str_a7(val_decimal.To_str("#,###.000")).Add_byte(Byte_ascii.Space).Add(gplx.core.ios.Io_size_.Units_bry[pow]);
if (suffix != null)
bfr.Add(suffix);
}
}

View File

@@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Io_size__tst {
private Io_size__fxt fxt = new Io_size__fxt();
@Test public void XtoLong() {
fxt.Test_XtoLong("1", 1);
fxt.Test_XtoLong("1 KB", 1024);
fxt.Test_XtoLong("1 MB", 1024 * 1024);
fxt.Test_XtoLong("1 GB", 1024 * 1024 * 1024);
fxt.Test_XtoLong("12 kb", 12 * 1024);
fxt.Test_XtoLong("1.5 kb", 1024 + 512); // 1536
fxt.Test_XtoLong("1.5 mb", (long)(1024 * 1024 * 1.5));
fxt.Test_XtoLong("-1", -1); // NOTE: negative bytes allowed
fxt.Test_XtoLongFail("1 kilobite");
fxt.Test_XtoLongFail("1 BB");
// fxt.Test_XtoLongFail("1.1"); // DELETED:do not check for fractional bytes; EX: 10.7 GB DATE:2015-01-06
// fxt.Test_XtoLongFail("1.51 kb");
}
@Test public void To_str() {
fxt.Test_XtoStr(1, "1.000 B");
fxt.Test_XtoStr(1024, "1.000 KB");
fxt.Test_XtoStr(1536, "1.500 KB");
fxt.Test_XtoStr(1024 * 1024, "1.000 MB");
fxt.Test_XtoStr(1016, "1,016.000 B"); // NOTE: 1016 is not 1.016 KB
}
@Test public void Xto_str_full() {
fxt.Test_Xto_str( 500, 1, "#,###", " ", Bool_.Y, "1 KB");
fxt.Test_Xto_str( 1000, 1, "#,###", " ", Bool_.Y, "1 KB");
fxt.Test_Xto_str( 2000, 1, "#,###", " ", Bool_.Y, "2 KB");
fxt.Test_Xto_str( 1234567, 1, "#,###", " ", Bool_.Y, "1,206 KB");
fxt.Test_Xto_str(1234567890, 1, "#,###", " ", Bool_.Y, "1,205,633 KB");
}
@Test public void EqualsTest() {
fxt.Test_Equals("1", "1");
fxt.Test_Equals("1 kb", "1 kb");
fxt.Test_Equals("1024", "1 kb");
fxt.Test_Equals("1048576", "1 mb");
fxt.Test_Equals("1024 kb", "1 mb");
fxt.Test_Equals("1.5 kb", "1536 b");
}
}
class Io_size__fxt {
public void Test_XtoLong(String raw, long expd) {Tfds.Eq(expd, Io_size_.parse_or(raw, Long_.Min_value));}
public void Test_XtoLongFail(String raw) {
long val = Io_size_.parse_or(raw, Long_.Min_value);
if (val != Long_.Min_value) Tfds.Fail("expd parse failure; raw=" + raw);
}
public void Test_Equals(String lhs, String rhs) {Tfds.Eq(Io_size_.parse_or(lhs, Long_.Min_value), Io_size_.parse_or(rhs, Long_.Min_value));}
public void Test_XtoStr(long val, String expd) {Tfds.Eq(expd, Io_size_.To_str(val));}
public void Test_Xto_str(long val, int exp_1024, String val_fmt, String unit_pad, boolean round_0_to_1, String expd) {Tfds.Eq(expd, Io_size_.To_str(val, exp_1024, val_fmt, unit_pad, round_0_to_1));}
}

View 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.ios; import gplx.*; import gplx.core.*;
public class Io_stream_ { // SERIALIZED
public static final byte Tid_null = 0, Tid_raw = 1, Tid_zip = 2, Tid_gzip = 3, Tid_bzip2 = 4;
public static final String Ext_zip = ".zip", Ext_gz = ".gz", Ext_bz2 = ".bz2";
public static String Obsolete_to_str(byte v) {
switch (v) {
case Io_stream_.Tid_raw : return ".xdat";
case Io_stream_.Tid_zip : return ".zip";
case Io_stream_.Tid_gzip : return ".gz";
case Io_stream_.Tid_bzip2 : return ".bz2";
default : throw Err_.new_unhandled(v);
}
}
public static byte Obsolete_to_tid(String v) {
if (String_.Eq(v, ".xdat")) return Io_stream_.Tid_raw;
else if (String_.Eq(v, ".zip")) return Io_stream_.Tid_zip;
else if (String_.Eq(v, ".gz")) return Io_stream_.Tid_gzip;
else if (String_.Eq(v, ".bz2")) return Io_stream_.Tid_bzip2;
else throw Err_.new_unhandled(v);
}
public static String To_str(byte v) {
switch (v) {
case Io_stream_.Tid_raw : return "raw";
case Io_stream_.Tid_zip : return "zip";
case Io_stream_.Tid_gzip : return "gzip";
case Io_stream_.Tid_bzip2 : return "bzip2";
default : throw Err_.new_unhandled(v);
}
}
public static byte To_tid(String v) {
if (String_.Eq(v, "raw")) return Io_stream_.Tid_raw;
else if (String_.Eq(v, "zip")) return Io_stream_.Tid_zip;
else if (String_.Eq(v, "gzip")) return Io_stream_.Tid_gzip;
else if (String_.Eq(v, "bzip2")) return Io_stream_.Tid_bzip2;
else throw Err_.new_unhandled(v);
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public interface Io_stream_rdr extends RlsAble {
byte Tid();
boolean Exists();
Io_url Url(); Io_stream_rdr Url_(Io_url v);
long Len(); Io_stream_rdr Len_(long v);
Io_stream_rdr Open();
void Open_mem(byte[] v);
Object Under();
int Read(byte[] bry, int bgn, int len);
long Skip(long len);
}

View File

@@ -0,0 +1,266 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class Io_stream_rdr_ {
public static Io_stream_rdr file_(Io_url url) {return new Io_stream_rdr_file().Url_(url);}
public static Io_stream_rdr file_(java.io.InputStream strm) {return new Io_stream_rdr_file().Under_(strm);}
public static Io_stream_rdr zip_(Io_url url) {return new Io_stream_rdr_zip().Url_(url);}
public static Io_stream_rdr gzip_(Io_url url) {return new Io_stream_rdr_gzip().Url_(url);}
public static Io_stream_rdr bzip2_(Io_url url) {return new Io_stream_rdr_bzip2().Url_(url);}
public static Io_stream_rdr new_by_url_(Io_url url) {
String ext = url.Ext();
if (String_.Eq(ext, Io_stream_.Ext_zip)) return gplx.core.ios.Io_stream_rdr_.zip_(url);
else if (String_.Eq(ext, Io_stream_.Ext_gz)) return gplx.core.ios.Io_stream_rdr_.gzip_(url);
else if (String_.Eq(ext, Io_stream_.Ext_bz2)) return gplx.core.ios.Io_stream_rdr_.bzip2_(url);
else return gplx.core.ios.Io_stream_rdr_.file_(url);
}
public static Io_stream_rdr new_by_tid_(byte tid) {
switch (tid) {
case Io_stream_.Tid_raw: return new Io_stream_rdr_file();
case Io_stream_.Tid_zip: return new Io_stream_rdr_zip();
case Io_stream_.Tid_gzip: return new Io_stream_rdr_gzip();
case Io_stream_.Tid_bzip2: return new Io_stream_rdr_bzip2();
default: throw Err_.new_unhandled(tid);
}
}
public static byte[] Load_all(Io_url url) {
Io_stream_rdr rdr = new_by_url_(url);
Bry_bfr rv = Bry_bfr.new_();
try {
rdr.Open();
return Load_all_as_bry(rv, rdr);
}
finally {rdr.Rls();}
}
public static String Load_all_as_str(Io_stream_rdr rdr) {return String_.new_u8(Load_all_as_bry(rdr));}
public static byte[] Load_all_as_bry(Io_stream_rdr rdr) {return Load_all_as_bry(Bry_bfr.new_(), rdr);}
public static byte[] Load_all_as_bry(Bry_bfr rv, Io_stream_rdr rdr) {
Load_all_to_bfr(rv, rdr);
return rv.To_bry_and_clear();
}
public static void Load_all_to_bfr(Bry_bfr rv, Io_stream_rdr rdr) {
try {
byte[] bry = new byte[4096];
while (true) {
int read = rdr.Read(bry, 0, 4096);
if (read < gplx.core.ios.Io_stream_rdr_.Read_done_compare) break;
rv.Add_mid(bry, 0, read);
}
} finally {rdr.Rls();}
}
public static final Io_stream_rdr Noop = new Io_stream_rdr_noop();
public static Io_stream_rdr mem_(String v) {return mem_(Bry_.new_u8(v));}
public static Io_stream_rdr mem_(byte[] v) {
Io_stream_rdr rv = new Io_stream_rdr_adp(Stream_new_mem(v));
rv.Len_(v.length);
return rv;
}
public static java.io.InputStream Stream_new_mem(byte[] v) {
return new java.io.ByteArrayInputStream(v);
}
public static boolean Stream_close(java.io.InputStream stream) {
try {
if (stream != null)
stream.close();
return true;
} catch (Exception e) {Err_.Noop(e); return false;}
}
public static int Stream_read_by_parts(java.io.InputStream stream, int part_len, byte[] bry, int bgn, int len) {
/*
NOTE: BZip2CompressorInputStream will fail if large len is used
Instead, make smaller requests and fill bry
*/
try {
int rv = 0;
int end = bgn + len;
int cur = bgn;
while (true) {
int bry_len = part_len; // read in increments of part_len
if (cur + bry_len > end) // if cur + 8 kb > bry_len, trim to end; EX: 9 kb bry passed; 1st pass is 8kb, 2nd pass should be 1kb, not 8 kb;
bry_len = end - cur;
if (cur == end) break; // no more bytes needed; break; EX: 8 kb bry passed; 1st pass is 8kb; 2nd pass is 0 and cur == end
int read = stream.read(bry, cur, bry_len);
if (read == gplx.core.ios.Io_stream_rdr_.Read_done) // read done; end
break;
rv += read;
cur += read;
}
return rv;
}
catch (Exception exc) {
throw Err_.new_exc(exc, "io", "read failed", "bgn", bgn, "len", len);
}
}
public static final int Read_done = -1;
public static final int Read_done_compare = 1;
}
class Io_stream_rdr_noop implements Io_stream_rdr {
public Object Under() {return null;}
public byte Tid() {return Io_stream_.Tid_null;}
public boolean Exists() {return false;}
public Io_url Url() {return Io_url_.Empty;} public Io_stream_rdr Url_(Io_url v) {return this;}
public long Len() {return Io_mgr.Len_null;} public Io_stream_rdr Len_(long v) {return this;}
public void Open_mem(byte[] v) {}
public Io_stream_rdr Open() {return this;}
public int Read(byte[] bry, int bgn, int len) {return Io_stream_rdr_.Read_done;}
public long Skip(long len) {return Io_stream_rdr_.Read_done;}
public void Rls() {}
}
class Io_stream_rdr_adp implements Io_stream_rdr {
private java.io.InputStream strm;
public Io_stream_rdr_adp(java.io.InputStream strm) {this.strm = strm;}
public Object Under() {return strm;}
public byte Tid() {return Io_stream_.Tid_raw;}
public boolean Exists() {return len > 0;}
public Io_url Url() {return url;} public Io_stream_rdr Url_(Io_url v) {this.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 = Io_mgr.Len_null;
public void Open_mem(byte[] v) {}
public Io_stream_rdr Open() {return this;}
public int Read(byte[] bry, int bgn, int len) {
try {return strm.read(bry, bgn, len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "read failed", "bgn", bgn, "len", len);}
}
public long Skip(long len) {
try {return strm.skip(len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "skip failed", "len", len);}
}
public void Rls() {
try {strm.close();}
catch (Exception e) {throw Err_.new_exc(e, "io", "close failed", "url", url.Xto_api());}
}
}
abstract class Io_stream_rdr_base implements Io_stream_rdr {
public abstract byte Tid();
public boolean Exists() {return this.Len() > 0;}
public Object Under() {return stream;} public Io_stream_rdr Under_(java.io.InputStream v) {this.stream = v; return this;} protected java.io.InputStream stream;
public Io_url Url() {return url;} public Io_stream_rdr Url_(Io_url v) {this.url = v; return this;} protected Io_url url;
public long Len() {return len;} public Io_stream_rdr Len_(long v) {len = v; return this;} private long len = Io_mgr.Len_null;
public void Open_mem(byte[] v) {
stream = Wrap_stream(new java.io.ByteArrayInputStream(v));
}
public Io_stream_rdr Open() {
try {stream = Wrap_stream(new java.io.FileInputStream(url.Xto_api()));}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Xto_api());}
return this;
}
public int Read(byte[] bry, int bgn, int len) {
try {return stream.read(bry, bgn, len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "read failed", "bgn", bgn, "len", len);}
}
public long Skip(long len) {
try {return stream.skip(len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "skip failed", "len", len);}
}
public void Rls() {
try {stream.close();}
catch (Exception e) {throw Err_.new_exc(e, "io", "close failed", "url", url.Xto_api());}
}
public abstract java.io.InputStream Wrap_stream(java.io.InputStream stream);
}
class Io_stream_rdr_file extends Io_stream_rdr_base {
@Override public byte Tid() {return Io_stream_.Tid_raw;}
public Io_stream_rdr Open() {
try {
if (!Io_mgr.Instance.Exists(url))
stream = Wrap_stream(new java.io.ByteArrayInputStream(Bry_.Empty));
else {
if (url.Info().EngineKey() == IoEngine_.MemKey)
stream = Wrap_stream(new java.io.ByteArrayInputStream(Io_mgr.Instance.LoadFilBry(url.Xto_api())));
else
stream = Wrap_stream(new java.io.FileInputStream(url.Xto_api()));
}
}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Xto_api());}
return this;
}
@Override public java.io.InputStream Wrap_stream(java.io.InputStream stream) {return stream;}
}
class Io_stream_rdr_zip implements Io_stream_rdr {
@Override public byte Tid() {return Io_stream_.Tid_zip;}
public boolean Exists() {return this.Len() > 0;}
public Io_url Url() {return url;} public Io_stream_rdr Url_(Io_url v) {this.url = v; return this;} Io_url url;
public long Len() {return len;} public Io_stream_rdr Len_(long v) {len = v; return this;} private long len = Io_mgr.Len_null;
public Object Under() {return zip_stream;} private java.util.zip.ZipInputStream zip_stream;
public void Src_bfr_(Bry_bfr v) {this.src_bfr = v;} Bry_bfr src_bfr;
public void Open_mem(byte[] v) {
Wrap_stream(new java.io.ByteArrayInputStream(v));
}
public Io_stream_rdr Open() {
try {Wrap_stream(new java.io.FileInputStream(url.Xto_api()));}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Xto_api());}
return this;
}
void Wrap_stream(java.io.InputStream input_stream) {zip_stream = new java.util.zip.ZipInputStream(input_stream);}
public int Read(byte[] bry, int bgn, int len) {
try {
while (true){
int read = zip_stream.read(bry, bgn, len);
if (read == Io_stream_rdr_.Read_done) {
if (zip_stream.getNextEntry() == null)
return Io_stream_rdr_.Read_done;
}
else
return read;
}
}
catch (Exception e) {throw Err_.new_exc(e, "io", "read failed", "bgn", bgn, "len", len);}
}
public long Skip(long len) {
try {return zip_stream.skip(len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "skip failed", "len", len);}
}
public void Rls() {
try {zip_stream.close();}
catch (Exception e) {throw Err_.new_exc(e, "io", "close failed", "url", url.Xto_api());}
}
}
class Io_stream_rdr_gzip extends Io_stream_rdr_base {
@Override public byte Tid() {return Io_stream_.Tid_gzip;}
@Override public int Read(byte[] bry, int bgn, int len) {
try {
int total_read = 0;
while (true) { // NOTE: the gz stream reads partially; (request 100; only get back 10); keep reading until entire bfr is full or -1
int read = stream.read(bry, bgn, len);
if (read == Io_stream_rdr_.Read_done) break;
total_read += read;
if (total_read >= len) break; // entire bfr full; stop
bgn += read; // increase bgn by amount read
len -= read; // decrease len by amount read
}
return total_read == 0 ? Io_stream_rdr_.Read_done : total_read; // gzip seems to allow 0 bytes read (bz2 and zip return -1 instead); normalize return to -1;
}
catch (Exception e) {
throw Err_.new_exc(e, "io", "read failed", "bgn", bgn, "len", len);
}
}
@Override public java.io.InputStream Wrap_stream(java.io.InputStream stream) {
try {return new java.util.zip.GZIPInputStream(stream);}
catch (Exception exc) {throw Err_.new_wo_type("failed to open gz stream");}
}
}
class Io_stream_rdr_bzip2 extends Io_stream_rdr_base {
@Override public byte Tid() {return Io_stream_.Tid_bzip2;}
@Override public java.io.InputStream Wrap_stream(java.io.InputStream stream) {
try {return new org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream(stream, true);}
catch (Exception exc) {throw Err_.new_wo_type("failed to open bzip2 stream");}
}
@Override public int Read(byte[] bry, int bgn, int len) {
return Io_stream_rdr_.Stream_read_by_parts(stream, Read_len, bry, bgn, len);
}
private static final int Read_len = Io_mgr.Len_mb * 128;
}

View File

@@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Io_stream_rdr_tst {
@Before public void init() {fxt.Clear();} private Io_stream_rdr_fxt fxt = new Io_stream_rdr_fxt();
@After public void term() {fxt.Rls();}
@Test public void Bz2_read() {
fxt .Init_stream("abcd") // read everything at once
.Expd_bytes_read(4).Test_read(0, 4, "abcd");
fxt .Init_stream("abcd") // read in steps
.Expd_bytes_read(1).Test_read(0, 1, "a")
.Expd_bytes_read(2).Test_read(1, 2, "bc")
.Expd_bytes_read(1).Test_read(3, 1, "d")
;
}
}
class Io_stream_rdr_fxt {
private java.io.InputStream stream;
private int stream_bry_len;
public void Clear() {
expd_bytes_read = Int_.Min_value;
}
public Io_stream_rdr_fxt Expd_bytes_read(int v) {expd_bytes_read = v; return this;} private int expd_bytes_read = Int_.Min_value;
public Io_stream_rdr_fxt Init_stream(String v) {
byte[] stream_bry = Bry_.new_a7(v);
stream_bry_len = stream_bry.length;
stream = Io_stream_rdr_.Stream_new_mem(stream_bry);
return this;
}
public Io_stream_rdr_fxt Test_read(int bgn, int len, String expd_str) {
byte[] bfr = new byte[stream_bry_len]; // allocate whole stream; may not use it all
int actl_bytes_read = Io_stream_rdr_.Stream_read_by_parts(stream, 8, bfr, bgn, len);
Tfds.Eq(expd_bytes_read, actl_bytes_read, "bytes_read");
Tfds.Eq(expd_str, String_.new_u8(bfr, bgn, bgn + actl_bytes_read), "str");
return this;
}
public void Rls() {
Io_stream_rdr_.Stream_close(stream);
}
}

View 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.core.ios; import gplx.*; import gplx.core.*;
public interface Io_stream_wtr extends RlsAble {
byte Tid();
Io_url Url(); Io_stream_wtr Url_(Io_url v);
void Trg_bfr_(Bry_bfr v);
Io_stream_wtr Open();
byte[] To_ary_and_clear();
void Write(byte[] bry, int bgn, int len);
void Flush();
}

View File

@@ -0,0 +1,213 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class Io_stream_wtr_ {
public static Io_stream_wtr bzip2_(Io_url url) {return new Io_stream_wtr_bzip2().Url_(url);}
public static Io_stream_wtr gzip_(Io_url url) {return new Io_stream_wtr_gzip().Url_(url);}
public static Io_stream_wtr zip_(Io_url url) {return new Io_stream_wtr_zip().Url_(url);}
public static Io_stream_wtr file_(Io_url url) {return new Io_stream_wtr_file().Url_(url);}
public static Io_stream_wtr new_by_url_(Io_url url) {
String ext = url.Ext();
if (String_.Eq(ext, Io_stream_.Ext_zip)) return gplx.core.ios.Io_stream_wtr_.zip_(url);
else if (String_.Eq(ext, Io_stream_.Ext_gz)) return gplx.core.ios.Io_stream_wtr_.gzip_(url);
else if (String_.Eq(ext, Io_stream_.Ext_bz2)) return gplx.core.ios.Io_stream_wtr_.bzip2_(url);
else return gplx.core.ios.Io_stream_wtr_.file_(url);
}
public static Io_stream_wtr new_by_mem(Bry_bfr bfr, byte tid) {
Io_stream_wtr wtr = new_by_tid_(tid).Url_(Io_url_.Empty);
wtr.Trg_bfr_(bfr);
return wtr;
}
public static Io_stream_wtr new_by_tid_(byte v) {
switch (v) {
case gplx.core.ios.Io_stream_.Tid_raw : return new Io_stream_wtr_file();
case gplx.core.ios.Io_stream_.Tid_zip : return new Io_stream_wtr_zip();
case gplx.core.ios.Io_stream_.Tid_gzip : return new Io_stream_wtr_gzip();
case gplx.core.ios.Io_stream_.Tid_bzip2 : return new Io_stream_wtr_bzip2();
default : throw Err_.new_unhandled(v);
}
}
public static void Save_all(Io_url url, byte[] bry, int bgn, int end) {
Io_stream_wtr wtr = new_by_url_(url);
try {
wtr.Open();
wtr.Write(bry, bgn, end);
wtr.Flush();
}
finally {wtr.Rls();}
}
public static void Save_rdr(Io_url url, Io_stream_rdr rdr, Io_download_fmt download_progress) {
byte[] bry = new byte[4096];
Io_stream_wtr wtr = new_by_url_(url);
try {
wtr.Open();
if (download_progress != Io_download_fmt.Null)
download_progress.Bgn(rdr.Len());
while (true) {
int read = rdr.Read(bry, 0, 4096);
if (read < gplx.core.ios.Io_stream_rdr_.Read_done_compare) break;
if (download_progress != Io_download_fmt.Null)
download_progress.Prog(read);
wtr.Write(bry, 0, read);
}
wtr.Flush();
if (download_progress != Io_download_fmt.Null)
download_progress.Term();
}
finally {wtr.Rls(); rdr.Rls();}
}
}
abstract class Io_stream_wtr_base implements Io_stream_wtr {
java.io.OutputStream zip_stream;
public Io_url Url() {return url;} public Io_stream_wtr Url_(Io_url v) {url = v; trg_bfr = null; return this;} Io_url url;
public void Trg_bfr_(Bry_bfr v) {trg_bfr = v;} Bry_bfr trg_bfr; java.io.ByteArrayOutputStream mem_stream;
public byte[] To_ary_and_clear() {return trg_bfr.To_bry_and_clear();}
@SuppressWarnings("resource") public Io_stream_wtr Open() {
java.io.OutputStream bry_stream = null;
if (trg_bfr == null) {
if (!Io_mgr.Instance.ExistsFil(url)) Io_mgr.Instance.SaveFilStr(url, "");
try {bry_stream = new java.io.FileOutputStream(url.Raw());}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Raw());}
}
else {
mem_stream = new java.io.ByteArrayOutputStream();
bry_stream = mem_stream;
}
zip_stream = Wrap_stream(bry_stream);
return this;
}
public void Write(byte[] bry, int bgn, int len) {
try {zip_stream.write(bry, bgn, len);}
catch (Exception e) {Err_.new_exc(e, "io", "write failed", "bgn", bgn, "len", len);}
}
public void Flush() {
if (trg_bfr != null) {
try {zip_stream.close();} catch (Exception e) {throw Err_.new_exc(e, "io", "flush failed");} // must close zip_stream to flush all bytes
trg_bfr.Add(mem_stream.toByteArray());
}
}
public void Rls() {
try {
if (zip_stream != null) zip_stream.close();
if (mem_stream != null) mem_stream.close();
}
catch (Exception e) {throw Err_.new_exc(e, "io", "close failed", "url", url.Raw());}
}
public abstract java.io.OutputStream Wrap_stream(java.io.OutputStream stream);
}
class Io_stream_wtr_bzip2 extends Io_stream_wtr_base {
@Override public byte Tid() {return Io_stream_.Tid_bzip2;}
@Override public java.io.OutputStream Wrap_stream(java.io.OutputStream stream) {
try {return new org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream(stream);}
catch (Exception e) {throw Err_.new_exc(e, "io", "failed to open bzip2 stream");}
}
static final byte[] Bz2_header = new byte[] {Byte_ascii.Ltr_B, Byte_ascii.Ltr_Z};
}
class Io_stream_wtr_gzip extends Io_stream_wtr_base {
@Override public byte Tid() {return Io_stream_.Tid_gzip;}
@Override public java.io.OutputStream Wrap_stream(java.io.OutputStream stream) {
try {return new java.util.zip.GZIPOutputStream(stream);}
catch (Exception e) {throw Err_.new_exc(e, "io", "failed to open gz stream");}
}
}
class Io_stream_wtr_zip implements Io_stream_wtr {
private java.util.zip.ZipOutputStream zip_stream;
@Override public byte Tid() {return Io_stream_.Tid_zip;}
public Io_url Url() {return url;} public Io_stream_wtr Url_(Io_url v) {url = v; trg_bfr = null; return this;} private Io_url url = Io_url_.Empty;
public void Trg_bfr_(Bry_bfr v) {trg_bfr = v;} private Bry_bfr trg_bfr; private java.io.ByteArrayOutputStream mem_stream;
@SuppressWarnings("resource") // rely on zip_stream to close bry_stream
public Io_stream_wtr Open() {
java.io.OutputStream bry_stream;
if (trg_bfr == null) {
if (!Io_mgr.Instance.ExistsFil(url)) Io_mgr.Instance.SaveFilStr(url, ""); // create file if it doesn't exist
try {bry_stream = new java.io.FileOutputStream(url.Xto_api());}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Raw());}
}
else {
mem_stream = new java.io.ByteArrayOutputStream();
bry_stream = mem_stream;
}
zip_stream = new java.util.zip.ZipOutputStream(bry_stream);
java.util.zip.ZipEntry entry = new java.util.zip.ZipEntry("file");
try {zip_stream.putNextEntry(entry);}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Raw());}
return this;
}
public void Write(byte[] bry, int bgn, int len) {
try {zip_stream.write(bry, bgn, len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "write failed", "url", url.Raw(), "bgn", bgn, "len", len);}
}
public void Flush() {// fixed as of DATE:2014-04-15
try {
zip_stream.closeEntry();
zip_stream.close();
if (trg_bfr != null)
trg_bfr.Add(mem_stream.toByteArray());
zip_stream.flush();
}
catch (Exception e) {throw Err_.new_exc(e, "io", "flush failed", "url", url.Raw());}
}
public void Rls() {
try {
if (zip_stream != null) zip_stream.close();
if (mem_stream != null) mem_stream.close();
}
catch (Exception e) {throw Err_.new_exc(e, "io", "close failed", "url", url.Raw());}
}
public byte[] To_ary_and_clear() {
byte[] rv = trg_bfr.To_bry_and_clear();
this.Rls();
return rv;
}
}
class Io_stream_wtr_file implements Io_stream_wtr {
IoStream bry_stream;
@Override public byte Tid() {return Io_stream_.Tid_raw;}
public Io_url Url() {return url;} public Io_stream_wtr Url_(Io_url v) {url = v; return this;} Io_url url;
public void Trg_bfr_(Bry_bfr v) {trg_bfr = v;} private Bry_bfr trg_bfr; java.io.ByteArrayOutputStream mem_stream;
public Io_stream_wtr Open() {
try {
if (trg_bfr == null)
bry_stream = Io_mgr.Instance.OpenStreamWrite(url);
}
catch (Exception e) {throw Err_.new_exc(e, "io", "open failed", "url", url.Raw());}
return this;
}
public void Write(byte[] bry, int bgn, int len) {
if (trg_bfr == null) {
try {bry_stream.Write(bry, bgn, len);}
catch (Exception e) {throw Err_.new_exc(e, "io", "write failed", "url", url.Raw(), "bgn", bgn, "len", len);}
}
else
trg_bfr.Add_mid(bry, bgn, bgn + len);
}
public byte[] To_ary_and_clear() {
return trg_bfr == null ? Io_mgr.Instance.LoadFilBry(url) : trg_bfr.To_bry_and_clear();
}
public void Flush() {
if (trg_bfr == null)
bry_stream.Flush();
}
public void Rls() {
try {
if (trg_bfr == null)
bry_stream.Rls();
}
catch (Exception e) {throw Err_.new_exc(e, "io", "close failed", "url", url.Raw());}
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
public class Io_url_obj_ref {
public Io_url Val() {return val;} public Io_url_obj_ref Val_(Io_url v) {val = v; return this;} private Io_url val;
public String Val_as_str() {return val.Raw();}
@Override public String toString() {return val.Raw();}
@Override public int hashCode() {return val.hashCode();}
@Override public boolean equals(Object obj) {return String_.Eq(val.Raw(), ((Io_url_obj_ref)obj).val.Raw());}
public static Io_url_obj_ref new_(Io_url val) {
Io_url_obj_ref rv = new Io_url_obj_ref();
rv.val = val;
return rv;
} Io_url_obj_ref() {}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_data {
public int Uid() {return uid;} int uid = uid_next++;
public Gfo_msg_itm Item() {return item;} Gfo_msg_itm item;
public Object[] Vals() {return vals;} Object[] vals;
public byte[] Src_bry() {return src_bry;} private byte[] src_bry;
public int Src_bgn() {return src_bgn;} int src_bgn;
public int Src_end() {return src_end;} int src_end;
public Gfo_msg_data Ctor_val_many(Gfo_msg_itm item, Object[] vals) {this.item = item; this.vals = vals; return this;}
public Gfo_msg_data Ctor_src_many(Gfo_msg_itm item, byte[] src_bry, int src_bgn, int src_end, Object[] vals) {this.item = item; this.src_bry = src_bry; this.src_bgn = src_bgn; this.src_end = src_end; this.vals = vals; return this;}
public void Clear() {
item = null; vals = null; src_bry = null;
}
public String Gen_str_ary() {return item.Gen_str_ary(vals);}
static int uid_next = 0;
public static final Gfo_msg_data[] Ary_empty = new Gfo_msg_data[0];
}

View 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.core.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_grp implements Gfo_msg_obj {
public Gfo_msg_grp(Gfo_msg_grp owner, int uid, byte[] key) {
this.owner = owner; this.uid = uid; this.key = key; this.key_str = String_.new_a7(key);
if (owner != null) {
owner.subs.Add(this);
path = Gfo_msg_grp_.Path(owner.path, key);
}
else
path = Bry_.Empty;
}
public void Subs_clear() {subs.Clear();}
public Gfo_msg_grp Owner() {return owner;} Gfo_msg_grp owner;
public int Uid() {return uid;} int uid;
public byte[] Key() {return key;} private byte[] key;
public String Key_str() {return key_str;} private String key_str;
public byte[] Path() {return path;} private byte[] path;
public String Path_str() {return String_.new_a7(path);}
public Gfo_msg_obj Subs_get_by_key(String sub_key) {
int subs_len = subs.Count();
for (int i = 0; i < subs_len; i++) {
Gfo_msg_obj sub = (Gfo_msg_obj)subs.Get_at(i);
if (String_.Eq(sub_key, sub.Key_str())) return sub;
}
return null;
}
public void Subs_add(Gfo_msg_itm item) {subs.Add(item);}
List_adp subs = List_adp_.new_();
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_grp_ {
public static final Gfo_msg_grp Root_gplx = new Gfo_msg_grp(null, Gfo_msg_grp_.Uid_next(), Bry_.new_a7("gplx"));
public static final Gfo_msg_grp Root = new Gfo_msg_grp(null, Gfo_msg_grp_.Uid_next(), Bry_.Empty);
public static Gfo_msg_grp prj_(String key) {return new Gfo_msg_grp(Root , Gfo_msg_grp_.Uid_next(), Bry_.new_a7(key));}
public static Gfo_msg_grp new_(Gfo_msg_grp owner, String key) {return new Gfo_msg_grp(owner , Gfo_msg_grp_.Uid_next(), Bry_.new_a7(key));}
public static int Uid_next() {return uid_next++;} static int uid_next = 0;
public static byte[] Path(byte[] owner_path, byte[] key) {
if (owner_path != Bry_.Empty) tmp_bfr.Add(owner_path).Add_byte(Byte_ascii.Dot); // only add "." if owner_path is available; prevents creating ".gplx"
return tmp_bfr.Add(key).To_bry_and_clear();
}
static Bry_bfr tmp_bfr = Bry_bfr.reset_(256);
}

View File

@@ -0,0 +1,57 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have 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.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_itm implements Gfo_msg_obj {
public Gfo_msg_itm(Gfo_msg_grp owner, int uid, byte cmd, byte[] key_bry, byte[] fmt, boolean add_to_owner) {
this.owner = owner; this.uid = uid; this.cmd = cmd; this.key_bry = key_bry; this.fmt = fmt;
this.key_str = String_.new_a7(key_bry);
this.path_bry = Gfo_msg_grp_.Path(owner.Path(), key_bry);
if (add_to_owner) owner.Subs_add(this);
}
public Gfo_msg_grp Owner() {return owner;} Gfo_msg_grp owner;
public int Uid() {return uid;} int uid;
public byte[] Path_bry() {return path_bry;} private byte[] path_bry;
public String Path_str() {return String_.new_u8(path_bry);}
public byte[] Key_bry() {return key_bry;} private byte[] key_bry;
public String Key_str() {return key_str;} private String key_str;
public Gfo_msg_obj Subs_get_by_key(String sub_key) {return null;}
public byte Cmd() {return cmd;} private byte cmd;
public byte[] Fmt() {return fmt;} private byte[] fmt;
public Bry_fmtr Fmtr() {if (fmtr == null) fmtr = Bry_fmtr.new_bry_(fmt).Compile(); return fmtr;} Bry_fmtr fmtr;
public String Gen_str_many(Object... vals) {return Gen_str_ary(vals);}
public String Gen_str_ary(Object[] vals) {
if (fmtr == null) fmtr = Bry_fmtr.new_bry_(fmt).Compile();
if (fmtr.Fmt_args_exist()) {
fmtr.Bld_bfr_many(tmp_bfr, vals);
return tmp_bfr.To_str_and_clear();
}
else
return String_.new_u8(fmt);
}
public String Gen_str_one(Object val) {
if (fmtr == null) fmtr = Bry_fmtr.new_bry_(fmt).Compile();
if (fmtr.Fmt_args_exist()) {
fmtr.Bld_bfr_one(tmp_bfr, val);
return tmp_bfr.To_str_and_clear();
}
else
return String_.new_u8(fmt);
}
public String Gen_str_none() {return key_str;}
static Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_itm_ {
public static final byte Cmd_null = 0, Cmd_log = 1, Cmd_note = 2, Cmd_warn = 3, Cmd_stop = 4, Cmd_fail = 5;
public static final byte[][] CmdBry = new byte[][] {Object_.Bry__null, Bry_.new_a7("log"), Bry_.new_a7("note"), Bry_.new_a7("warn"), Bry_.new_a7("stop"), Bry_.new_a7("fail")};
public static Gfo_msg_itm new_note_(Gfo_msg_grp owner, String key) {return new_(owner, Cmd_note, key, key);}
public static Gfo_msg_itm new_fail_(Gfo_msg_grp owner, String key, String fmt) {return new_(owner, Cmd_warn, key, fmt);}
public static Gfo_msg_itm new_warn_(Gfo_msg_grp owner, String key) {return new_(owner, Cmd_warn, key, key);}
public static Gfo_msg_itm new_warn_(Gfo_msg_grp owner, String key, String fmt) {return new_(owner, Cmd_warn, key, fmt);}
public static Gfo_msg_itm new_(Gfo_msg_grp owner, byte cmd, String key, String fmt) {return new Gfo_msg_itm(owner, Gfo_msg_grp_.Uid_next(), cmd, Bry_.new_a7(key), Bry_.new_a7(fmt), false);}
}

View 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.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_log {
public Gfo_msg_log(String root_key) {root = new Gfo_msg_root(root_key);} Gfo_msg_root root;
public int Ary_len() {return ary_idx;}
public Gfo_msg_data Ary_get(int i) {return ary[i];}
public Gfo_msg_log Clear() {
for (int i = 0; i < ary_idx; i++)
ary[i].Clear();
ary_idx = 0;
return this;
}
public Gfo_msg_log Add_str_warn_key_none(String grp, String itm, byte[] src, int pos) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, null, src, pos, pos + 1, null);}
public Gfo_msg_log Add_str_warn_key_none(String grp, String itm, byte[] src, int bgn, int end) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, null, src, bgn, end, null);}
public Gfo_msg_log Add_str_warn_fmt_none(String grp, String itm, String fmt) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , Bry_.Empty, -1, -1, null);}
public Gfo_msg_log Add_str_warn_fmt_none(String grp, String itm, String fmt, byte[] src, int pos) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , src, pos, pos + 1, null);}
public Gfo_msg_log Add_str_warn_fmt_none(String grp, String itm, String fmt, byte[] src, int bgn, int end) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , src, bgn, end, null);}
public Gfo_msg_log Add_str_warn_fmt_many(String grp, String itm, String fmt, Object... vals) {return Add_str(Gfo_msg_itm_.Cmd_warn, grp, itm, fmt , Bry_.Empty, -1, -1, vals);}
Gfo_msg_log Add_str(byte cmd, String owner_key, String itm, String fmt, byte[] src, int bgn, int end, Object[] vals) {
if (ary_idx >= ary_max) ary_expand();
ary[ary_idx++] = root.Data_new_many(cmd, src, bgn, end, owner_key, itm, fmt, vals);
return this;
}
public Gfo_msg_log Add_itm_none(Gfo_msg_itm itm, byte[] src, int bgn, int end) {return Add_itm(itm, src, bgn, end, null);}
public Gfo_msg_log Add_itm_many(Gfo_msg_itm itm, byte[] src, int bgn, int end, Object... val_ary) {return Add_itm(itm, src, bgn, end, val_ary);}
Gfo_msg_log Add_itm(Gfo_msg_itm itm, byte[] src, int bgn, int end, Object[] vals) {
if (ary_idx >= ary_max) ary_expand();
ary[ary_idx++] = root.Data_new_many(itm, src, bgn, end, vals);
return this;
}
void ary_expand() {
int new_max = ary_max == 0 ? 2 : ary_max * 2;
ary = (Gfo_msg_data[])Array_.Expand(ary, new Gfo_msg_data[new_max], ary_max);
ary_max = new_max;
}
Gfo_msg_data[] ary = Gfo_msg_data.Ary_empty; int ary_idx, ary_max;
public static Gfo_msg_log Test() {return new Gfo_msg_log("test");}
}

View File

@@ -0,0 +1,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.log_msgs; import gplx.*; import gplx.core.*;
public interface Gfo_msg_obj {
String Key_str();
Gfo_msg_obj Subs_get_by_key(String sub_key);
}

View File

@@ -0,0 +1,80 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have 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.log_msgs; import gplx.*; import gplx.core.*;
public class Gfo_msg_root {
public Gfo_msg_root(String root_key) {
this.root_key = root_key;
this.root = Gfo_msg_grp_.new_(Gfo_msg_grp_.Root, root_key);
} String root_key;
public void Data_ary_clear() {
for (int i = 0; i < data_ary_idx; i++)
data_ary[i].Clear();
data_ary_idx = 0;
}
public void Data_ary_len_(int v) {
data_ary_len = v;
data_ary = new Gfo_msg_data[data_ary_len];
for (int i = 0; i < data_ary_len; i++)
data_ary[i] = new Gfo_msg_data();
data_ary_idx = 0;
} int data_ary_len; int data_ary_idx; Gfo_msg_data[] data_ary;
public void Reset() {
root.Subs_clear();
owners.Clear();
uid_list_next = uid_item_next = 0;
Data_ary_clear();
}
public Gfo_msg_data Data_new_note_many(String owner_key, String key, String fmt, Object... vals) {return Data_new_many(Gfo_msg_itm_.Cmd_note, Bry_.Empty, -1, -1, owner_key, key, fmt, vals);}
public Gfo_msg_data Data_new_many(byte cmd, String owner_key, String key, String fmt, Object[] vals) {return Data_new_many(cmd, Bry_.Empty, -1, -1, owner_key, key, fmt, vals);}
public Gfo_msg_data Data_new_many(byte cmd, byte[] src, int bgn, int end, String owner_key, String key, String fmt, Object[] vals) {
Object owner_obj = owners.Get_by(owner_key);
Gfo_msg_grp owner = null;
if (owner_obj == null) {
owner = New_list_by_key(owner_key);
owners.Add(owner_key, owner);
}
else
owner = (Gfo_msg_grp)owner_obj;
Gfo_msg_itm itm = (Gfo_msg_itm)owner.Subs_get_by_key(key);
if (itm == null)
itm = new Gfo_msg_itm(owner, uid_item_next++, cmd, Bry_.new_u8(key), fmt == null ? Bry_.Empty : Bry_.new_a7(fmt), false);
return Data_new_many(itm, src, bgn, end, vals);
}
public Gfo_msg_data Data_new_many(Gfo_msg_itm itm, byte[] src, int bgn, int end, Object... vals) {return Data_get().Ctor_src_many(itm, src, bgn, end, vals);}
public Gfo_msg_data Data_get() {
return data_ary_idx < data_ary_len ? data_ary[data_ary_idx++] : new Gfo_msg_data();
}
Gfo_msg_grp New_list_by_key(String key) {
String[] segs = String_.Split(key, '.');
int segs_len = segs.length; int segs_last = segs_len - 1;
Gfo_msg_grp cur_list = root;
for (int i = 0; i < segs_last; i++) {
String seg = segs[i];
Gfo_msg_grp sub_list = (Gfo_msg_grp)cur_list.Subs_get_by_key(seg);
if (sub_list == null)
sub_list = new Gfo_msg_grp(cur_list, uid_list_next++, Bry_.new_a7(key));
cur_list = sub_list;
}
return cur_list;
}
Gfo_msg_grp root;
Ordered_hash owners = Ordered_hash_.New();
int uid_list_next = 0;
int uid_item_next = 0;
public static final Gfo_msg_root Instance = new Gfo_msg_root("gplx");
}

View File

@@ -0,0 +1,62 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.log_msgs; import gplx.*; import gplx.core.*;
import org.junit.*;
public class Gfo_msg_root_tst {
Gfo_msg_root_fxt fxt = new Gfo_msg_root_fxt();
@Before public void setup() {fxt.Reset();}
@Test public void Str() {
fxt.Clear().Expd_data_str_("failed a0 b0").Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a0", "b0");
fxt.Clear().Expd_data_str_("failed a1 b1").Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a1", "b1");
}
// @Test public void Item() { // DISABLED: no longer registering items with owner;
// fxt.Clear().Expd_item_uid_(0).Expd_item_fmtr_arg_exists_(Bool_.Y).Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a0", "b0");
// fxt.Clear().Expd_item_uid_(1).Expd_item_fmtr_arg_exists_(Bool_.N).Tst_data_new_many("proj.cls.proc", "err_1", "failed");
// fxt.Clear().Expd_item_uid_(0).Tst_data_new_many("proj.cls.proc", "err_0", "failed ~{0} ~{1}", "a0", "b0"); // make sure item_uid stays the same
// }
@Test public void Cache() {
fxt.Mgr().Data_ary_len_(2);
fxt.Clear().Expd_data_uid_(0).Tst_data_new_many("x", "err_0", "a");
fxt.Clear().Expd_data_uid_(1).Tst_data_new_many("x", "err_0", "b");
fxt.Clear().Expd_data_uid_(2).Tst_data_new_many("x", "err_0", "a");
fxt.Mgr().Data_ary_clear();
fxt.Clear().Expd_data_uid_(0).Tst_data_new_many("x", "err_0", "a");
}
}
class Gfo_msg_root_fxt {
Gfo_msg_root root = new Gfo_msg_root("tst");
public Gfo_msg_root_fxt Reset() {root.Reset(); this.Clear(); return this;}
public Gfo_msg_root_fxt Clear() {
expd_item_uid = -1;
expd_item_fmtr_arg_exists = Bool_.__byte;
expd_data_uid = -1;
expd_data_str = null;
return this;
}
public Gfo_msg_root Mgr() {return root;}
public Gfo_msg_root_fxt Expd_data_uid_(int v) {this.expd_data_uid = v; return this;} int expd_data_uid;
public Gfo_msg_root_fxt Expd_data_str_(String v) {this.expd_data_str = v; return this;} private String expd_data_str;
public Gfo_msg_root_fxt Expd_item_uid_(int v) {this.expd_item_uid = v; return this;} int expd_item_uid;
public Gfo_msg_root_fxt Expd_item_fmtr_arg_exists_(boolean v) {this.expd_item_fmtr_arg_exists = v ? Bool_.Y_byte : Bool_.N_byte; return this;} private byte expd_item_fmtr_arg_exists;
public void Tst_data_new_many(String path, String key, String fmt, Object... vals) {
Gfo_msg_data data = root.Data_new_many(Gfo_msg_itm_.Cmd_note, path, key, fmt, vals);
if (expd_item_uid != -1) Tfds.Eq(expd_item_uid, data.Item().Uid());;
if (expd_item_fmtr_arg_exists != Bool_.__byte) Tfds.Eq(Bool_.By_int(expd_item_fmtr_arg_exists), data.Item().Fmtr().Fmt_args_exist());
if (expd_data_str != null) Tfds.Eq(expd_data_str, data.Item().Gen_str_many(data.Vals()));
}
}

View 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.core.security; import gplx.*; import gplx.core.*;
import gplx.core.consoles.*;
import gplx.core.ios.*; /*IoStream*/
public interface HashAlgo {
String Key();
String CalcHash(Console_adp dialog, IoStream stream);
byte[] Calc_hash_bry(byte[] v);
}

View 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.core.security; import gplx.*; import gplx.core.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import gplx.core.consoles.*;
import gplx.core.ios.*; /*IoStream*/import gplx.core.texts.*; /*Base32Converter*/
public class HashAlgo_ {
public static final HashAlgo Null = new HashAlgo_null();
public static final HashAlgo Sha1 = HashAlgo_sha1.new_();
public static final HashAlgo Md5 = HashAlgo_md5.new_();
public static final HashAlgo Tth192 = HashAlgo_tth192.new_();
public static HashAlgo as_(Object obj) {return obj instanceof HashAlgo ? (HashAlgo)obj : null;}
public static HashAlgo cast(Object obj) {if (obj == null) return null; HashAlgo rv = as_(obj); if (rv == null) throw Err_.new_type_mismatch(HashAlgo.class, obj); return rv;}
public static HashAlgo fetch_(String key) {
if (key == HashAlgo_md5.KEY) return Md5;
else if (key == HashAlgo_sha1.KEY) return Sha1;
else if (key == HashAlgo_tth192.KEY) return Tth192;
else throw Err_.new_unhandled(key);
}
public static HashAlgo store_orSelf_(SrlMgr mgr, String key, HashAlgo or) {
String algoType = mgr.SrlStrOr(key, or.Key());
return mgr.Type_rdr() ? HashAlgo_.fetch_(algoType): or;
}
}
class HashAlgo_null implements HashAlgo {
public String Key() {return "HashAlgo_null";}
public byte[] Calc_hash_bry(byte[] v) {return Bry_.new_a7(CalcHash(Console_adp_.Noop, gplx.core.ios.IoStream_.ary_(v)));}
public String CalcHash(Console_adp dialog, IoStream stream) {return "NullAlgoHash";}
}
class HashAlgo_md5 implements HashAlgo {
public String Key() {return KEY;} public static final String KEY = "md5";
public byte[] Calc_hash_bry(byte[] v) {return Bry_.new_a7(CalcHash(Console_adp_.Noop, IoStream_.ary_(v)));}
public String CalcHash(Console_adp dialog, IoStream stream) {return HashAlgoUtl.CalcHashAsString(dialog, stream, "MD5");}
public static HashAlgo_md5 new_() {return new HashAlgo_md5();} HashAlgo_md5() {}
}
class HashAlgo_sha1 implements HashAlgo {
public String Key() {return KEY;} public static final String KEY = "sha1";
public byte[] Calc_hash_bry(byte[] v) {return Bry_.new_a7(CalcHash(Console_adp_.Noop, IoStream_.ary_(v)));}
public String CalcHash(Console_adp dialog, IoStream stream) {return HashAlgoUtl.CalcHashAsString(dialog, stream, "SHA1");}
public static HashAlgo_sha1 new_() {return new HashAlgo_sha1();} HashAlgo_sha1() {}
}
class HashAlgoUtl {
public static String CalcHashAsString(Console_adp dialog, IoStream stream, String key) {
MessageDigest md = null;
try {md = MessageDigest.getInstance(key);}
catch (NoSuchAlgorithmException e) {throw Err_.new_missing_key(key);}
byte[] buffer = new byte[8192];
int read = 0;
long pos = 0, len = stream.Len(); // pos and len must be long, else will not hash files > 2 GB
while (true) {
read = stream.Read(buffer, 0, 8192);
if (pos >= len) break;
md.update(buffer, 0, read);
pos += read;
}
byte[] md5sum = md.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
String rv = bigInt.toString(16);
int rvLen = rv.length();
while (rvLen < 32) {
rv = "0" + rv;
rvLen++;
}
return rv;
}
public static String XtoStrBase16(byte[] ary) {
BigInteger bigInt = new BigInteger(1, ary);
String rv = bigInt.toString(16);
int rvLen = rv.length();
while (rvLen < 32) {
rv = "0" + rv;
rvLen++;
}
return rv;
}
public static String XtoStrBase32(byte[] ary) {return Base32Converter.Encode(ary);}
}

View File

@@ -0,0 +1,81 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.security; import gplx.*; import gplx.core.*;
import org.junit.*;
import gplx.core.consoles.*; import gplx.core.ios.*; /*IoStream*/
public class HashAlgo_md5_tst {
@Test public void Empty() {
tst_CalcBase16FromString("", "d41d8cd98f00b204e9800998ecf8427e");
}
@Test public void A() {
tst_CalcBase16FromString("a", "0cc175b9c0f1b6a831c399e269772661");
}
@Test public void Abc() {
tst_CalcBase16FromString("abc", "900150983cd24fb0d6963f7d28e17f72");
}
@Test public void A_Za_z0_9() {
tst_CalcBase16FromString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f");
}
//@Test
public void A_1Million() {
tst_CalcBase16FromString(String_.Repeat("a", 1000000), "7707d6ae4e027c70eea2a935c2296f21");
}
void tst_CalcBase16FromString(String raw, String expd) {
IoStream stream = IoStream_.mem_txt_(Io_url_.Empty, raw);
String actl = HashAlgo_.Md5.CalcHash(Console_adp_.Noop, stream);
Tfds.Eq(expd, actl);
}
/*
https://www.cosic.esat.kuleuven.be/nessie/testvectors/hash/md5/Md5-128.unverified.test-vectors
Set 1, vector# 0:
message="" (empty String)
hash=D41D8CD98F00B204E9800998ECF8427E
Set 1, vector# 1:
message="a"
hash=0CC175B9C0F1B6A831C399E269772661
Set 1, vector# 2:
message="abc"
hash=900150983CD24FB0D6963F7D28E17F72
Set 1, vector# 3:
message="message digest"
hash=F96B697D7CB7938D525A2F31AAF161D0
Set 1, vector# 4:
message="abcdefghijklmnopqrstuvwxyz"
hash=C3FCD3D76192E4007DFB496CCA67E13B
Set 1, vector# 5:
message="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
hash=8215EF0796A20BCAAAE116D3876C664A
Set 1, vector# 6:
message="A...Za...z0...9"
hash=D174AB98D277D9F5A5611C2C9F419D9F
Set 1, vector# 7:
message=8 times "1234567890"
hash=57EDF4A22BE3C955AC49DA2E2107B67A
Set 1, vector# 8:
message=1 million times "a"
hash=7707D6AE4E027C70EEA2A935C2296F21
*/
}

View File

@@ -0,0 +1,81 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.security; import gplx.*; import gplx.core.*;
import org.junit.*;
import gplx.core.consoles.*; import gplx.core.ios.*; /*IoStream*/
public class HashAlgo_sha1_tst {
@Test public void Empty() {
tst_CalcBase16FromString("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
}
@Test public void A() {
tst_CalcBase16FromString("a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
}
@Test public void Abc() {
tst_CalcBase16FromString("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
}
@Test public void A_Za_z0_9() {
tst_CalcBase16FromString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "761c457bf73b14d27e9e9265c46f4b4dda11f940");
}
//@Test
public void A_1Million() {
tst_CalcBase16FromString(String_.Repeat("a", 1000000), "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
}
void tst_CalcBase16FromString(String raw, String expd) {
IoStream stream = IoStream_.mem_txt_(Io_url_.Empty, raw);
String actl = HashAlgo_.Sha1.CalcHash(Console_adp_.Noop, stream);
Tfds.Eq(expd, actl);
}
/*
https://www.cosic.esat.kuleuven.be/nessie/testvectors/
Set 1, vector# 0:
message="" (empty String)
hash=DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
Set 1, vector# 1:
message="a"
hash=86F7E437FAA5A7FCE15D1DDCB9EAEAEA377667B8
Set 1, vector# 2:
message="abc"
hash=A9993E364706816ABA3E25717850C26C9CD0D89D
Set 1, vector# 3:
message="message digest"
hash=C12252CEDA8BE8994D5FA0290A47231C1D16AAE3
Set 1, vector# 4:
message="abcdefghijklmnopqrstuvwxyz"
hash=32D10C7B8CF96570CA04CE37F2A19D84240D3A89
Set 1, vector# 5:
message="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
hash=84983E441C3BD26EBAAE4AA1F95129E5E54670F1
Set 1, vector# 6:
message="A...Za...z0...9"
hash=761C457BF73B14D27E9E9265C46F4B4DDA11F940
Set 1, vector# 7:
message=8 times "1234567890"
hash=50ABF5706A150990A08B2C5EA40FA0E585554732
Set 1, vector# 8:
message=1 million times "a"
hash=34AA973CD4C4DAA4F61EEB2BDBAD27316534016F
*/
}

File diff suppressed because it is too large Load Diff

View 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.core.security; import gplx.*; import gplx.core.*;
import org.junit.*;
public class HashAlgo_tth192_tree_tst {
@Test public void CalcRecursiveHalves() {
tst_CalcRecursiveHalves(129, 128);
tst_CalcRecursiveHalves(128, 127);
tst_CalcRecursiveHalves(100, 99);
tst_CalcRecursiveHalves(20, 19);
tst_CalcRecursiveHalves(6, 5);
tst_CalcRecursiveHalves(5, 4);
tst_CalcRecursiveHalves(4, 3);
tst_CalcRecursiveHalves(3, 2);
tst_CalcRecursiveHalves(2, 1);
tst_CalcRecursiveHalves(1, 0);
tst_CalcRecursiveHalves(0, 0);
}
@Test public void CalcWorkUnits() {
tst_CalcWorkUnits(101, 21); // leafs; 10 full, 1 part (+11) -> reduce 11 to 5+1 (+5) -> reduce 6 to 3 (+3) -> reduce 3 to 1+1 (+1) -> reduce 2 to 1 (+1)
tst_CalcWorkUnits(100, 19); // leafs; 10 full (+10) -> reduce 10 to 5 (+5) -> reduce 5 to 2+1 (+2) -> reduce 3 to 1+1 (+1) -> reduce 2 to 1 (+1)
tst_CalcWorkUnits(30, 5); // leafs; 3 full (+3) -> reduce 3 to 1+1 (+1) -> reduce 2 to 1 (+1)
tst_CalcWorkUnits(11, 3); // leafs: 1 full, 1 part (+2) -> reduce 2 to 1 (+1)
tst_CalcWorkUnits(10, 1);
tst_CalcWorkUnits(9, 1);
tst_CalcWorkUnits(1, 1);
tst_CalcWorkUnits(0, 1);
}
void tst_CalcWorkUnits(int length, int expd) {
HashAlgo_tth192 algo = HashAlgo_tth192.new_(); algo.BlockSize_set(10);
int actl = algo.CalcWorkUnits(length);
Tfds.Eq(expd, actl);
}
void tst_CalcRecursiveHalves(int val, int expd) {
int actl = CalcRecursiveHalvesMock(val);
Tfds.Eq(expd, actl);
}
int CalcRecursiveHalvesMock(int val) {
if (val <= 1) return 0;
int rv = 0;
while (true) {
int multiple = val / 2;
int remainder = val % 2;
rv += multiple;
val = multiple + remainder;
if (val == 1)
return remainder == 0 ? rv : ++rv;
}
}
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.security; import gplx.*; import gplx.core.*;
import org.junit.*; import gplx.core.consoles.*; import gplx.core.ios.*; /*IoStream*/
public class HashAlgo_tth192_tst {
@Test public void Char0000() {tst_CalcBase32FromString("", "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ");}
@Test public void Char0001() {tst_CalcBase32FromString("\0", "VK54ZIEEVTWNAUI5D5RDFIL37LX2IQNSTAXFKSA");}
@Test public void Char0002() {tst_CalcBase32FromString("ab", "XQXRSGMB3PSN2VGZYJMNJG6SOOQ3JIGQHD2I6PQ");}
@Test public void Char0003() {tst_CalcBase32FromString("abc", "ASD4UJSEH5M47PDYB46KBTSQTSGDKLBHYXOMUIA");}
@Test public void Char0004() {tst_CalcBase32FromString("abcd", "SQF2PFTVIFRR5KJSI45IDENXMB43NI7EIXYGHGI");}
@Test public void Char0005() {tst_CalcBase32FromString("abcde", "SKGLNP5WV7ZUMF6IUK5CYXBE3PI4C6PHWNVM2YQ");}
@Test public void Char0009() {tst_CalcBase32FromString("abcdefghi", "RUIKHZFO4NIY6NNUHJMAC2I26U3U65FZWCO3UFY");}
@Test public void Char1024() {tst_CalcBase32FromString(String_.Repeat("A", 1024), "L66Q4YVNAFWVS23X2HJIRA5ZJ7WXR3F26RSASFA");}
@Test public void Char1025() {tst_CalcBase32FromString(String_.Repeat("A", 1025), "PZMRYHGY6LTBEH63ZWAHDORHSYTLO4LEFUIKHWY");}
// @Test // commented out due to time (approx 17.94 seconds)
public void Ax2Pow27() { // 134 MB
tst_CalcBase32FromString(String_.Repeat("A", (int)Math_.Pow(2, 27)), "QNIJO36QDIQREUT3HWK4MDVKD2T6OENAEKYADTQ");
}
void tst_CalcBase32FromString(String raw, String expd) {
IoStream stream = IoStream_.mem_txt_(Io_url_.Empty, raw);
String actl = HashAlgo_.Tth192.CalcHash(Console_adp_.Noop, stream);
Tfds.Eq(expd, actl);
}
}
/*
The empty (zero-length) file:
urn:tree:tiger:LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ
A file with a single zero byte:
urn:tree:tiger:VK54ZIEEVTWNAUI5D5RDFIL37LX2IQNSTAXFKSA
A file with 1024 'A' characters:
urn:tree:tiger:L66Q4YVNAFWVS23X2HJIRA5ZJ7WXR3F26RSASFA
A file with 1025 'A' characters:
urn:tree:tiger:PZMRYHGY6LTBEH63ZWAHDORHSYTLO4LEFUIKHWY
http://open-content.net/specs/draft-jchapweske-thex-02.html
A file with 134,217,728 'A' characters (2 Pow 27)
urn:tree:tiger:QNIJO36QDIQREUT3HWK4MDVKD2T6OENAEKYADTQ
queried against DC++ 0.698
*/

View File

@@ -0,0 +1,41 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.security; import gplx.*; import gplx.core.*;
import org.junit.*; import gplx.core.consoles.*; import gplx.core.ios.*; /*IoStream*/
public class HashDlgWtr_tst {
@Before public void setup() {
HashAlgo_tth192 algo = HashAlgo_tth192.new_();
algo.BlockSize_set(10);
calc = algo;
}
@Test public void Basic() {
tst_Status(10, stringAry_(" - hash: 100%"));
tst_Status(11, stringAry_(" - hash: 66%"));
tst_Status(30, stringAry_(" - hash: 40%", " - hash: 60%", " - hash: 100%"));
}
void tst_Status(int count, String[] expdWritten) {
Console_adp__mem dialog = Console_adp_.Dev();
String data = String_.Repeat("A", count);
IoStream stream = IoStream_.mem_txt_(Io_url_.Empty, data);
calc.CalcHash(dialog, stream);
String[] actlWritten = dialog.Written().To_str_ary();
Tfds.Eq_ary(actlWritten, expdWritten);
}
String[] stringAry_(String... ary) {return ary;}
HashAlgo calc;
}

View 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.core.tests; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class PerfLogMgr_fxt {
public void Init(Io_url url, String text) {
this.url = url;
entries.Resize_bounds(1000);
entries.Add(new PerfLogItm(0, text + "|" + DateAdp_.Now().XtoStr_gplx()));
tmr.Bgn();
}
public void Write(String text) {
long milliseconds = tmr.ElapsedMilliseconds();
entries.Add(new PerfLogItm(milliseconds, text));
tmr.Bgn();
}
public void WriteFormat(String fmt, Object... ary) {
long milliseconds = tmr.ElapsedMilliseconds();
String text = String_.Format(fmt, ary);
entries.Add(new PerfLogItm(milliseconds, text));
tmr.Bgn();
}
public void Flush() {
String_bldr sb = String_bldr_.new_();
for (Object itmObj : entries) {
PerfLogItm itm = (PerfLogItm)itmObj;
sb.Add(itm.To_str()).Add_char_crlf();
}
Io_mgr.Instance.AppendFilStr(url, sb.To_str());
entries.Clear();
}
List_adp entries = List_adp_.new_(); PerfLogTmr tmr = PerfLogTmr.new_(); Io_url url = Io_url_.Empty;
public static final PerfLogMgr_fxt Instance = new PerfLogMgr_fxt(); PerfLogMgr_fxt() {}
class PerfLogItm {
public String To_str() {
String secondsStr = TimeSpanAdp_.To_str(milliseconds, TimeSpanAdp_.Fmt_Default);
secondsStr = String_.PadBgn(secondsStr, 7, "0"); // 7=000.000; left-aligns all times
return String_.Concat(secondsStr, "|", text);
}
long milliseconds; String text;
@gplx.Internal protected PerfLogItm(long milliseconds, String text) {
this.milliseconds = milliseconds; this.text = text;
}
}
}
class PerfLogTmr {
public void Bgn() {bgn = Env_.TickCount();} long bgn;
public long ElapsedMilliseconds() {return Env_.TickCount() - bgn; }
public static PerfLogTmr new_() {return new PerfLogTmr();} PerfLogTmr() {}
}

View 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.core.texts; import gplx.*; import gplx.core.*;
public class Base32Converter {
public static String EncodeString(String orig) {return Encode(Bry_.new_u8(orig));}
public static String Encode(byte[] raw) {
int i = 0, index = 0, digit = 0; int currByte, nextByte;
int rawLen = Array_.Len(raw);
char[] ary = new char[(rawLen + 7) * 8 / 5]; int aryPos = 0;
while (i < rawLen) {
currByte = (raw[i] >= 0) ? raw[i] : raw[i] + 256; // unsign; java converts char 128+ -> byte -128
if (index > 3) { /* Is the curPath digit going to span a byte boundary? */
if ((i+1) < rawLen)
nextByte = (raw[i+1] >= 0) ? raw[i+1] : (raw[i+1] + 256);
else
nextByte = 0;
digit = currByte & (0xFF >> index);
index = (index + 5) % 8;
digit <<= index;
digit |= nextByte >> (8 - index);
i++;
}
else {
digit = (currByte >> (8 - (index + 5))) & 0x1F;
index = (index + 5) % 8;
if (index == 0) i++;
}
ary[aryPos++] = String_.CharAt(chars, digit);
}
return new String(ary, 0, aryPos);
}
public static String DecodeString(String orig) {return String_.new_u8(Decode(orig));}
public static byte[] Decode(String raw) {
int i, index, lookup, offset; byte digit;
int rawLen = String_.Len(raw);
int rvLen = rawLen * 5 / 8;
byte[] rv = new byte[rvLen];
for (i = 0, index = 0, offset = 0; i < rawLen; i++) {
lookup = String_.CharAt(raw, i) - '0';
if (lookup < 0 || lookup >= valsLen) continue; /* Skip any char outside the lookup table */
digit = vals[lookup];
if (digit == 0x7F) continue; /* If this digit is not in the table, ignore it */
if (index <= 3) {
index = (index + 5) % 8;
if (index == 0) {
rv[offset] |= digit;
offset++;
if(offset >= rvLen) break;
}
else
rv[offset] |= (byte)(digit << (8 - index));
}
else {
index = (index + 5) % 8;
rv[offset] |= (byte)(digit >> index);
offset++;
if(offset >= rvLen) break;
rv[offset] |= (byte)(digit << (8 - index));
}
}
return rv;
}
static String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
static int valsLen = 80;
static byte[] vals = {
0x7F,0x7F,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, // '0', '1', '2', '3', '4', '5', '6', '7'
0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F, // '8', '9', ':', ';', '<', '=', '>', '?'
0x7F,0x00,0x01,0x02,0x03,0x04,0x05,0x06, // '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G'
0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, // 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, // 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W'
0x17,0x18,0x19,0x7F,0x7F,0x7F,0x7F,0x7F, // 'X', 'Y', 'Z', '[', '\', ']', '^', '_'
0x7F,0x00,0x01,0x02,0x03,0x04,0x05,0x06, // '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g'
0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, // 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'
0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, // 'p', 'q', 'r', 's', 't', 'u', 'v', 'w'
0x17,0x18,0x19,0x7F,0x7F,0x7F,0x7F,0x7F // 'x', 'y', 'z', '{', '|', '}', '~', 'DEL'
};
}
/*
source: Azraeus excerpt in java
http://www.koders.com/java/fidA4D6F0DF43E6E9A6B518762366AB7232C14E9DB7.aspx
*/

View 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.core.texts; import gplx.*; import gplx.core.*;
public class Base64Converter {
private final static char[] ALPHABET = String_.XtoCharAry("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
private static int[] toInt = null;//new int[128];
static void Init() {
toInt = new int[128];
for(int i=0; i< ALPHABET.length; i++){
toInt[ALPHABET[i]]= i;
}
}
public static String EncodeString(String orig) {return Encode(Bry_.new_u8(orig));}
public static String Encode(byte[] buf){
if (toInt == null) Init();
int size = buf.length;
char[] ar = new char[((size + 2) / 3) * 4];
int a = 0;
int i=0;
while(i < size){
byte b0 = buf[i++];
byte b1 = (i < size) ? buf[i++] : (byte)0;
byte b2 = (i < size) ? buf[i++] : (byte)0;
int mask = 0x3F;
ar[a++] = ALPHABET[(b0 >> 2) & mask];
ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
ar[a++] = ALPHABET[b2 & mask];
}
switch(size % 3){
case 1: ar[--a] = '=';
ar[--a] = '=';
break;
case 2: ar[--a] = '='; break;
}
return new String(ar);
}
public static String DecodeString(String orig) {return String_.new_u8(Decode(orig));}
public static byte[] Decode(String s){
if (toInt == null) Init();
int sLen = String_.Len(s);
int delta = String_.Has_at_end(s, "==") ? 2 : String_.Has_at_end(s, "=") ? 1 : 0;
byte[] buffer = new byte[sLen *3/4 - delta];
int mask = 0xFF;
int index = 0;
for(int i=0; i< sLen; i+=4){
int c0 = toInt[String_.CharAt(s, i)];
int c1 = toInt[String_.CharAt(s, i + 1)];
buffer[index++]= (byte)(((c0 << 2) | (c1 >> 4)) & mask);
if(index >= buffer.length){
return buffer;
}
int c2 = toInt[String_.CharAt(s, i + 2)];
buffer[index++]= (byte)(((c1 << 4) | (c2 >> 2)) & mask);
if(index >= buffer.length){
return buffer;
}
int c3 = toInt[String_.CharAt(s, i + 3)];
buffer[index++]= (byte)(((c2 << 6) | c3) & mask);
}
return buffer;
}
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.texts; import gplx.*; import gplx.core.*;
import org.junit.*;
public class BaseXXConverter_tst {
@Test public void Base32() {
tst_Base32("", "");
tst_Base32("f", "MY");
tst_Base32("fo", "MZXQ");
tst_Base32("foo", "MZXW6");
tst_Base32("foob", "MZXW6YQ");
tst_Base32("fooba", "MZXW6YTB");
tst_Base32("foobar", "MZXW6YTBOI");
tst_Base32("A", "IE");
tst_Base32("a", "ME");
tst_Base32("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", "IFBEGRCFIZDUQSKKJNGE2TSPKBIVEU2UKVLFOWCZLIZDGNBVGY3Q");
}
@Test public void Base64() {
tst_Base64("", "");
tst_Base64("f", "Zg==");
tst_Base64("fo", "Zm8=");
tst_Base64("foo", "Zm9v");
tst_Base64("foob", "Zm9vYg==");
tst_Base64("fooba", "Zm9vYmE=");
tst_Base64("foobar", "Zm9vYmFy");
// tst_Base64("A", "IE");
// tst_Base64("a", "ME");
// tst_Base64("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", "IFBEGRCFIZDUQSKKJNGE2TSPKBIVEU2UKVLFOWCZLIZDGNBVGY3Q");
}
void tst_Base32(String orig, String expd) {
String actl = Base32Converter.EncodeString(orig);
Tfds.Eq(expd, actl);
String decode = Base32Converter.DecodeString(actl);
Tfds.Eq(orig, decode);
}
void tst_Base64(String orig, String expd) {
String actl = Base64Converter.EncodeString(orig);
Tfds.Eq(expd, actl);
String decode = Base64Converter.DecodeString(actl);
Tfds.Eq(orig, decode);
}
}
//http://tools.ietf.org/html/rfc4648: test vectors for "foobar"

View 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.core.texts; import gplx.*; import gplx.core.*;
public class CharStream {
public char[] Ary() {return ary;} char[] ary;
public int Len() {return len;} int len;
public int Pos() {return pos;} int pos = BgnPos; static final int BgnPos = -1;
public boolean AtBgn() {return pos <= BgnPos;}
public boolean AtEnd() {return pos >= len;}
public boolean AtMid() {return pos > BgnPos && pos < len;}
public char Cur() {try {return ary[pos];} catch (Exception exc) {Err_.Noop(exc); throw Err_.new_missing_idx(pos, this.Len());}}
public void MoveNext() {pos++;}
public void MoveNextBy(int offset) {pos += offset;}
public void MoveBack() {pos--;}
public void MoveBackBy(int offset) {pos -= offset;}
public void Move_to(int val) {pos = val;}
public boolean Match(String match) {
int matchLen = String_.Len(match);
for (int i = 0; i < matchLen; i++) {
int cur = pos + i;
if (cur >= len || ary[cur] != String_.CharAt(match, i)) return false;
}
return true;
}
public boolean MatchAndMove(String match) {
int matchLen = String_.Len(match);
boolean rv = Match(match);
if (rv) MoveNextBy(matchLen);
return rv;
}
public boolean MatchAndMove(char match) {
boolean rv = ary[pos] == match;
if (rv) pos++;
return rv;
}
public String To_str() {return Char_.To_str(ary, 0, len);}
public String XtoStrAtCur(int length) {
length = (pos + length > len) ? len - pos : length;
return Char_.To_str(ary, pos, length);
}
public String To_str_by_pos(int bgn, int end) {
if (bgn < 0) bgn = 0; if (end > len - 1) end = len - 1;
return Char_.To_str(ary, bgn, end - bgn + 1);
}
public static CharStream pos0_(String text) {
CharStream rv = new CharStream();
rv.ary = String_.XtoCharAry(text);
rv.len = Array_.Len(rv.ary);
rv.MoveNext(); // bgn at pos=0
return rv;
} CharStream(){}
}

View File

@@ -0,0 +1,61 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.texts; import gplx.*; import gplx.core.*;
import org.junit.*;
public class CharStream_tst {
@Before public void setup() {
stream = CharStream.pos0_("abcdefgh");
}
@Test public void To_str() {
Tfds.Eq(stream.To_str(), "abcdefgh");
}
@Test public void CurrentText() {
stream.MoveNextBy(1);
Tfds.Eq(stream.XtoStrAtCur(2), "bc");
Tfds.Eq(stream.To_str(), "abcdefgh");
}
@Test public void CurrentText_outOfBounds() {
stream.MoveNextBy(7);
Tfds.Eq(stream.XtoStrAtCur(2), "h");
}
@Test public void Match() {
stream.MoveNextBy(6);
tst_Match(true, "g");
tst_Match(false, "z");
tst_Match(true, "gh");
tst_Match(false, "gz");
tst_Match(false, "ghi");
}
@Test public void AtBounds() {
stream.Move_to(-1);
tst_AtBounds(true, false, false);
stream.Move_to(0);
tst_AtBounds(false, true, false);
stream.Move_to(stream.Len());
tst_AtBounds(false, false, true);
}
void tst_Match(boolean expd, String text) {Tfds.Eq(expd, stream.Match(text));}
void tst_AtBounds(boolean atBgn, boolean atMid, boolean atEnd) {
Tfds.Eq(atBgn, stream.AtBgn());
Tfds.Eq(atMid, stream.AtMid());
Tfds.Eq(atEnd, stream.AtEnd());
}
CharStream stream;
}

View File

@@ -0,0 +1,96 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.texts; import gplx.*; import gplx.core.*;
public class HexDecUtl {
public static int parse_or(String raw, int or) {
int rv = 0; int digit; int factor = 1, rawLen = String_.Len(raw);
for (int i = rawLen - 1; i >= 0; i--) {
digit = XtoInt(String_.CharAt(raw, i));
if (digit == -1) return or;
rv += digit * factor;
factor *= 16;
}
return rv;
}
public static int parse_or(byte[] raw, int or) {return parse_or(raw, 0, raw.length, or);}
public static int parse_or(byte[] raw, int bgn, int end, int or) {
int rv = 0; int factor = 1;
byte b = Byte_.Max_value_127;
for (int i = end - 1; i >= bgn; i--) {
switch (raw[i]) {
case Byte_ascii.Num_0: b = 0; break; case Byte_ascii.Num_1: b = 1; break; case Byte_ascii.Num_2: b = 2; break; case Byte_ascii.Num_3: b = 3; break; case Byte_ascii.Num_4: b = 4; break;
case Byte_ascii.Num_5: b = 5; break; case Byte_ascii.Num_6: b = 6; break; case Byte_ascii.Num_7: b = 7; break; case Byte_ascii.Num_8: b = 8; break; case Byte_ascii.Num_9: b = 9; break;
case Byte_ascii.Ltr_A: b = 10; break; case Byte_ascii.Ltr_B: b = 11; break; case Byte_ascii.Ltr_C: b = 12; break; case Byte_ascii.Ltr_D: b = 13; break; case Byte_ascii.Ltr_E: b = 14; break; case Byte_ascii.Ltr_F: b = 15; break;
case Byte_ascii.Ltr_a: b = 10; break; case Byte_ascii.Ltr_b: b = 11; break; case Byte_ascii.Ltr_c: b = 12; break; case Byte_ascii.Ltr_d: b = 13; break; case Byte_ascii.Ltr_e: b = 14; break; case Byte_ascii.Ltr_f: b = 15; break;
default: b = Byte_.Max_value_127; break;
}
if (b == Byte_.Max_value_127) return or;
rv += b * factor;
factor *= 16;
}
return rv;
}
public static int parse(String raw) {
int rv = parse_or(raw, -1); if (rv == -1) throw Err_.new_parse("HexDec", "raw");
return rv;
}
public static String To_str(int val, int pad) {
char[] ary = new char[8]; int idx = 8; // 8 is max len of hexString; (2^4 * 8); EX: int.MaxValue = 7FFFFFFF
do {
int byt = val % 16;
ary[--idx] = XtoChar(byt);
val /= 16;
} while (val > 0);
while (8 - idx < pad) // pad left with zeros
ary[--idx] = '0';
return String_.new_charAry_(ary, idx, 8-idx);
}
static int XtoInt(char c) {
switch (c) {
case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4;
case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9;
case 'A': return 10; case 'B': return 11; case 'C': return 12; case 'D': return 13; case 'E': return 14; case 'F': return 15;
case 'a': return 10; case 'b': return 11; case 'c': return 12; case 'd': return 13; case 'e': return 14; case 'f': return 15;
default: return -1;
}
}
static char XtoChar(int val) {
switch (val) {
case 0: return '0'; case 1: return '1'; case 2: return '2'; case 3: return '3'; case 4: return '4';
case 5: return '5'; case 6: return '6'; case 7: return '7'; case 8: return '8'; case 9: return '9';
case 10: return 'A'; case 11: return 'B'; case 12: return 'C'; case 13: return 'D'; case 14: return 'E'; case 15: return 'F';
default: throw Err_.new_parse("hexstring", Int_.To_str(val));
}
}
static byte Xto_byte(int v) {
switch (v) {
case 0: return Byte_ascii.Num_0; case 1: return Byte_ascii.Num_1; case 2: return Byte_ascii.Num_2; case 3: return Byte_ascii.Num_3; case 4: return Byte_ascii.Num_4;
case 5: return Byte_ascii.Num_5; case 6: return Byte_ascii.Num_6; case 7: return Byte_ascii.Num_7; case 8: return Byte_ascii.Num_8; case 9: return Byte_ascii.Num_9;
case 10: return Byte_ascii.Ltr_A; case 11: return Byte_ascii.Ltr_B; case 12: return Byte_ascii.Ltr_C; case 13: return Byte_ascii.Ltr_D; case 14: return Byte_ascii.Ltr_E; case 15: return Byte_ascii.Ltr_F;
default: throw Err_.new_parse("hexstring", Int_.To_str(v));
}
}
public static void Write(byte[] bry, int bgn, int end, int val) {
for (int i = end - 1; i > bgn - 1; i--) {
int b = val % 16;
bry[i] = Xto_byte(b);
val /= 16;
if (val == 0) break;
}
}
}

View 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.core.texts; import gplx.*; import gplx.core.*;
import org.junit.*;
public class HexDecUtl_tst {
@Test public void XtoInt() {
tst_XtoInt("0", 0);
tst_XtoInt("F", 15);
tst_XtoInt("0F", 15);
tst_XtoInt("10", 16);
tst_XtoInt("20", 32);
tst_XtoInt("FF", 255);
tst_XtoInt("100", 256);
tst_XtoInt("0a", 10);
tst_XtoInt("7FFFFFFF", Int_.Max_value);
tst_XtoInt_bry("100", 256);
}
@Test public void To_str() {
tst_XtoStr(0, "0");
tst_XtoStr(15, "F");
tst_XtoStr(16, "10");
tst_XtoStr(32, "20");
tst_XtoStr(255, "FF");
tst_XtoStr(Int_.Max_value, "7FFFFFFF");
tst_XtoStr(15, 2, "0F");
tst_XtoStr(15, 3, "00F");
}
@Test public void Write() {
tst_Write("[00000000]", 1, 9, 15, "[0000000F]");
tst_Write("[00000000]", 1, 9, 255, "[000000FF]");
}
private void tst_Write(String s, int bgn, int end, int val, String expd) {
byte[] bry = Bry_.new_a7(s);
HexDecUtl.Write(bry, bgn, end, val);
Tfds.Eq(expd, String_.new_a7(bry));
}
private void tst_XtoInt(String raw, int expd) {
int actl = HexDecUtl.parse(raw);
Tfds.Eq(expd, actl);
}
private void tst_XtoInt_bry(String raw, int expd) {Tfds.Eq(expd, HexDecUtl.parse_or(Bry_.new_a7(raw), -1));}
private void tst_XtoStr(int val, String expd) {tst_XtoStr(val, 0, expd);}
private void tst_XtoStr(int val, int pad, String expd) {
String actl = HexDecUtl.To_str(val, pad);
Tfds.Eq(expd, actl);
}
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.texts; import gplx.*; import gplx.core.*;
import gplx.langs.regxs.*;
public class RegxPatn_cls_ioMatch {
public String Raw() {return raw;} private String raw;
public boolean CaseSensitive() {return caseSensitive;} private boolean caseSensitive;
public boolean Matches(String text) {
text = String_.CaseNormalize(caseSensitive, text);
return Regx_adp_.Match(text, compiled);} // WNT-centric: Io_mgr paths are case-insensitive;
@Override public String toString() {return raw;}
String compiled;
@gplx.Internal protected RegxPatn_cls_ioMatch(String raw, String compiled, boolean caseSensitive) {
this.caseSensitive = caseSensitive;
this.raw = raw;
compiled = String_.CaseNormalize(caseSensitive, compiled);
this.compiled = compiled;
}
}

View File

@@ -0,0 +1,53 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.texts; import gplx.*; import gplx.core.*;
import gplx.core.strings.*; import gplx.langs.regxs.*;
public class RegxPatn_cls_ioMatch_ {
public static final String Wildcard = "*";
public static final String OrDelimiter = "|";
public static final RegxPatn_cls_ioMatch All = RegxPatn_cls_ioMatch_.parse(Wildcard, false);
public static final String ImpossiblePath = "<>"; //"<>" should be an impossible url; NOTE: do not pick * or | or : or \
public static final RegxPatn_cls_ioMatch None = RegxPatn_cls_ioMatch_.parse(RegxPatn_cls_ioMatch_.ImpossiblePath, false);
public static RegxPatn_cls_ioMatch cast(Object obj) {try {return (RegxPatn_cls_ioMatch)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, RegxPatn_cls_ioMatch.class, obj);}}
public static RegxPatn_cls_ioMatch parse(String raw, boolean caseSensitive) {
String compiled = RegxPatn_cls_ioMatch_.Compile(raw);
return new RegxPatn_cls_ioMatch(raw, compiled, caseSensitive);
}
@gplx.Internal protected static String Compile(String raw) {
if (raw == ImpossiblePath) return ImpossiblePath;
String_bldr sb = String_bldr_.new_();
sb.Add(Regx_bldr.Tkn_LineBegin); // Char_LineBegin for exact match (else "LIKE a" would match "abc")
int rawLen = String_.Len(raw);
for (int i = 0; i < rawLen; i++) {
char c = String_.CharAt(raw, i);
if (c == '\\')
sb.Add("\\\\");
else if (c == '*')
sb.Add(".").Add(Regx_bldr.Tkn_Wild_0Plus);
else if (c == '|')
sb.Add(Regx_bldr.Tkn_LineEnd).Add("|").Add(Regx_bldr.Tkn_LineBegin); // each term must be bracketed by lineBgn/lineEnd; ex: A|B -> ^A$|^B$
else
sb.Add(c);
}
sb.Add(Regx_bldr.Tkn_LineEnd);
return sb.To_str();
}
public static final String InvalidCharacters = "|*?\"<>"; // : / \ are omitted b/c they will cause full paths to fail
public static final String ValidCharacters = Regx_bldr.Excludes(InvalidCharacters);
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.texts; import gplx.*; import gplx.core.*;
import org.junit.*;
public class RegxPatn_cls_ioMatch_tst {
@Test public void SimpleMatches() {
tst_Matches("file.cs", "file.cs", true); // basic
tst_Matches("file.cs", "file.cs.exe", false); // fail: must match name precisely
tst_Matches("file.cs", "tst_file.cs", false); // fail: must match name precisely
}
@Test public void Wildcard() {
tst_Matches("*.cs", "file.cs", true); // pass: before
tst_Matches("file*", "file_valid.cs", true); // pass: after
tst_Matches("*.exe", "file.cs", false); // fail: before
tst_Matches("file*", "invalid_file.cs", false); // fail: after
}
@Test public void DoubleWildcard() {
tst_Matches("*cs*", "file.cs", true); // pass: after
tst_Matches("*cs*", "csFile.exe", true); // pass: before
tst_Matches("*cs*", "file.cs.exe", true); // pass: middle
tst_Matches("*cs*", "file.exe", false); // fail
}
@Test public void Compound() {
tst_Matches("*.cs|*.exe", "file.cs", true); // pass: match first
tst_Matches("*.cs|*.exe", "file.exe", true); // pass: match second
tst_Matches("*.cs|*.exe", "file.dll", false); // fail: match neither
tst_Matches("*.cs|*.exe", "file.cs.exe.dll", false); // fail: match neither (though both are embedded)
}
@Test public void Backslash() {
tst_Matches("*\\bin\\*", "C:\\project\\bin\\", true); // pass: dir
tst_Matches("*\\bin\\*", "C:\\project\\bin\\file.dll", true); // pass: fil
tst_Matches("*\\bin\\*", "C:\\project\\binFiles\\", false); // fail
}
@Test public void MixedCase() {
tst_Matches("file.cs", "file.cs", true); // pass: same case
tst_Matches("file.cs", "File.cS", true); // pass: diff case
}
void tst_Matches(String regx, String raw, boolean expd) {
RegxPatn_cls_ioMatch pattern = RegxPatn_cls_ioMatch_.parse(regx, false);
boolean actl = pattern.Matches(raw);
Tfds.Eq(expd, actl);
}
}

Some files were not shown because too many files have changed in this diff Show More