mirror of https://github.com/gnosygnu/xowa
parent
dc66b926d3
commit
0cdfa0992c
@ -0,0 +1,46 @@
|
|||||||
|
package gplx.core.serials.binarys;
|
||||||
|
|
||||||
|
import gplx.Bry_;
|
||||||
|
import gplx.core.serials.core.SerialLoadMgr;
|
||||||
|
import gplx.core.serials.core.SerialLoadWkr;
|
||||||
|
import gplx.core.texts.Base64Converter;
|
||||||
|
|
||||||
|
public class BinaryLoadMgr implements SerialLoadMgr {
|
||||||
|
public static final int CORE_VERSION = 0;
|
||||||
|
private byte[] data;
|
||||||
|
private int headerEnd;
|
||||||
|
private int dataVersion;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int CoreVersion() {
|
||||||
|
return CORE_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int DataVersion() {return dataVersion;}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ReadHeader(byte[] data) {
|
||||||
|
this.data = data;
|
||||||
|
this.dataVersion = Base64Converter.GetIndexInt((char)data[1]);
|
||||||
|
this.headerEnd = 3; // 1=coreVersion; 2=dataVersion; 3=\n
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] Data() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int HeaderEnd() {
|
||||||
|
return headerEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialLoadWkr NewLoadWkr() {
|
||||||
|
return new BinaryLoadWkr().Ctor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] FldDlm() {return fldDlm;} private final byte[] fldDlm = Bry_.new_a7("|");
|
||||||
|
public byte[] RowDlm() {return rowDlm;} private final byte[] rowDlm = Bry_.new_a7("\n");
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package gplx.core.serials.binarys;
|
||||||
|
|
||||||
|
import gplx.Bry_;
|
||||||
|
import gplx.Bry_find_;
|
||||||
|
import gplx.Err_;
|
||||||
|
import gplx.String_;
|
||||||
|
import gplx.core.serials.core.SerialLoadMgr;
|
||||||
|
import gplx.core.serials.core.SerialLoadWkr;
|
||||||
|
|
||||||
|
public class BinaryLoadWkr implements SerialLoadWkr {
|
||||||
|
private BinaryLoadMgr mgr;
|
||||||
|
private byte[] fldDlm;
|
||||||
|
private byte[] rowDlm;
|
||||||
|
private byte[] src;
|
||||||
|
private int srcLen;
|
||||||
|
private int cur;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialLoadWkr Ctor(SerialLoadMgr mgrObj) {
|
||||||
|
this.mgr = (BinaryLoadMgr)mgrObj;
|
||||||
|
this.fldDlm = mgr.FldDlm();
|
||||||
|
this.rowDlm = mgr.RowDlm();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void Init(byte[] src, int cur) {
|
||||||
|
this.src = src;
|
||||||
|
this.srcLen = src.length;
|
||||||
|
this.cur = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String LoadStr() {
|
||||||
|
return String_.new_u8(LoadBry());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int LoadInt() {
|
||||||
|
return LoadInt(rowDlm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] LoadBry() {
|
||||||
|
int bryLen = LoadInt(fldDlm);
|
||||||
|
|
||||||
|
// extract bry
|
||||||
|
int bryBgn = cur;
|
||||||
|
int bryEnd = bryBgn + bryLen;
|
||||||
|
if (bryEnd > srcLen) {
|
||||||
|
throw Err_.new_wo_type(String_.Format("End position is out of bounds; src={0} currentPosition={1} byteArrayLength={2} remainder={3}", src, cur, bryLen, Bry_.Mid(src, bryBgn, bryEnd)));
|
||||||
|
}
|
||||||
|
cur = bryEnd + rowDlm.length;
|
||||||
|
|
||||||
|
return Bry_.Mid(src, bryBgn, bryEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int LoadInt(byte[] dlm) {
|
||||||
|
int bgn = cur;
|
||||||
|
|
||||||
|
// find position of delimiter
|
||||||
|
int end = Bry_find_.Find_fwd(src, dlm, cur, srcLen);
|
||||||
|
if (end == Bry_find_.Not_found) {
|
||||||
|
throw Err_.new_wo_type(String_.Format("Failed to find delimiter for integer's end position; src={0} currentPosition={1} delimiter={2}", src, cur, fldDlm));
|
||||||
|
}
|
||||||
|
cur = end + dlm.length;
|
||||||
|
|
||||||
|
// parse int
|
||||||
|
int val = Bry_.To_int_or(src, bgn, end, -1);
|
||||||
|
if (val == -1) {
|
||||||
|
throw Err_.new_wo_type(String_.Format("Failed to parse integer; src={0} currentPosition={1} string={2}", src, cur, Bry_.Mid(src, bgn, end)));
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package gplx.core.serials.binarys;
|
||||||
|
|
||||||
|
import gplx.Bry_;
|
||||||
|
import gplx.core.serials.core.SerialSaveMgr;
|
||||||
|
import gplx.core.serials.core.SerialSaveWkr;
|
||||||
|
|
||||||
|
public class BinarySaveMgr implements SerialSaveMgr {
|
||||||
|
public int CoreVersion() {return BinaryLoadMgr.CORE_VERSION;}
|
||||||
|
public byte[] FldDlm() {return fldDlm;} private final byte[] fldDlm = Bry_.new_a7("|");
|
||||||
|
public byte[] RowDlm() {return rowDlm;} private final byte[] rowDlm = Bry_.new_a7("\n");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialSaveWkr NewSaveWkr() {
|
||||||
|
return new BinarySaveWkr().Ctor(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package gplx.core.serials.binarys;
|
||||||
|
|
||||||
|
import gplx.Bry_;
|
||||||
|
import gplx.Bry_bfr;
|
||||||
|
import gplx.Bry_bfr_;
|
||||||
|
import gplx.core.serials.core.SerialSaveMgr;
|
||||||
|
import gplx.core.serials.core.SerialSaveWkr;
|
||||||
|
import gplx.core.texts.Base64Converter;
|
||||||
|
|
||||||
|
public class BinarySaveWkr implements SerialSaveWkr {
|
||||||
|
private byte[] fldDlm;
|
||||||
|
private byte[] rowDlm;
|
||||||
|
private BinarySaveMgr mgr;
|
||||||
|
private final Bry_bfr bfr = Bry_bfr_.New();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerialSaveWkr Ctor(SerialSaveMgr mgrObj) {
|
||||||
|
this.mgr = (BinarySaveMgr)mgrObj;
|
||||||
|
this.fldDlm = mgr.FldDlm();
|
||||||
|
this.rowDlm = mgr.RowDlm();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void Init() {
|
||||||
|
bfr.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void SaveHdr(int dataVersion) {
|
||||||
|
// EX: AA -> SerialCoreMgrID+DataVersionID
|
||||||
|
bfr.Add_byte((byte)Base64Converter.GetIndexChar(mgr.CoreVersion()));
|
||||||
|
bfr.Add_byte((byte)Base64Converter.GetIndexChar(dataVersion)).Add(rowDlm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void SaveInt(int val) {
|
||||||
|
SaveInt(val, rowDlm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void SaveStr(String val) {
|
||||||
|
this.SaveBry(Bry_.new_u8(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void SaveBry(byte[] val) {
|
||||||
|
SaveInt(val.length, fldDlm);
|
||||||
|
bfr.Add(val).Add(rowDlm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveInt(int val, byte[] dlm) {
|
||||||
|
bfr.Add_int_variable(val).Add(dlm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] ToBry() {
|
||||||
|
return bfr.To_bry();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package gplx.core.serials.core;
|
||||||
|
|
||||||
|
import gplx.Err_;
|
||||||
|
import gplx.core.serials.binarys.BinaryLoadMgr;
|
||||||
|
import gplx.core.serials.binarys.BinarySaveMgr;
|
||||||
|
import gplx.core.texts.Base64Converter;
|
||||||
|
|
||||||
|
public class SerialCoreFactory {
|
||||||
|
public static SerialSaveMgr NewSaveMgr(int coreVersion) {
|
||||||
|
if (coreVersion == BinaryLoadMgr.CORE_VERSION) {
|
||||||
|
return new BinarySaveMgr();
|
||||||
|
}
|
||||||
|
throw Err_.new_unhandled_default(coreVersion);
|
||||||
|
}
|
||||||
|
public static SerialLoadMgr NewLoadMgr(byte[] data) {
|
||||||
|
int coreVersion = Base64Converter.GetIndexInt((char)data[0]);
|
||||||
|
if (coreVersion == BinaryLoadMgr.CORE_VERSION) {
|
||||||
|
BinaryLoadMgr loadMgr = new BinaryLoadMgr();
|
||||||
|
loadMgr.ReadHeader(data);
|
||||||
|
return loadMgr;
|
||||||
|
}
|
||||||
|
throw Err_.new_unhandled_default(coreVersion);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package gplx.core.serials.core;
|
||||||
|
|
||||||
|
public interface SerialLoadMgr {
|
||||||
|
int CoreVersion();
|
||||||
|
int DataVersion();
|
||||||
|
SerialLoadWkr NewLoadWkr();
|
||||||
|
void ReadHeader(byte[] data);
|
||||||
|
byte[] Data();
|
||||||
|
int HeaderEnd();
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package gplx.core.serials.core;
|
||||||
|
|
||||||
|
public interface SerialLoadWkr {
|
||||||
|
SerialLoadWkr Ctor(SerialLoadMgr mgr);
|
||||||
|
void Init(byte[] src, int cur);
|
||||||
|
int LoadInt();
|
||||||
|
byte[] LoadBry();
|
||||||
|
String LoadStr();
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package gplx.core.serials.core;
|
||||||
|
|
||||||
|
public interface SerialSaveMgr {
|
||||||
|
int CoreVersion();
|
||||||
|
SerialSaveWkr NewSaveWkr();
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package gplx.core.serials.core;
|
||||||
|
|
||||||
|
public interface SerialSaveWkr {
|
||||||
|
SerialSaveWkr Ctor(SerialSaveMgr mgr);
|
||||||
|
void Init();
|
||||||
|
void SaveHdr(int dataVersion);
|
||||||
|
void SaveInt(int val);
|
||||||
|
void SaveStr(String val);
|
||||||
|
void SaveBry(byte[] val);
|
||||||
|
byte[] ToBry();
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package gplx.xowa.xtns.indicators;
|
||||||
|
|
||||||
|
import gplx.Ordered_hash;
|
||||||
|
import gplx.Ordered_hash_;
|
||||||
|
import gplx.core.serials.binarys.BinaryLoadMgr;
|
||||||
|
import gplx.core.serials.core.SerialCoreFactory;
|
||||||
|
import gplx.core.serials.core.SerialLoadMgr;
|
||||||
|
import gplx.core.serials.core.SerialLoadWkr;
|
||||||
|
import gplx.core.serials.core.SerialSaveMgr;
|
||||||
|
import gplx.core.serials.core.SerialSaveWkr;
|
||||||
|
|
||||||
|
public class IndicatorSerialCore {
|
||||||
|
private static final int DATA_VERSION = 0;
|
||||||
|
|
||||||
|
public static byte[] Save(Ordered_hash list) {
|
||||||
|
// get wkr
|
||||||
|
SerialSaveMgr mgr = SerialCoreFactory.NewSaveMgr(BinaryLoadMgr.CORE_VERSION);
|
||||||
|
SerialSaveWkr wkr = mgr.NewSaveWkr();
|
||||||
|
|
||||||
|
// save header
|
||||||
|
wkr.SaveHdr(DATA_VERSION);
|
||||||
|
|
||||||
|
// save items
|
||||||
|
int len = list.Len();
|
||||||
|
wkr.SaveInt(len);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
Indicator_xnde xnde = (Indicator_xnde)list.Get_at(i);
|
||||||
|
wkr.SaveStr(xnde.Name());
|
||||||
|
wkr.SaveBry(xnde.Html());
|
||||||
|
}
|
||||||
|
return wkr.ToBry();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Ordered_hash Load(byte[] data) {
|
||||||
|
// get wkr
|
||||||
|
SerialLoadMgr mgr = SerialCoreFactory.NewLoadMgr(data);
|
||||||
|
SerialLoadWkr wkr = mgr.NewLoadWkr();
|
||||||
|
|
||||||
|
// init
|
||||||
|
wkr.Init(mgr.Data(), mgr.HeaderEnd());
|
||||||
|
|
||||||
|
// load items
|
||||||
|
int len = wkr.LoadInt();
|
||||||
|
Ordered_hash list = Ordered_hash_.New();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
Indicator_xnde xnde = new Indicator_xnde();
|
||||||
|
xnde.Name_(wkr.LoadStr());
|
||||||
|
xnde.Html_(wkr.LoadBry());
|
||||||
|
list.Add_if_dupe_use_nth(xnde.Name(), xnde);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
XOWA: the XOWA Offline Wiki Application
|
||||||
|
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||||
|
|
||||||
|
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||||
|
or alternatively under the terms of the Apache License Version 2.0.
|
||||||
|
|
||||||
|
You may use XOWA according to either of these licenses as is most appropriate
|
||||||
|
for your project on a case-by-case basis.
|
||||||
|
|
||||||
|
The terms of each license can be found in the source code repository:
|
||||||
|
|
||||||
|
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||||
|
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||||
|
*/
|
||||||
|
package gplx.xowa.xtns.indicators;
|
||||||
|
|
||||||
|
import gplx.xowa.Xoa_app;
|
||||||
|
import gplx.xowa.Xow_wiki;
|
||||||
|
import gplx.xowa.addons.Xoax_addon_itm;
|
||||||
|
import gplx.xowa.addons.Xoax_addon_itm__init;
|
||||||
|
|
||||||
|
public class Indicator_addon implements Xoax_addon_itm, Xoax_addon_itm__init {
|
||||||
|
public void Init_addon_by_app(Xoa_app app) {}
|
||||||
|
public void Init_addon_by_wiki(Xow_wiki wiki) {
|
||||||
|
wiki.Hxtn_mgr().Reg_wkr(new Indicator_hxtn_page_wkr(wiki.Hxtn_mgr().Blob_tbl()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String Addon__key() {return "xowa.indicators";}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
XOWA: the XOWA Offline Wiki Application
|
||||||
|
Copyright (C) 2012-2020 gnosygnu@gmail.com
|
||||||
|
|
||||||
|
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
|
||||||
|
or alternatively under the terms of the Apache License Version 2.0.
|
||||||
|
|
||||||
|
You may use XOWA according to either of these licenses as is most appropriate
|
||||||
|
for your project on a case-by-case basis.
|
||||||
|
|
||||||
|
The terms of each license can be found in the source code repository:
|
||||||
|
|
||||||
|
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
|
||||||
|
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||||
|
*/
|
||||||
|
package gplx.xowa.xtns.indicators;
|
||||||
|
|
||||||
|
import gplx.xowa.Xoa_ttl;
|
||||||
|
import gplx.xowa.htmls.Xoh_page;
|
||||||
|
import gplx.xowa.htmls.hxtns.blobs.Hxtn_blob_tbl;
|
||||||
|
import gplx.xowa.htmls.hxtns.pages.Hxtn_page_mgr;
|
||||||
|
import gplx.xowa.htmls.hxtns.pages.Hxtn_page_wkr;
|
||||||
|
|
||||||
|
public class Indicator_hxtn_page_wkr implements Hxtn_page_wkr {
|
||||||
|
private final Hxtn_blob_tbl page_text_tbl;
|
||||||
|
public int Id() {return Hxtn_page_mgr.Id__indicators;}
|
||||||
|
public String Key() {return KEY;}
|
||||||
|
public Indicator_hxtn_page_wkr(Hxtn_blob_tbl page_text_tbl) {
|
||||||
|
this.page_text_tbl = page_text_tbl;
|
||||||
|
}
|
||||||
|
public void Load_by_page(Xoh_page hpg, Xoa_ttl ttl, int page_id) {
|
||||||
|
byte[] data = page_text_tbl.Select_text(Hxtn_blob_tbl.Blob_tid__wtxt, Hxtn_page_mgr.Id__indicators, page_id);
|
||||||
|
hpg.Props().Add(KEY, data);
|
||||||
|
}
|
||||||
|
public static final String KEY = "xowa.xtns.indicators";
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package gplx.xowa.xtns.indicators;
|
||||||
|
|
||||||
|
import gplx.Bry_;
|
||||||
|
import gplx.Ordered_hash;
|
||||||
|
import gplx.Ordered_hash_;
|
||||||
|
import gplx.String_;
|
||||||
|
import gplx.core.tests.Gftest;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class IndicatorSerialCoreTest {
|
||||||
|
private IndicatorSerialCoreTstr tstr = new IndicatorSerialCoreTstr();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Save() {
|
||||||
|
tstr.TestBoth(String_.Concat_lines_nl
|
||||||
|
( "AA"
|
||||||
|
, "2"
|
||||||
|
, "5|name0"
|
||||||
|
, "5|html0"
|
||||||
|
, "5|name1"
|
||||||
|
, "5|html1"
|
||||||
|
), tstr.NewXnde("name0", "html0"), tstr.NewXnde("name1", "html1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class IndicatorSerialCoreTstr {
|
||||||
|
public Indicator_xnde NewXnde(String name, String html) {
|
||||||
|
Indicator_xnde xnde = new Indicator_xnde();
|
||||||
|
xnde.Name_(name);
|
||||||
|
xnde.Html_(Bry_.new_u8(html));
|
||||||
|
return xnde;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TestBoth(String data, Indicator_xnde... xndes) {
|
||||||
|
byte[] save = TestSave(data, xndes);
|
||||||
|
TestLoad(String_.new_u8(save), xndes);
|
||||||
|
}
|
||||||
|
public byte[] TestSave(String expd, Indicator_xnde... xndes) {
|
||||||
|
byte[] actl = IndicatorSerialCore.Save(ToList(xndes));
|
||||||
|
Gftest.Eq__str(expd, actl);
|
||||||
|
return actl;
|
||||||
|
}
|
||||||
|
public Ordered_hash TestLoad(String data, Indicator_xnde... expd) {
|
||||||
|
Ordered_hash list = IndicatorSerialCore.Load(Bry_.new_u8(data));
|
||||||
|
|
||||||
|
Gftest.Eq__bry(IndicatorSerialCore.Save(ToList(expd)), IndicatorSerialCore.Save(list)); // should probably compare items, but easier to compare seiarlization
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
private Ordered_hash ToList(Indicator_xnde[] xndes) {
|
||||||
|
Ordered_hash list = Ordered_hash_.New();
|
||||||
|
for (Indicator_xnde xnde : xndes) {
|
||||||
|
list.Add_if_dupe_use_nth(xnde.Name(), xnde);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue