mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.7.2.1
This commit is contained in:
61
400_xowa/src_161_meta/gplx/xowa/Xof_meta_fil.java
Normal file
61
400_xowa/src_161_meta/gplx/xowa/Xof_meta_fil.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.core.flds.*;
|
||||
public class Xof_meta_fil {
|
||||
private final Ordered_hash itms = Ordered_hash_.new_bry_();
|
||||
public Xof_meta_fil(Xof_meta_mgr meta_mgr, byte[] md5) {this.meta_mgr = meta_mgr; this.md5 = md5;}
|
||||
public Xof_meta_mgr Owner_mgr() {return meta_mgr;} private final Xof_meta_mgr meta_mgr;
|
||||
public byte[] Md5() {return md5;} private final byte[] md5;
|
||||
public void Dirty_() {meta_mgr.Dirty_(this);}
|
||||
public Xof_meta_itm Get_or_new(byte[] ttl) {
|
||||
Xof_meta_itm rv = Get_or_null(ttl);
|
||||
if (rv == null) {
|
||||
rv = new Xof_meta_itm(this, ttl);
|
||||
itms.Add(ttl, rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Xof_meta_itm Get_or_null(byte[] ttl) {return (Xof_meta_itm)itms.Get_by(ttl);}
|
||||
public void Save(Gfo_fld_wtr wtr) {
|
||||
int itms_len = itms.Count();
|
||||
for (int i = 0; i < itms_len; i++) {
|
||||
Xof_meta_itm itm = (Xof_meta_itm)itms.Get_at(i);
|
||||
itm.Save(wtr);
|
||||
}
|
||||
}
|
||||
public Xof_meta_fil Load(Gfo_fld_rdr rdr, Xof_meta_thumb_parser parser) {
|
||||
itms.Clear();
|
||||
int bry_len = rdr.Data().length;
|
||||
while (rdr.Pos() < bry_len) {
|
||||
Xof_meta_itm itm = new Xof_meta_itm(this, Bry_.Empty);
|
||||
itm.Load(rdr, parser);
|
||||
itms.Add(itm.Ttl(), itm);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public static Io_url Bld_url(Io_url root, byte[] md5, int depth) {
|
||||
Bld_url_bfr.Add(root.RawBry());
|
||||
for (int i = 0; i < depth - 1; i++)
|
||||
Bld_url_bfr.Add_byte(md5[i]).Add_byte(root.Info().DirSpr_byte());
|
||||
for (int i = 0; i < depth; i++)
|
||||
Bld_url_bfr.Add_byte(md5[i]);
|
||||
Bld_url_bfr.Add(Bry_url_ext);
|
||||
return Io_url_.new_fil_(Bld_url_bfr.Xto_str_and_clear());
|
||||
} static final byte[] Bry_url_ext = Bry_.new_a7(".csv"); static Bry_bfr Bld_url_bfr = Bry_bfr.new_(260); // 260 is max path of url
|
||||
}
|
||||
29
400_xowa/src_161_meta/gplx/xowa/Xof_meta_fil_tst.java
Normal file
29
400_xowa/src_161_meta/gplx/xowa/Xof_meta_fil_tst.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*; import gplx.xowa.files.*;
|
||||
public class Xof_meta_fil_tst {
|
||||
Xof_meta_fil_fxt fxt = new Xof_meta_fil_fxt();
|
||||
@Before public void init() {fxt.Ini();}
|
||||
@Test public void Bld_url() {fxt.Bld_url("mem/root/", "abcdef", 3, "mem/root/a/b/abc.csv");}
|
||||
}
|
||||
class Xof_meta_fil_fxt {
|
||||
byte[] md5_(byte[] name) {return Xof_file_wkr_.Md5_(name);}
|
||||
public void Ini() {}
|
||||
public void Bld_url(String root, String md5, int depth, String expd) {Tfds.Eq(expd, Xof_meta_fil.Bld_url(Io_url_.new_dir_(root), Bry_.new_a7(md5), depth).Raw());}
|
||||
}
|
||||
183
400_xowa/src_161_meta/gplx/xowa/Xof_meta_itm.java
Normal file
183
400_xowa/src_161_meta/gplx/xowa/Xof_meta_itm.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
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.xowa; import gplx.*;
|
||||
import gplx.core.flds.*;
|
||||
import gplx.xowa.files.*; import gplx.xowa.files.repos.*;
|
||||
public class Xof_meta_itm {
|
||||
public Xof_meta_itm(Xof_meta_fil owner_fil, byte[] ttl) {this.owner_fil = owner_fil; this.ttl = ttl;}
|
||||
public Xof_meta_fil Owner_fil() {return owner_fil;} private Xof_meta_fil owner_fil;
|
||||
public byte[] Ttl() {return ttl;} private byte[] ttl;
|
||||
public byte[] Ptr_ttl() {return ptr_ttl;} public Xof_meta_itm Ptr_ttl_(byte[] v) {this.ptr_ttl = v; return this;} private byte[] ptr_ttl = Xop_redirect_mgr.Redirect_null_bry;
|
||||
public boolean Ptr_ttl_exists() {return ptr_ttl != Xop_redirect_mgr.Redirect_null_bry;}
|
||||
public boolean State_new() {return state_new;} private boolean state_new = true;
|
||||
public int Vrtl_repo() {return vrtl_repo;} private int vrtl_repo = Repo_unknown;
|
||||
public void Vrtl_repo_(int v) {
|
||||
// if (vrtl_repo == Xof_meta_itm.Repo_unknown) { // NOTE: only update vrtl_repo when unknown; this assumes that orig and all thumbs sit in same repo (which they should)
|
||||
vrtl_repo = v;
|
||||
Dirty();
|
||||
// }
|
||||
}
|
||||
public Xof_repo_itm Repo_itm(Xowe_wiki wiki) {
|
||||
switch (vrtl_repo) {
|
||||
case Xof_meta_itm.Repo_missing : //return null; // DELETE: used to return null, but this caused Redownload_missing to fail; no reason why missing shouldn't return a default repo; DATE:2013-01-26
|
||||
case Xof_meta_itm.Repo_unknown :
|
||||
case Xof_meta_itm.Repo_same : return wiki.Appe().File_mgr().Repo_mgr().Get_by_primary(wiki.Domain_bry());
|
||||
default : return wiki.File_mgr().Repo_mgr().Repos_get_at(vrtl_repo).Trg();
|
||||
}
|
||||
}
|
||||
public int Orig_w() {return orig_w;} private int orig_w;
|
||||
public int Orig_h() {return orig_h;} private int orig_h;
|
||||
public byte Orig_exists() {return orig_exists;} private byte orig_exists = Exists_unknown;
|
||||
public void Orig_exists_(byte v) {if (this.orig_exists == v) return; this.orig_exists = v; Dirty();}
|
||||
public Xof_meta_thumb[] Thumbs() {return thumbs;} private Xof_meta_thumb[] thumbs = Xof_meta_thumb.Ary_empty;
|
||||
public boolean Thumbs_indicates_oga() {return Thumbs_get_by_w(0, 0, Xof_lnki_time.Null_as_int) != null;} // if 0,0 exists, then assume no thumbs; needed for oga/ogg
|
||||
public boolean Thumbs_del(int w) {
|
||||
int del_idx = -1;
|
||||
int thumbs_len = thumbs.length;
|
||||
for (int i = 0; i < thumbs_len; i++) {
|
||||
Xof_meta_thumb thumb = thumbs[i];
|
||||
if (thumb.Width() == w) {del_idx = i; break;}
|
||||
}
|
||||
if (del_idx == -1) return false;
|
||||
Xof_meta_thumb[] thumbs_new = new Xof_meta_thumb[thumbs_len - 1];
|
||||
int new_idx = 0;
|
||||
for (int i = 0; i < thumbs_len; i++) {
|
||||
Xof_meta_thumb thumb = thumbs[i];
|
||||
if (thumb.Width() == w) continue;
|
||||
thumbs_new[new_idx++] = thumbs[i];
|
||||
}
|
||||
thumbs = thumbs_new;
|
||||
return true;
|
||||
}
|
||||
public Xof_meta_thumb Thumbs_get_img(int w, int w_adj) {return Thumbs_get_by_w(w, w_adj, Xof_lnki_time.Null_as_int);}
|
||||
public Xof_meta_thumb Thumbs_get_vid(int s) {return Thumbs_get_by_w(Xop_lnki_tkn.Width_null, 0, s);}
|
||||
Xof_meta_thumb Thumbs_get_by_w(int w, int w_adj, int seek) {
|
||||
int thumbs_len = thumbs.length;
|
||||
for (int i = 0; i < thumbs_len; i++) {
|
||||
Xof_meta_thumb thumb = thumbs[i];
|
||||
int tmp_adj = w_adj;// thumb.Width() < 50 ? 0 : w_adj;
|
||||
if ( (Xof_lnki_time.Null_y(seek)
|
||||
&& Int_.Between(thumb.Width(), w - tmp_adj, w + tmp_adj))
|
||||
|| (w == Xop_lnki_tkn.Width_null
|
||||
&& (Xof_lnki_time.Null_y(seek) || Int_.In(seek, thumb.Seeks()))))
|
||||
return thumb;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Xof_meta_thumb Thumbs_get_by_h(int h, int thumbs_len) {
|
||||
for (int i = 0; i < thumbs_len; i++) {
|
||||
Xof_meta_thumb thumb = thumbs[i];
|
||||
int tmp_adj = 1;//thumb.Height() < 50 ? 0 : 1;
|
||||
if (Int_.Between(thumb.Height(), h - tmp_adj, h + tmp_adj)) return thumb;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Xof_meta_thumb Thumbs_get_largest(int thumbs_len) {
|
||||
if (thumbs_len == 0) return null;
|
||||
int rv_idx = -1, cur_largest = -1;
|
||||
for (int i = 0; i < thumbs_len; i++) {
|
||||
Xof_meta_thumb thumb = thumbs[i];
|
||||
if (thumb.Width() > cur_largest) {
|
||||
rv_idx = i;
|
||||
cur_largest = thumb.Width();
|
||||
}
|
||||
}
|
||||
return thumbs[rv_idx];
|
||||
}
|
||||
public void Update_all(byte[] ptr_ttl, int w, int h, byte orig_exists, Xof_meta_thumb[] thumbs) {
|
||||
this.ptr_ttl = ptr_ttl; orig_w = w; orig_h = h; this.orig_exists = orig_exists; this.thumbs = thumbs; Dirty();
|
||||
}
|
||||
public void Update_orig_size(int w, int h) {this.orig_w = w; this.orig_h = h; Dirty();}
|
||||
public Xof_meta_itm Update_thumb_oga_() {
|
||||
Update_thumb_add(0, 0).Exists_n_();
|
||||
return this;
|
||||
}
|
||||
public Xof_meta_thumb Update_thumb_add(int w, int h) { // WARNING: h may not match existing val; will be discarded; EX: 10,20 stored in file; 10,21 passed in; 21 effectively discarded
|
||||
Xof_meta_thumb thumb = Thumbs_get_img(w, 0);
|
||||
if (thumb == null) {
|
||||
int thumbs_len = thumbs.length;
|
||||
Xof_meta_thumb[] thumbs_new = new Xof_meta_thumb[thumbs_len + 1];
|
||||
for (int i = 0; i < thumbs_len; i++)
|
||||
thumbs_new[i] = thumbs[i];
|
||||
thumb = new Xof_meta_thumb().Width_(w).Height_(h).Exists_y_().State_new_();
|
||||
thumbs_new[thumbs_len] = thumb;
|
||||
thumbs = thumbs_new;
|
||||
Dirty();
|
||||
}
|
||||
return thumb;
|
||||
}
|
||||
private void Dirty() {if (owner_fil != null) owner_fil.Dirty_();}
|
||||
public void Save(Gfo_fld_wtr wtr) {
|
||||
wtr.Write_bry_escape_fld(ttl);
|
||||
byte vrtl_repo_byte = Byte_.Max_value_127;
|
||||
switch (vrtl_repo) {
|
||||
case Repo_unknown: vrtl_repo_byte = Byte_ascii.Ltr_z; break;
|
||||
case Repo_same: vrtl_repo_byte = Byte_ascii.Ltr_y; break;
|
||||
case Repo_missing: vrtl_repo_byte = Byte_ascii.Ltr_x; break;
|
||||
default: vrtl_repo_byte = (byte)(vrtl_repo + Byte_ascii.Num_0); break;
|
||||
}
|
||||
wtr.Write_byte_fld(vrtl_repo_byte);
|
||||
wtr.Write_bry_escape_fld(ptr_ttl);
|
||||
wtr.Bfr() .Add_int_fixed(orig_exists, 1) .Add_byte(Xof_meta_thumb_parser.Dlm_exists)
|
||||
.Add_int_variable(orig_w) .Add_byte(Xof_meta_thumb_parser.Dlm_width)
|
||||
.Add_int_variable(orig_h) .Add_byte_pipe();
|
||||
int thumbs_len = thumbs.length;
|
||||
Bry_bfr bfr = wtr.Bfr();
|
||||
for (int i = 0; i < thumbs_len; i++) {
|
||||
if (i != 0) bfr.Add_byte(Byte_ascii.Semic);
|
||||
Xof_meta_thumb thumb = thumbs[i];
|
||||
thumb.Save(bfr);
|
||||
}
|
||||
wtr.Write_dlm_row();
|
||||
state_new = false;
|
||||
}
|
||||
public void Load_orig_(int w, int h) {this.orig_w = w; this.orig_h = h;}
|
||||
public void Load(Gfo_fld_rdr rdr, Xof_meta_thumb_parser parser) {
|
||||
ttl = rdr.Read_bry_escape();
|
||||
byte vrtl_repo_byte = rdr.Read_byte();
|
||||
switch (vrtl_repo_byte) {
|
||||
case Byte_ascii.Ltr_z: vrtl_repo = Repo_unknown; break;
|
||||
case Byte_ascii.Ltr_y: vrtl_repo = Repo_same; break;
|
||||
case Byte_ascii.Ltr_x: vrtl_repo = Repo_missing; break;
|
||||
default: vrtl_repo = (byte)(vrtl_repo_byte - Byte_ascii.Num_0); break;
|
||||
}
|
||||
ptr_ttl = rdr.Read_bry_escape();
|
||||
rdr.Move_next_simple_fld();
|
||||
Xof_meta_thumb orig_itm = parser.Parse_one(rdr.Data(), rdr.Fld_bgn(), rdr.Fld_end());
|
||||
orig_exists = orig_itm.Exists();
|
||||
orig_w = orig_itm.Width();
|
||||
orig_h = orig_itm.Height();
|
||||
rdr.Move_next_simple_fld();
|
||||
parser.Parse_ary(rdr.Data(), rdr.Fld_bgn(), rdr.Fld_end());
|
||||
int thumbs_len = parser.Len();
|
||||
thumbs = new Xof_meta_thumb[thumbs_len];
|
||||
for (int i = 0; i < thumbs_len; i++)
|
||||
thumbs[i] = parser.Ary()[i];
|
||||
parser.Clear();
|
||||
state_new = false;
|
||||
}
|
||||
public static final byte Exists_n = 0, Exists_y = 1, Exists_unknown = 2;
|
||||
public static final byte Repo_unknown = (byte)127, Repo_same = (byte)126, Repo_missing = (byte)125;
|
||||
public static final byte
|
||||
Tid_main = 0
|
||||
, Tid_ptr = 1
|
||||
, Tid_vrtl = 2
|
||||
, Tid_null = Byte_.Max_value_127
|
||||
;
|
||||
public static final byte[] Ptr_ttl_null = Bry_.Empty;
|
||||
}
|
||||
118
400_xowa/src_161_meta/gplx/xowa/Xof_meta_mgr.java
Normal file
118
400_xowa/src_161_meta/gplx/xowa/Xof_meta_mgr.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
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.xowa; import gplx.*;
|
||||
import gplx.core.flds.*;
|
||||
public class Xof_meta_mgr implements GfoInvkAble {
|
||||
private Object[] root = new Object[16]; private final Ordered_hash dirty_fils = Ordered_hash_.new_bry_();
|
||||
private final Gfo_fld_rdr rdr = Gfo_fld_rdr.xowa_(); private final Xof_meta_thumb_parser parser = new Xof_meta_thumb_parser();
|
||||
public Xof_meta_mgr(Xowe_wiki wiki) {this.wiki = wiki; this.root_dir = wiki.Appe().Fsys_mgr().File_dir().GenSubDir_nest("#meta", wiki.Domain_str());}
|
||||
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
|
||||
public Io_url Root_dir() {return root_dir;} Io_url root_dir;
|
||||
public int Depth() {return depth;} public Xof_meta_mgr Depth_(int v) {depth = v; return this;} private int depth = 3; // allows a full english wikipedia to have meta files of approximately 32 kb; otherwise would be 480 kb; most wikis will not get to this size, but worst case is wasting 16 kb in (16 * 16) files which is less than 4 mb
|
||||
public boolean Append_only() {return append_only;} public Xof_meta_mgr Append_only_(boolean v) {append_only = v; return this;} private boolean append_only;
|
||||
public Xof_meta_fil Get_fil_or_new(byte[] md5) {
|
||||
Xof_meta_fil rv = Get_fil_or_null(md5);
|
||||
if (rv == null) {
|
||||
if (!append_only)
|
||||
rv = Load(md5);
|
||||
if (rv == null) {
|
||||
rv = Bld_new(root, depth - 1, this, md5, 0);
|
||||
dirty_fils.Add(md5, rv);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Xof_meta_itm Get_itm_or_new(byte[] ttl) {return Get_itm_or_new(ttl, gplx.xowa.files.Xof_file_wkr_.Md5_(ttl));}
|
||||
public Xof_meta_itm Get_itm_or_new(byte[] ttl, byte[] md5) {
|
||||
Xof_meta_fil fil = this.Get_fil_or_new(md5);
|
||||
return fil.Get_or_new(ttl);
|
||||
}
|
||||
Xof_meta_fil Get_fil_or_null(byte[] md5) {return Get_fil_or_null_recur(root, depth - 1, md5, 0);}
|
||||
public void Dirty_(Xof_meta_fil fil) {
|
||||
byte[] md5 = fil.Md5();
|
||||
if (!dirty_fils.Has(md5)) dirty_fils.Add(md5, fil);
|
||||
}
|
||||
public void Clear() {root = new Object[16]; dirty_fils.Clear();}
|
||||
public void Save() {Save(false);}
|
||||
public void Save(boolean clear) {
|
||||
int dirty_len = dirty_fils.Count();
|
||||
Bry_bfr tmp_bfr = Bry_bfr.new_();
|
||||
wtr.Bfr_(tmp_bfr);
|
||||
for (int i = 0; i < dirty_len; i++) {
|
||||
Xof_meta_fil fil = (Xof_meta_fil)dirty_fils.Get_at(i);
|
||||
Io_url fil_url = Xof_meta_fil.Bld_url(root_dir, fil.Md5(), depth);
|
||||
fil.Save(wtr);
|
||||
if (append_only)
|
||||
Io_mgr.I.AppendFilBfr(fil_url, tmp_bfr);
|
||||
else
|
||||
Io_mgr.I.SaveFilBfr(fil_url, tmp_bfr);
|
||||
}
|
||||
dirty_fils.Clear();
|
||||
if (clear) this.Clear();
|
||||
} Gfo_fld_wtr wtr = Gfo_fld_wtr.xowa_();
|
||||
Xof_meta_fil Load(byte[] md5) {
|
||||
Io_url fil_url = Xof_meta_fil.Bld_url(root_dir, md5, depth);
|
||||
byte[] bry = Io_mgr.I.LoadFilBry(fil_url); if (bry == Bry_.Empty) return null;
|
||||
rdr.Ini(bry, 0);
|
||||
Xof_meta_fil rv = Bld_new(root, depth - 1, this, md5, 0); // NOTE: need to register file before loading it; defect wherein 2 files with same hash prefix would skip one b/c Loaded file was not registered; EX.WS: en.wikiquote.org/The Hitchhiker's Guide to the Galaxy; NMMP_dolphin_with_locator.jpeg, da6f95736ed249f371f30bf5f1205fbd; Hoags_object.jpg, daed4a54e48e4266bd2f2763b7c4018c
|
||||
rv.Load(rdr, parser);
|
||||
return rv;
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_regy_depth_)) depth = m.ReadInt("v");
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_regy_depth_ = "depth_";
|
||||
static final String GRP_KEY = "xowa.file_regy.";
|
||||
private static Xof_meta_fil Get_fil_or_null_recur(Object[] ary, int depth_max, byte[] md5, int md5_idx) {
|
||||
int ary_idx = Int_.Xto_int_hex(md5[md5_idx]);
|
||||
if (ary_idx < 0 || ary_idx > 15) throw Exc_.new_("md5_not_valid", "md5", String_.new_u8(md5), "idx", md5_idx);
|
||||
Object o = ary[ary_idx];
|
||||
if (o == null) return null;
|
||||
if (md5_idx == depth_max) { // leaf; return fil
|
||||
try {return (Xof_meta_fil)o;} catch (Exception exc) {throw Exc_.new_cast(exc, Xof_meta_fil.class, o);}
|
||||
}
|
||||
Object[] nxt = null; try {nxt = (Object[])o;} catch(Exception exc) {throw Exc_.new_cast(exc, Object[].class, o);}
|
||||
return Get_fil_or_null_recur(nxt, depth_max, md5, md5_idx + 1);
|
||||
}
|
||||
private static Xof_meta_fil Bld_new(Object[] ary, int depth_max, Xof_meta_mgr regy_mgr, byte[] md5, int md5_idx) {
|
||||
int ary_idx = Int_.Xto_int_hex(md5[md5_idx]);
|
||||
if (ary_idx < 0 || ary_idx > 15) throw Exc_.new_("md5_not_valid", "md", String_.new_u8(md5), "idx", md5_idx);
|
||||
Object o = ary[ary_idx];
|
||||
if (md5_idx == depth_max) { // leaf; create itm
|
||||
Xof_meta_fil rv = null;
|
||||
if (o == null) {
|
||||
rv = new Xof_meta_fil(regy_mgr, md5);
|
||||
ary[ary_idx] = rv;
|
||||
}
|
||||
else
|
||||
rv = (Xof_meta_fil)o;
|
||||
return rv;
|
||||
}
|
||||
else {
|
||||
Object[] nxt = null;
|
||||
if (o == null) {
|
||||
nxt = new Object[16];
|
||||
ary[ary_idx] = nxt;
|
||||
}
|
||||
else
|
||||
nxt = (Object[])o;
|
||||
return Bld_new(nxt, depth_max, regy_mgr, md5, md5_idx + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
400_xowa/src_161_meta/gplx/xowa/Xof_meta_mgr_tst.java
Normal file
94
400_xowa/src_161_meta/gplx/xowa/Xof_meta_mgr_tst.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.gfui.*; import gplx.xowa.files.*;
|
||||
public class Xof_meta_mgr_tst {
|
||||
Xof_file_regy_fxt fxt = new Xof_file_regy_fxt();
|
||||
@Before public void init() {fxt.Ini();}
|
||||
@Test public void Set_one() {
|
||||
fxt .Set("A.png", 440, 400, true, "440,400", "220,200")
|
||||
.tst_Save("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv", "A.png|y||1?440,400|1?440,400;1?220,200");
|
||||
}
|
||||
@Test public void Set_many() {
|
||||
fxt .Set("A.png" , 440, 400, true, "440,400", "220,200")
|
||||
.Set("Cabbage.jpg" , 640, 456, false, "220,200", "200,180")
|
||||
.tst_Save("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv"
|
||||
, "A.png|y||1?440,400|1?440,400;1?220,200"
|
||||
, "Cabbage.jpg|y||2?640,456|1?220,200;1?200,180"
|
||||
);
|
||||
}
|
||||
@Test public void Load_and_add() {
|
||||
fxt.Save_fil("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv"
|
||||
, "A.png|y||1?440,400|"
|
||||
, "Cabbage.jpg|y||2?640,456|1?440,220;1?220,200"
|
||||
)
|
||||
.Set("Wooden_hourglass_3.jpg", 967, 1959, false, "220,200")
|
||||
.tst_Save("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv"
|
||||
, "A.png|y||1?440,400|"
|
||||
, "Cabbage.jpg|y||2?640,456|1?440,220;1?220,200"
|
||||
, "Wooden_hourglass_3.jpg|y||2?967,1959|1?220,200"
|
||||
);
|
||||
}
|
||||
@Test public void Load_and_update() {
|
||||
fxt.Save_fil("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv"
|
||||
, "A.png|y||0?440,400|"
|
||||
, "Cabbage.jpg|y||2?640,456|1?440,400;1?220,200"
|
||||
)
|
||||
.Set("A.png", 550, 500, false, "220,200")
|
||||
.tst_Save("mem/xowa/file/#meta/en.wikipedia.org/7/70.csv"
|
||||
, "A.png|y||2?550,500|1?220,200"
|
||||
, "Cabbage.jpg|y||2?640,456|1?440,400;1?220,200"
|
||||
);
|
||||
}
|
||||
}
|
||||
class Xof_file_regy_fxt {
|
||||
Xof_meta_mgr regy_mgr;
|
||||
byte[] md5_(byte[] name) {return Xof_file_wkr_.Md5_(name);}
|
||||
public void Ini() {
|
||||
Io_mgr.I.InitEngine_mem();
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_tst_(app);
|
||||
regy_mgr = new Xof_meta_mgr(wiki);
|
||||
regy_mgr.Clear();
|
||||
regy_mgr.Depth_(2);
|
||||
}
|
||||
public Xof_file_regy_fxt Save_fil(String url, String... data) {Io_mgr.I.SaveFilStr(Io_url_.mem_fil_(url), String_.Concat_lines_nl(data)); return this;}
|
||||
public Xof_file_regy_fxt Set(String name_str, int w, int h, boolean orig_exists, String... thumbs) {
|
||||
byte[] name = Bry_.new_u8(name_str);
|
||||
byte[] md5 = md5_(name);
|
||||
Xof_meta_itm itm = regy_mgr.Get_itm_or_new(name, md5);
|
||||
itm.Vrtl_repo_(Xof_meta_itm.Repo_same); // all tests above assume this is main
|
||||
itm.Update_all(Bry_.Empty, w, h, orig_exists ? Xof_meta_itm.Exists_y : Xof_meta_itm.Exists_unknown, To_ary(thumbs));
|
||||
return this;
|
||||
}
|
||||
Xof_meta_thumb[] To_ary(String[] ary) {
|
||||
int len = ary.length;
|
||||
Xof_meta_thumb[] rv = new Xof_meta_thumb[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
int[] size = Int_ary_parser._.Parse_ary(ary[i], Byte_ascii.Comma);
|
||||
rv[i] = new Xof_meta_thumb().Width_(size[0]).Height_(size[1]).Exists_y_();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Xof_file_regy_fxt tst_Save(String url_str, String... expd_ary) {
|
||||
regy_mgr.Save();
|
||||
Tfds.Eq_ary_str(expd_ary, Io_mgr.I.LoadFilStr_args(Io_url_.new_fil_(url_str)).ExecAsStrAryLnx());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
51
400_xowa/src_161_meta/gplx/xowa/Xof_meta_thumb.java
Normal file
51
400_xowa/src_161_meta/gplx/xowa/Xof_meta_thumb.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
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.xowa; import gplx.*;
|
||||
public class Xof_meta_thumb {
|
||||
public Xof_meta_thumb() {}
|
||||
public Xof_meta_thumb(byte exists, int width, int height, int[] seeks) {this.exists = exists; this.width = width; this.height = height; this.seeks = seeks; if (seeks == null) seeks = Int_.Ary_empty;}
|
||||
public byte Exists() {return exists;} private byte exists = Xof_meta_itm.Exists_unknown; // default to y, b/c thumbs are usually added if they exist; handle n when it occurs; unknown should never happen;
|
||||
public boolean State_new() {return state_new;} public Xof_meta_thumb State_new_() {state_new = true; return this;} private boolean state_new;
|
||||
public Xof_meta_thumb Exists_(byte v) {exists = v; return this;}
|
||||
public Xof_meta_thumb Exists_y_() {exists = Xof_meta_itm.Exists_y; return this;}
|
||||
public Xof_meta_thumb Exists_n_() {exists = Xof_meta_itm.Exists_n; return this;}
|
||||
public int Width() {return width;} public Xof_meta_thumb Width_(int v) {width = v; return this;} private int width;
|
||||
public int Height() {return height;} public Xof_meta_thumb Height_(int v) {height = v; return this;} private int height;
|
||||
public int[] Seeks() {return seeks;} public Xof_meta_thumb Seeks_(int[] v) {seeks = v; return this;} private int[] seeks = Int_.Ary_empty;
|
||||
public Xof_meta_thumb Seeks_add(int v) {
|
||||
int seeks_len = seeks.length;
|
||||
seeks = (int[])Array_.Resize(seeks, seeks_len + 1);
|
||||
seeks[seeks_len] = v;
|
||||
return this;
|
||||
}
|
||||
public void Save(Bry_bfr bfr) {
|
||||
bfr .Add_int_fixed(exists, 1) .Add_byte(Xof_meta_thumb_parser.Dlm_exists)
|
||||
.Add_int_variable(width) .Add_byte(Xof_meta_thumb_parser.Dlm_width)
|
||||
.Add_int_variable(height);
|
||||
if (seeks != Int_.Ary_empty) {
|
||||
bfr.Add_byte(Xof_meta_thumb_parser.Dlm_seek);
|
||||
int seeks_len = seeks.length;
|
||||
for (int i = 0; i < seeks_len; i++) {
|
||||
if (i != 0) bfr.Add_byte(Xof_meta_thumb_parser.Dlm_width);
|
||||
bfr.Add_int_variable(seeks[i]);
|
||||
}
|
||||
}
|
||||
state_new = false;
|
||||
}
|
||||
public static final Xof_meta_thumb[] Ary_empty = new Xof_meta_thumb[0];
|
||||
}
|
||||
72
400_xowa/src_161_meta/gplx/xowa/Xof_meta_thumb_parser.java
Normal file
72
400_xowa/src_161_meta/gplx/xowa/Xof_meta_thumb_parser.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xof_meta_thumb_parser extends Obj_ary_parser_base {
|
||||
Number_parser num_parser = new Number_parser();
|
||||
Int_ary_parser int_ary_parser = new Int_ary_parser();
|
||||
public Xof_meta_thumb[] Ary() {return ary;} private Xof_meta_thumb[] ary = new Xof_meta_thumb[Ary_max]; static final int Ary_max = 16;
|
||||
public int Len() {return ary_idx;} private int ary_idx;
|
||||
public void Parse_ary(byte[] bry, int bgn, int end) {super.Parse_core(bry, bgn, end, Byte_ascii.Semic, Byte_ascii.Nil);}
|
||||
public Xof_meta_thumb Parse_one(byte[] bry, int bgn, int end) {
|
||||
super.Parse_core(bry, bgn, end, Byte_ascii.Semic, Byte_ascii.Nil);
|
||||
return ary[0];
|
||||
}
|
||||
public void Clear() {if (ary.length > Ary_max) ary = new Xof_meta_thumb[Ary_max];}
|
||||
@Override protected void Ary_len_(int v) {
|
||||
ary_idx = 0;
|
||||
if (v > Ary_max) ary = new Xof_meta_thumb[v];
|
||||
}
|
||||
@Override protected void Parse_itm(byte[] bry, int bgn, int end) { // EX: "1:45,40"; "1:45,40:3,4"
|
||||
Xof_meta_thumb itm = new Xof_meta_thumb(); boolean height_found = false;
|
||||
if (end - 2 < bgn) throw Exc_.new_("itm must be at least 2 bytes long", "itm", String_.new_u8(bry, bgn, end)); // EX: 4,6
|
||||
int pos = bgn;
|
||||
byte exists_byte = bry[pos];
|
||||
switch (exists_byte) {
|
||||
case Byte_ascii.Num_0: itm.Exists_(Xof_meta_itm.Exists_n); break;
|
||||
case Byte_ascii.Num_1: itm.Exists_(Xof_meta_itm.Exists_y); break;
|
||||
case Byte_ascii.Num_2: itm.Exists_(Xof_meta_itm.Exists_unknown); break;
|
||||
default: throw Exc_.new_("exists must be 0,1,2", "exists", exists_byte, "itm", String_.new_u8(bry, bgn, end));
|
||||
}
|
||||
if (bry[pos + 1] != Dlm_exists) throw Exc_.new_("question must follow exists", "bad_char", bry[pos + 1], "itm", String_.new_u8(bry, bgn, end));
|
||||
pos += 2;
|
||||
int num_bgn = pos;
|
||||
while (pos < end) {
|
||||
byte b = bry[pos];
|
||||
switch (b) {
|
||||
case Dlm_width: // "," found; assume width; note that seek commas will be handled by seek
|
||||
itm.Width_(num_parser.Parse(bry, num_bgn, pos).Rv_as_int());
|
||||
num_bgn = pos + Int_.Const_dlm_len;
|
||||
break;
|
||||
case Dlm_seek:
|
||||
itm.Height_(num_parser.Parse(bry, num_bgn, pos).Rv_as_int());
|
||||
num_bgn = pos + Int_.Const_dlm_len;
|
||||
height_found = true;
|
||||
itm.Seeks_(int_ary_parser.Parse_ary(bry, num_bgn, end, Byte_ascii.Comma));
|
||||
pos = end;
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
if (!height_found) // handle '1:2,3' as opposed to '1:2,3@4'
|
||||
itm.Height_(num_parser.Parse(bry, num_bgn, end).Rv_as_int());
|
||||
ary[ary_idx++] = itm;
|
||||
}
|
||||
static final String GRP_KEY = "xowa.meta.itm.file";
|
||||
public static final byte Dlm_exists = Byte_ascii.Question, Dlm_seek = Byte_ascii.At, Dlm_width = Byte_ascii.Comma;
|
||||
public static final String Dlm_seek_str = "@";
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*; import gplx.core.strings.*;
|
||||
public class Xof_meta_thumb_parser_tst {
|
||||
Xof_meta_thumb_parser parser = new Xof_meta_thumb_parser();
|
||||
@Test public void Exists_y() {Tst_parse("1?45,40", itm_y_(45, 40));}
|
||||
@Test public void Exists_n() {Tst_parse("0?45,40", itm_n_(45, 40));}
|
||||
@Test public void Many() {Tst_parse("1?45,40;0?90,80", itm_y_(45, 40), itm_n_(90, 80));}
|
||||
@Test public void Seek() {Tst_parse("1?45,40@2,3,4", itm_y_(45, 40, 2, 3, 4));}
|
||||
private void Tst_parse(String raw_str, Xof_meta_thumb... expd) {
|
||||
byte[] raw = Bry_.new_a7(raw_str);
|
||||
parser.Parse_ary(raw, 0, raw.length);
|
||||
Tfds.Eq_str_lines(Xto_str(expd, 0, expd.length), Xto_str(parser.Ary(), 0, parser.Len()));
|
||||
}
|
||||
String Xto_str(Xof_meta_thumb[] ary, int bgn, int end) {
|
||||
for (int i = bgn; i < end; i++) {
|
||||
Xof_meta_thumb itm = ary[i];
|
||||
sb .Add(itm.Exists()).Add(":")
|
||||
.Add(itm.Width()).Add(",")
|
||||
.Add(itm.Height());
|
||||
int seeks_len = itm.Seeks().length;
|
||||
for (int j = 0; j < seeks_len; j++) {
|
||||
int seek = itm.Seeks()[j];
|
||||
sb.Add(i == 0 ? "@" : ",");
|
||||
sb.Add(seek);
|
||||
}
|
||||
sb.Add_char_nl();
|
||||
}
|
||||
return sb.Xto_str_and_clear();
|
||||
} String_bldr sb = String_bldr_.new_();
|
||||
// Xof_meta_img_chkr img_(int w, int h, params int[] seeks) {return new Xof_meta_img_chkr().Width_(w).Height_(h).Seeks_(seeks);}
|
||||
Xof_meta_thumb itm_y_(int w, int h, int... seeks) {return new Xof_meta_thumb(Xof_meta_itm.Exists_y, w, h, seeks);}
|
||||
Xof_meta_thumb itm_n_(int w, int h, int... seeks) {return new Xof_meta_thumb(Xof_meta_itm.Exists_n, w, h, seeks);}
|
||||
}
|
||||
Reference in New Issue
Block a user