mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
'v3.9.4.1'
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.lists; import gplx.*; import gplx.core.*;
|
||||
public class Binary_search_ {
|
||||
public static int Search(CompareAble[] ary, int ary_len, CompareAble val) {
|
||||
if (ary_len == 1) return 0;
|
||||
int interval = ary_len / 2;
|
||||
int pos = interval - List_adp_.Base1;
|
||||
int pos_last = ary_len - 1;
|
||||
int pos_prv = -1;
|
||||
int loop_count = 0;
|
||||
while (loop_count++ < 32) { // 32 bit integer
|
||||
CompareAble lo = ary[pos];
|
||||
CompareAble hi = pos + 1 == ary_len ? null : ary[pos + 1];
|
||||
int adj = 0;
|
||||
int lo_comp = val.compareTo(lo);
|
||||
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
|
||||
adj = -1;
|
||||
else {
|
||||
if (hi == null) return pos; // hi is null when at last slot in ary
|
||||
int hi_comp = val.compareTo(hi);
|
||||
if (hi_comp == CompareAble_.More) // val is > hi; search slots above
|
||||
adj = 1;
|
||||
else
|
||||
return pos; // val is > lo and < hi; return slot
|
||||
}
|
||||
interval /= 2;
|
||||
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
|
||||
pos += (interval * adj);
|
||||
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
|
||||
if (pos < 0) pos = 0;
|
||||
else if (pos > pos_last) pos = pos_last;
|
||||
pos_prv = pos;
|
||||
}
|
||||
return Int_.Min_value; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
|
||||
}
|
||||
public static int Search(List_adp__getable list, int list_len, CompareAble val) {
|
||||
if (list_len == 1) return 0;
|
||||
int interval = list_len / 2;
|
||||
int pos = interval - List_adp_.Base1;
|
||||
int pos_last = list_len - 1;
|
||||
int pos_prv = -1;
|
||||
int loop_count = 0;
|
||||
while (loop_count++ < 32) { // 32 bit integer
|
||||
CompareAble lo = (CompareAble)list.Get_at(pos);
|
||||
CompareAble hi = pos + 1 == list_len ? null : (CompareAble)list.Get_at(pos + 1);
|
||||
int adj = 0;
|
||||
int lo_comp = val.compareTo(lo);
|
||||
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
|
||||
adj = -1;
|
||||
else {
|
||||
if (hi == null) return pos; // hi is null when at last slot in ary
|
||||
int hi_comp = val.compareTo(hi);
|
||||
if (hi_comp == CompareAble_.More) // val is > hi; search slots above
|
||||
adj = 1;
|
||||
else
|
||||
return pos; // val is > lo and < hi; return slot
|
||||
}
|
||||
interval /= 2;
|
||||
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
|
||||
pos += (interval * adj);
|
||||
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
|
||||
if (pos < 0) pos = 0;
|
||||
else if (pos > pos_last) pos = pos_last;
|
||||
pos_prv = pos;
|
||||
}
|
||||
return Int_.Min_value; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
|
||||
}
|
||||
}
|
||||
@@ -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.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
public interface Binary_comparer {
|
||||
int Compare_val_to_obj(Object val, Object obj);
|
||||
}
|
||||
@@ -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.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
public class Binary_search_ {
|
||||
public static int Search(CompareAble[] ary , CompareAble val) {return Search(new Binary_search_grp__ary(ary) , new Binary_search_cmp__comparable(val));}
|
||||
public static int Search(Object[] ary , Binary_comparer comparer, Object val) {return Search(new Binary_search_grp__ary(ary), new Binary_search_cmp__comparer(comparer, val));}
|
||||
private static int Search(Binary_search_grp grp, Binary_search_cmp cmp) {
|
||||
int grp_len = grp.Len();
|
||||
if (grp_len == 1) return 0; // if 1 item, return 0;
|
||||
if (grp_len == 0) return Bry_find_.Not_found; // if 0 item, return -1
|
||||
|
||||
// init
|
||||
int interval = grp_len / 2;
|
||||
int pos = interval - List_adp_.Base1;
|
||||
int pos_last = grp_len - 1;
|
||||
int pos_prv = -1;
|
||||
int loop_count = 0;
|
||||
while (loop_count++ < 32) { // 32=32-bit integer
|
||||
Object lo = grp.Get_at(pos);
|
||||
Object hi = pos + 1 == grp_len ? null : grp.Get_at(pos + 1);
|
||||
int adj = 0;
|
||||
int lo_comp = cmp.Compare(lo);
|
||||
if (lo_comp == CompareAble_.Less) // val is < lo; search slots below
|
||||
adj = -1;
|
||||
else {
|
||||
if (hi == null) return pos; // hi is null when at last slot in ary
|
||||
int hi_comp = cmp.Compare(hi);
|
||||
switch (hi_comp) {
|
||||
case CompareAble_.More: // val is > hi; search slots above
|
||||
adj = 1;
|
||||
break;
|
||||
case CompareAble_.Same: // val is > hi; search slots above
|
||||
return pos + 1;
|
||||
case CompareAble_.Less: // val is > lo and < hi; return slot
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
interval /= 2;
|
||||
if (interval == 0) interval = 1; // do not allow 0 intervals; pos must always change;
|
||||
pos += (interval * adj);
|
||||
if (pos == 0 && pos_prv == 0) break; // NOTE: this will only happen when 1st member is not ""
|
||||
if (pos < 0) pos = 0;
|
||||
else if (pos > pos_last) pos = pos_last;
|
||||
pos_prv = pos;
|
||||
}
|
||||
return Bry_find_.Not_found; // should only occur if (a) ary's 0th slot is not ""; or (b) some unknown error
|
||||
}
|
||||
}
|
||||
@@ -15,33 +15,41 @@ GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.lists; import gplx.*; import gplx.core.*;
|
||||
package gplx.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
import org.junit.*; import gplx.core.primitives.*;
|
||||
public class Binary_search__tst {
|
||||
private Binary_search__fxt fxt = new Binary_search__fxt();
|
||||
private final Binary_search__fxt fxt = new Binary_search__fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Init_ary("", "e", "j", "o", "t", "y");
|
||||
fxt.Test_binary_search("a", 0);
|
||||
fxt.Test_binary_search("f", 1);
|
||||
fxt.Test_binary_search("k", 2);
|
||||
fxt.Test_binary_search("p", 3);
|
||||
fxt.Test_binary_search("u", 4);
|
||||
fxt.Test_binary_search("z", 5);
|
||||
fxt.Init__ary("", "e", "j", "o", "t", "y");
|
||||
fxt.Test__binary_search("a", 0);
|
||||
fxt.Test__binary_search("f", 1);
|
||||
fxt.Test__binary_search("k", 2);
|
||||
fxt.Test__binary_search("p", 3);
|
||||
fxt.Test__binary_search("u", 4);
|
||||
fxt.Test__binary_search("z", 5);
|
||||
}
|
||||
@Test public void One() {
|
||||
fxt.Init_ary("");
|
||||
fxt.Test_binary_search("a", 0);
|
||||
fxt.Init__ary("");
|
||||
fxt.Test__binary_search("a", 0);
|
||||
}
|
||||
@Test public void Catpage() {
|
||||
String[] ary = new String[25];
|
||||
for (int i = 0; i < 25; ++i)
|
||||
ary[i] = Int_.To_str_pad_bgn_zero(i, 2);
|
||||
fxt.Init__ary(ary);
|
||||
fxt.Test__binary_search("10", 10); // was 9
|
||||
}
|
||||
}
|
||||
class Binary_search__fxt {
|
||||
public void Init_ary(String... v) {
|
||||
private String_obj_val[] ary;
|
||||
public void Init__ary(String... v) {
|
||||
int ary_len = v.length;
|
||||
ary = new String_obj_val[ary_len];
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i] = String_obj_val.new_(v[i]);
|
||||
} private String_obj_val[] ary;
|
||||
public void Test_binary_search(String val, int expd) {
|
||||
int actl = Binary_search_.Search(ary, ary.length, String_obj_val.new_(val));
|
||||
}
|
||||
public void Test__binary_search(String val, int expd) {
|
||||
int actl = Binary_search_.Search(ary, String_obj_val.new_(val));
|
||||
Tfds.Eq(expd, actl, val);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.core.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
import gplx.core.lists.*;
|
||||
interface Binary_search_cmp {
|
||||
int Compare(Object comp);
|
||||
}
|
||||
class Binary_search_cmp__comparable implements Binary_search_cmp {
|
||||
private final CompareAble val;
|
||||
public Binary_search_cmp__comparable(CompareAble val) {this.val = val;}
|
||||
public int Compare(Object comp) {
|
||||
return val.compareTo((CompareAble)comp);
|
||||
}
|
||||
}
|
||||
class Binary_search_cmp__comparer implements Binary_search_cmp {
|
||||
private final Binary_comparer comparer; private final Object val;
|
||||
public Binary_search_cmp__comparer(Binary_comparer comparer, Object val) {this.comparer = comparer; this.val = val;}
|
||||
public int Compare(Object comp) {
|
||||
return comparer.Compare_val_to_obj(val, comp);
|
||||
}
|
||||
}
|
||||
@@ -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.lists.binary_searches; import gplx.*; import gplx.core.*; import gplx.core.lists.*;
|
||||
interface Binary_search_grp {
|
||||
int Len();
|
||||
Object Get_at(int i);
|
||||
}
|
||||
class Binary_search_grp__ary implements Binary_search_grp {
|
||||
private final Object[] ary;
|
||||
public Binary_search_grp__ary(Object[] ary) {this.ary = ary;}
|
||||
public int Len() {return ary.length;}
|
||||
public Object Get_at(int i) {return ary[i];}
|
||||
}
|
||||
class Binary_search_grp__list implements Binary_search_grp {
|
||||
private final List_adp list;
|
||||
public Binary_search_grp__list(List_adp list) {this.list = list;}
|
||||
public int Len() {return list.Len();}
|
||||
public Object Get_at(int i) {return list.Get_at(i);}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class Hash_adp__int {
|
||||
private final Int_obj_ref tmp_key = Int_obj_ref.New_neg1();
|
||||
public void Clear() {hash.Clear();}
|
||||
public int Len() {return hash.Count();}
|
||||
public Object Get_by(int key) {return hash.Get_by_or_fail(tmp_key.Val_(key));}
|
||||
public Object Get_by_or_fail(int key) {return hash.Get_by_or_fail(tmp_key.Val_(key));}
|
||||
public Object Get_by_or_null(int key) {return hash.Get_by(tmp_key.Val_(key));}
|
||||
public void Add(int key, Object obj) {hash.Add(Int_obj_ref.New(key), obj);}
|
||||
public void Add(Int_obj_ref key, Object obj) {hash.Add(key, obj);}
|
||||
|
||||
@@ -22,10 +22,13 @@ public abstract class Http_download_wkr__base implements Http_download_wkr {
|
||||
private Io_url tmp_url, checkpoint_url;
|
||||
private long downloaded;
|
||||
private long checkpoint_interval = 1024 * 1024, checkpoint_nxt = 0;
|
||||
protected Io_url Checkpoint_url() {return checkpoint_url;}
|
||||
protected Io_url Trg_url() {return trg_url;} private Io_url trg_url;
|
||||
public Io_url Tmp_url() {return tmp_url;}
|
||||
public String Fail_msg() {return fail_msg;} private String fail_msg;
|
||||
public abstract Http_download_wkr Make_new();
|
||||
public byte Exec(gplx.core.progs.Gfo_prog_ui prog_ui, String src_str, Io_url trg_url, long expd_size_val) {
|
||||
this.trg_url = trg_url;
|
||||
this.downloaded = this.Checkpoint__load_by_trg_fil(trg_url);
|
||||
this.checkpoint_nxt = downloaded + checkpoint_interval;
|
||||
this.expd_size = expd_size_val;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
|
||||
File trg_fil = new File(trg_url.Xto_api());
|
||||
FileOutputStream trg_stream = null;
|
||||
try {trg_stream = new FileOutputStream(trg_fil.getPath(), prog_resumed);} // pass true for append
|
||||
catch (FileNotFoundException e) {throw Err_.new_("download_file", "write failed; permission error?", "trg", trg_url, "err", e.toString());}
|
||||
catch (FileNotFoundException e) {throw Err_.new_wo_type("write failed; permission error?", "trg", trg_url, "err", e.toString());}
|
||||
|
||||
// open src stream
|
||||
InputStream src_stream = null;
|
||||
@@ -41,7 +41,7 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
|
||||
catch (MalformedURLException e) {
|
||||
try {if (trg_stream != null) trg_stream.close();}
|
||||
catch (IOException e1) {}
|
||||
throw Err_.new_("download_file", "bad url", "src", src_url, "err" + e.toString());
|
||||
throw Err_.new_wo_type("bad url", "src", src_url, "err" + e.toString());
|
||||
}
|
||||
HttpURLConnection src_conn = null;
|
||||
try {
|
||||
@@ -58,21 +58,25 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
|
||||
if (response_code != HttpURLConnection.HTTP_PARTIAL) {
|
||||
try {if (trg_stream != null) trg_stream.close();}
|
||||
catch (IOException e1) {}
|
||||
throw Err_.new_("download_file", "server returned non-partial response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
|
||||
if (response_code == 416 && prog_data_cur > 0) { // 416=Requested Range not satisfiable; if resuming at position > max_len, assume critical failure; delete files to start over from scratch; DATE:2016-09-24
|
||||
Io_mgr.Instance.DeleteFil(this.Trg_url());
|
||||
Io_mgr.Instance.DeleteFil(this.Checkpoint_url());
|
||||
}
|
||||
throw Err_.new_wo_type("server returned non-partial response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (response_code != HttpURLConnection.HTTP_OK) {
|
||||
try {if (trg_stream != null) trg_stream.close();}
|
||||
catch (IOException e1) {}
|
||||
throw Err_.new_("download_file", "server returned non-OK response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
|
||||
throw Err_.new_wo_type("server returned non-OK response code", "src", src_url, "code", src_conn.getResponseCode(), "msg", src_conn.getResponseMessage());
|
||||
}
|
||||
}
|
||||
src_stream = src_conn.getInputStream();
|
||||
} catch (Exception e) {
|
||||
try {if (trg_stream != null) trg_stream.close();}
|
||||
catch (IOException e1) {}
|
||||
throw Err_.new_("download_file", "src connection failed", "src", src_url, "err",e.toString());
|
||||
throw Err_.new_wo_type(Err__server_connection_failed, "src", src_url, "err", e.toString());
|
||||
}
|
||||
|
||||
// do downloading
|
||||
@@ -89,7 +93,7 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
|
||||
if (prog_ui.Prog_notify_and_chk_if_suspended(prog_data_cur, prog_data_end)) return Gfo_prog_ui_.Status__suspended;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw Err_.new_("download_file", "downloading failed", "src", src_url, "trg_url", trg_url, "err", e.toString());
|
||||
throw Err_.new_wo_type(Err__server_download_failed, "src", src_url, "trg_url", trg_url, "err", e.toString());
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
@@ -100,4 +104,8 @@ public class Http_download_wkr__jre extends Http_download_wkr__base {
|
||||
}
|
||||
return Gfo_prog_ui_.Status__done;
|
||||
}
|
||||
}
|
||||
public static final String
|
||||
Err__server_connection_failed = "server connection failed"
|
||||
, Err__server_download_failed = "server download failed"
|
||||
;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user