mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.8.1.1
This commit is contained in:
57
400_xowa/src_060_utl/gplx/Bry_ary.java
Normal file
57
400_xowa/src_060_utl/gplx/Bry_ary.java
Normal 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;
|
||||
public class Bry_ary {
|
||||
private byte[][] ary; private int len, max;
|
||||
public Bry_ary(int max) {
|
||||
this.len = 0;
|
||||
this.max = max;
|
||||
this.ary = new byte[max][];
|
||||
}
|
||||
public byte[][] Ary() {return ary;}
|
||||
public void Clear() {
|
||||
for (int i = 0; i < len; ++i)
|
||||
ary[i] = null;
|
||||
len = 0;
|
||||
}
|
||||
public int Len() {return len;}
|
||||
public void Add(byte[] v) {
|
||||
if (len == max) {
|
||||
int new_max = max * 2;
|
||||
byte[][] new_ary = new byte[new_max][];
|
||||
for (int i = 0; i < len; ++i)
|
||||
new_ary[i] = ary[i];
|
||||
this.ary = new_ary;
|
||||
this.max = new_max;
|
||||
}
|
||||
ary[len] = v;
|
||||
++len;
|
||||
}
|
||||
public byte[] Get_at(int i) {return ary[i];}
|
||||
public byte[] Get_at_last() {return len == 0 ? null : ary[len - 1];}
|
||||
public void Set_at_last(byte[] v) {ary[len - 1] = v;}
|
||||
public void Set_at(int i, byte[] v) {ary[i] = v;}
|
||||
public byte[][] To_ary(int rel) {
|
||||
if (len == 0) return Bry_.Ary_empty;
|
||||
int rv_len = len + rel;
|
||||
byte[][] rv = new byte[rv_len][];
|
||||
for (int i = 0; i < rv_len; ++i)
|
||||
rv[i] = ary[i];
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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;
|
||||
import gplx.xowa.net.*;
|
||||
public class Gfo_url {
|
||||
public byte[] Raw() {return raw;} private byte[] raw;
|
||||
public boolean Protocol_is_relative() {return protocol_is_relative;} public Gfo_url Protocol_is_relative_(boolean v) {protocol_is_relative = v; return this;} private boolean protocol_is_relative;
|
||||
public byte Protocol_tid() {return protocol_tid;} public Gfo_url Protocol_tid_(byte v) {protocol_tid = v; return this;} private byte protocol_tid;
|
||||
public byte[] Protocol_bry() {return protocol_bry;} public Gfo_url Protocol_bry_(byte[] v) {protocol_bry = v; return this;} private byte[] protocol_bry;
|
||||
public byte[] Site() {return site;} public Gfo_url Site_(byte[] v) {site = v; return this;} private byte[] site;
|
||||
public byte[] Site_sub() {return site_sub;} public Gfo_url Site_sub_(byte[] v) {site_sub = v; return this;} private byte[] site_sub;
|
||||
public byte[] Site_name() {return site_name;} public Gfo_url Site_name_(byte[] v) {site_name = v; return this;} private byte[] site_name;
|
||||
public byte[] Site_domain() {return site_domain;} public Gfo_url Site_domain_(byte[] v) {site_domain = v; return this;} private byte[] site_domain;
|
||||
public byte[] Page() {return page;} public Gfo_url Page_(byte[] v) {page = v; return this;} private byte[] page;
|
||||
public byte[] Anchor() {return anchor;} public Gfo_url Anchor_(byte[] v) {anchor = v; return this;} private byte[] anchor;
|
||||
public byte[][] Segs() {return segs;} public Gfo_url Segs_(byte[][] v) {segs = v; return this;} private byte[][] segs;
|
||||
public Gfo_url_arg[] Args() {return args;} public Gfo_url Args_(Gfo_url_arg[] v) {args = v; return this;} Gfo_url_arg[] args;
|
||||
public int Args_bgn() {return args_bgn;} public Gfo_url Args_bgn_(int v) {args_bgn = v; return this;} private int args_bgn = -1;
|
||||
public byte Err() {return err;} public Gfo_url Err_(byte v) {err = v; return this;} private byte err;
|
||||
public Gfo_url Ini_(byte[] v) {
|
||||
raw = v;
|
||||
protocol_tid = Xoo_protocol_itm.Tid_null; protocol_is_relative = false;
|
||||
protocol_bry = site = site_sub = site_name = site_domain = page = anchor = null;
|
||||
segs = Bry_.Ary_empty;
|
||||
args = Gfo_url_arg.Ary_empty;
|
||||
err = Err_none;
|
||||
args_bgn = -1;
|
||||
return this;
|
||||
}
|
||||
public static final byte Err_none = 0, Err_protocol_missing = 1, Err_site_missing = 2;
|
||||
}
|
||||
@@ -1,41 +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;
|
||||
public class Gfo_url_arg {
|
||||
public Gfo_url_arg(byte[] key_bry, byte[] val_bry) {this.key_bry = key_bry; this.val_bry = val_bry;}
|
||||
public byte[] Key_bry() {return key_bry;} private byte[] key_bry;
|
||||
public byte[] Val_bry() {return val_bry;} private byte[] val_bry;
|
||||
public Gfo_url_arg Val_bry_(byte[] v) {val_bry = v; return this;}
|
||||
public static final Gfo_url_arg[] Ary_empty = new Gfo_url_arg[0];
|
||||
public static Gfo_url_arg new_key_(String key) {
|
||||
return new Gfo_url_arg(Bry_.new_u8(key), Bry_.Empty);
|
||||
}
|
||||
public static Gfo_url_arg[] Ary(String... kvs) {
|
||||
int len = kvs.length;
|
||||
Gfo_url_arg[] rv = new Gfo_url_arg[len / 2];
|
||||
String key = null;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
String s = kvs[i];
|
||||
if (i % 2 == 0)
|
||||
key = s;
|
||||
else
|
||||
rv[i / 2] = new Gfo_url_arg(Bry_.new_u8(key), Bry_.new_u8(s));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1,312 +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;
|
||||
import gplx.xowa.net.*;
|
||||
public class Gfo_url_parser {
|
||||
private boolean pass = true;
|
||||
private Gfo_url url;
|
||||
private List_adp segs = List_adp_.new_(), args = List_adp_.new_();
|
||||
private Url_encoder encoder = Url_encoder.new_html_href_mw_().Itms_raw_same_many(Byte_ascii.Underline); private Hash_adp_bry protocols = Hash_adp_bry.ci_ascii_(); // ASCII:url_protocol; EX:"http:", "ftp:", etc
|
||||
public Gfo_url_parser() {
|
||||
Init_protocols(Xoo_protocol_itm.Ary());
|
||||
Init_protocol(Xoo_protocol_itm.Tid_file, Xoo_protocol_itm.Str_file);
|
||||
}
|
||||
public void Init_protocol(byte tid, String protocol) {Init_protocols(new Xoo_protocol_itm(tid, protocol));}
|
||||
public void Init_protocols(Xoo_protocol_itm... itms) {
|
||||
int len = itms.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xoo_protocol_itm itm = itms[i];
|
||||
byte[] key = itm.Key_w_colon_bry();
|
||||
if (protocols.Has(key)) continue; // NOTE: must check if protocol exists, else test will fail
|
||||
protocols.Add(key, itm);
|
||||
}
|
||||
}
|
||||
public byte Relative_url_protocol() {return relative_url_protocol;} public Gfo_url_parser Relative_url_protocol_(byte v) {relative_url_protocol = v; return this;} private byte relative_url_protocol = Xoo_protocol_itm.Tid_http;
|
||||
public byte[] Relative_url_protocol_bry() {return Xoo_protocol_itm.Ary()[relative_url_protocol].Key_w_colon_bry();}
|
||||
public void Parse_site_fast(Gfo_url_site_data site_data, byte[] src, int bgn, int end) {
|
||||
int pos = bgn; boolean rel = false;
|
||||
if (pos + 1 < end && src[pos] == Byte_ascii.Slash && src[pos + 1] == Byte_ascii.Slash) { // starts with "//"
|
||||
pos += 2;
|
||||
rel = true;
|
||||
}
|
||||
if (!rel) { // search for ":"; NOTE: only search if not rel; i.e.: "//"
|
||||
int colon_pos = Bry_finder.Find_fwd(src, Byte_ascii.Colon, pos, end); // no colon found; EX: "//a.org/b"; "a.org/b"
|
||||
if (colon_pos != Bry_.NotFound) // colon found; EX: "http://" or "https://"
|
||||
pos = colon_pos + Int_.Const_dlm_len;
|
||||
if (pos < end && src[pos] == Byte_ascii.Slash) { // skip slash after colon
|
||||
pos += 1;
|
||||
if (pos < end && src[pos] == Byte_ascii.Slash) // skip 2nd slash after colon
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
int slash_pos = Bry_finder.Find_fwd(src, Byte_ascii.Slash, pos, end);
|
||||
if (slash_pos == Bry_.NotFound) // no terminating slash; EX: http://a.org
|
||||
slash_pos = end;
|
||||
slash_pos = Bry_.Trim_end_pos(src, slash_pos);
|
||||
site_data.Atrs_set(rel, pos, slash_pos);
|
||||
}
|
||||
public Gfo_url Parse(byte[] src) {Gfo_url rv = new Gfo_url(); this.Parse(rv, src, 0, src.length); return rv;}
|
||||
public boolean Parse(Gfo_url url, byte[] src, int bgn, int end) {
|
||||
this.url = url;
|
||||
url.Ini_(src);
|
||||
pass = true;
|
||||
segs.Clear();
|
||||
args.Clear();
|
||||
int colon_pos = Bry_finder.Find_fwd(src, Byte_ascii.Colon, bgn, end);
|
||||
Object protocol_obj = colon_pos == Bry_.NotFound ? null : protocols.Get_by_mid(src, bgn, colon_pos + 1); // +1 to include colon
|
||||
if (protocol_obj != null) {
|
||||
Xoo_protocol_itm protocol_itm = (Xoo_protocol_itm)protocol_obj;
|
||||
url.Protocol_bry_(protocol_itm.Key_w_colon_bry());
|
||||
url.Protocol_tid_(protocol_itm.Tid());
|
||||
Parse_site(src, protocol_itm.Key_w_colon_bry().length, end);
|
||||
}
|
||||
else {
|
||||
int pos = bgn;
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (pos == end) {
|
||||
encoder.Decode(src, bgn, end, tmp_bfr, false);
|
||||
url.Site_(tmp_bfr.Xto_bry_and_clear());
|
||||
url.Err_(Gfo_url.Err_protocol_missing); pass = false;
|
||||
break;
|
||||
}
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Colon:
|
||||
// Segs_add(src, bgn, end);
|
||||
Parse_segs(src, bgn, end);
|
||||
loop = false;
|
||||
url.Err_(Gfo_url.Err_protocol_missing); pass = false;
|
||||
loop = false;
|
||||
break;
|
||||
case Byte_ascii.Question:
|
||||
Segs_add(src, bgn, pos);
|
||||
Parse_args(src, pos + 1, end);
|
||||
loop = false;
|
||||
url.Err_(Gfo_url.Err_protocol_missing); pass = false;
|
||||
break;
|
||||
case Byte_ascii.Hash:
|
||||
Segs_add(src, bgn, pos);
|
||||
Parse_anchor(src, pos + 1, end);
|
||||
slash_prv = pos;
|
||||
loop = false;
|
||||
url.Err_(Gfo_url.Err_protocol_missing); pass = false;
|
||||
break;
|
||||
case Byte_ascii.Slash:
|
||||
if (pos == 0 && pos + 1 < end && src[pos + 1] == Byte_ascii.Slash) { // starts with "//"
|
||||
encoder.Decode(src, bgn, pos, tmp_bfr, false);
|
||||
url.Site_(tmp_bfr.Xto_bry_and_clear());
|
||||
url.Protocol_is_relative_(true);
|
||||
url.Protocol_tid_(relative_url_protocol);
|
||||
byte[] protocol_bry = Xoo_protocol_itm.Ary()[relative_url_protocol].Key_w_colon_bry();
|
||||
url.Protocol_bry_(protocol_bry);
|
||||
Parse_site(src, 2, end); // 2=//
|
||||
loop = false;
|
||||
}
|
||||
else { // has "/"
|
||||
encoder.Decode(src, bgn, pos, tmp_bfr, false);
|
||||
url.Site_(tmp_bfr.Xto_bry_and_clear());
|
||||
Parse_segs(src, pos + 1, end);
|
||||
loop = false;
|
||||
url.Err_(Gfo_url.Err_protocol_missing); pass = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
private void Parse_site(byte[] src, int bgn, int end) {
|
||||
int dot_count = 0, dot_pos_0 = -1, dot_pos_1 = -1;
|
||||
boolean loop = true;
|
||||
byte b = Byte_ascii.Null;
|
||||
while (loop) {
|
||||
if (bgn == end) {
|
||||
url.Err_(Gfo_url.Err_site_missing);
|
||||
break;
|
||||
}
|
||||
b = src[bgn];
|
||||
if (b == Byte_ascii.Slash)
|
||||
++bgn;
|
||||
else
|
||||
break;
|
||||
}
|
||||
int pos = bgn;
|
||||
while (loop) {
|
||||
switch (b) {
|
||||
case Byte_ascii.Dot:
|
||||
switch (dot_count) {
|
||||
case 0: dot_pos_0 = pos; break;
|
||||
case 1: dot_pos_1 = pos; break;
|
||||
}
|
||||
++dot_count;
|
||||
break;
|
||||
case Byte_ascii.Slash:
|
||||
Site_set(src, bgn, pos, dot_count, dot_pos_0, dot_pos_1);
|
||||
Parse_segs(src, pos + 1, end);
|
||||
loop = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!loop) break;
|
||||
++pos;
|
||||
if (pos >= end) { // NOTE: >= needed b/c sometimes "xowa-cmd:", 5 passed in
|
||||
Site_set(src, bgn, end, dot_count, dot_pos_0, dot_pos_1);
|
||||
break;
|
||||
}
|
||||
b = src[pos];
|
||||
}
|
||||
}
|
||||
int slash_prv;
|
||||
private void Parse_segs(byte[] src, int bgn, int end) {
|
||||
if (bgn == end) return;
|
||||
int pos = bgn;
|
||||
slash_prv = bgn;
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (pos == end) {
|
||||
if (slash_prv < pos) Segs_add(src, slash_prv, end);
|
||||
break;
|
||||
}
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Question:
|
||||
Segs_add(src, slash_prv, pos);
|
||||
Parse_args(src, pos + 1, end);
|
||||
loop = false;
|
||||
break;
|
||||
case Byte_ascii.Hash:
|
||||
Segs_add(src, slash_prv, pos);
|
||||
Parse_anchor(src, pos + 1, end);
|
||||
slash_prv = pos;
|
||||
loop = false;
|
||||
break;
|
||||
case Byte_ascii.Slash:
|
||||
if (slash_prv != pos) // HACK: handles urls of form "/wiki//A"; treat 2nd / as part of "/A"
|
||||
Segs_add(src, slash_prv, pos);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
url.Segs_((byte[][])segs.To_ary(byte[].class));
|
||||
}
|
||||
private void Parse_anchor(byte[] src, int bgn, int end) {
|
||||
if (bgn == end) return;
|
||||
int pos = bgn;
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (pos == end) {
|
||||
Anchor_set(src, bgn, pos);
|
||||
break;
|
||||
}
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Question:
|
||||
Anchor_set(src, bgn, pos);
|
||||
Parse_args(src, pos + 1, end);
|
||||
loop = false;
|
||||
break;
|
||||
//case Byte_ascii.Slash: // NOTE: do not handle slash (by trying to parse segs); will cause anchor to fail; EX:A/b#c/d
|
||||
// case Byte_ascii.Slash:
|
||||
// Anchor_set(src, bgn, pos);
|
||||
// Parse_segs(src, pos + 1, end);
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
private void Parse_args(byte[] src, int bgn, int end) {
|
||||
// if (bgn == end) return; // make "A?" -> "A" DATE:2014-01-19
|
||||
int pos = bgn;
|
||||
boolean loop = true;
|
||||
int key_bgn = pos, key_end = pos, val_bgn = pos;
|
||||
while (loop) {
|
||||
if (pos == end) {
|
||||
Args_add(src, key_bgn, key_end, val_bgn, pos);
|
||||
break;
|
||||
}
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Amp:
|
||||
Args_add(src, key_bgn, key_end, val_bgn, pos);
|
||||
key_bgn = pos + 1;
|
||||
break;
|
||||
case Byte_ascii.Eq:
|
||||
key_end = pos;
|
||||
val_bgn = pos + 1; // +1 to set after eq
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
url.Args_bgn_(bgn - 1); // NOTE: bgn is 1st char after ?; -1 to place at ?
|
||||
url.Args_((Gfo_url_arg[])args.To_ary(Gfo_url_arg.class));
|
||||
}
|
||||
private void Args_add(byte[] src, int key_bgn, int key_end, int val_bgn, int val_end) {
|
||||
encoder.Decode(src, key_bgn, key_end, tmp_bfr, false);
|
||||
byte[] key = tmp_bfr.Xto_bry_and_clear();
|
||||
encoder.Decode(src, val_bgn, val_end, tmp_bfr, false);
|
||||
byte[] val = tmp_bfr.Xto_bry_and_clear();
|
||||
Gfo_url_arg arg = new Gfo_url_arg(key, val);
|
||||
args.Add(arg);
|
||||
}
|
||||
private void Site_set(byte[] src, int bgn, int end, int dot_count, int dot_pos_0, int dot_pos_1) {
|
||||
encoder.Decode(src, bgn, end, tmp_bfr, false);
|
||||
url.Site_(tmp_bfr.Xto_bry_and_clear());
|
||||
switch (dot_count) {
|
||||
default:
|
||||
case 2:
|
||||
encoder.Decode(src, bgn, dot_pos_0, tmp_bfr, false);
|
||||
url.Site_sub_(tmp_bfr.Xto_bry_and_clear());
|
||||
encoder.Decode(src, dot_pos_0 + 1, dot_pos_1, tmp_bfr, false);
|
||||
url.Site_name_(tmp_bfr.Xto_bry_and_clear());
|
||||
encoder.Decode(src, dot_pos_1 + 1, end, tmp_bfr, false);
|
||||
url.Site_domain_(tmp_bfr.Xto_bry_and_clear());
|
||||
break;
|
||||
case 1:
|
||||
encoder.Decode(src, bgn, dot_pos_0, tmp_bfr, false);
|
||||
url.Site_name_(tmp_bfr.Xto_bry_and_clear());
|
||||
encoder.Decode(src, dot_pos_0 + 1, end, tmp_bfr, false);
|
||||
url.Site_domain_(tmp_bfr.Xto_bry_and_clear());
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void Segs_add(byte[] src, int bgn, int end) {
|
||||
encoder.Decode(src, bgn, end, tmp_bfr, false);
|
||||
byte[] seg = tmp_bfr.Xto_bry_and_clear();
|
||||
if (url.Page() != null)
|
||||
segs.Add(url.Page());
|
||||
url.Page_(seg);
|
||||
slash_prv = end + 1; // +1 to position after /
|
||||
}
|
||||
private void Anchor_set(byte[] src, int bgn, int end) {
|
||||
encoder.Decode(src, bgn, end, tmp_bfr, false);
|
||||
url.Anchor_(tmp_bfr.Xto_bry_and_clear());
|
||||
}
|
||||
private static final Bry_bfr tmp_bfr = Bry_bfr.reset_(500);
|
||||
public static final byte[] Bry_double_slash = new byte[] {Byte_ascii.Slash, Byte_ascii.Slash};
|
||||
}
|
||||
@@ -1,153 +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;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.net.*;
|
||||
public class Gfo_url_parser_tst {
|
||||
Gfo_url_parser_chkr fxt = new Gfo_url_parser_chkr();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void All() {
|
||||
fxt.Raw_("http://en.wikipedia.org/wiki/mock/Page 0#a?b=c&d=e")
|
||||
.Protocol_tid_(Xoo_protocol_itm.Tid_http)
|
||||
.Site_("en.wikipedia.org")
|
||||
.Site_sub_("en")
|
||||
.Site_name_("wikipedia")
|
||||
.Site_domain_("org")
|
||||
.Segs_("wiki")
|
||||
.Segs_("mock")
|
||||
.Page_("Page 0")
|
||||
.Anchor_("a")
|
||||
.Args_("b", "c")
|
||||
.Args_("d", "e")
|
||||
.tst_();
|
||||
}
|
||||
@Test public void Site_slash_none() {
|
||||
fxt.Raw_("http:en.wikipedia.org").Protocol_tid_(Xoo_protocol_itm.Tid_http).Site_("en.wikipedia.org").tst_();
|
||||
}
|
||||
@Test public void Site_slash_many() {
|
||||
fxt.Raw_("http:////en.wikipedia.org").Protocol_tid_(Xoo_protocol_itm.Tid_http).Site_("en.wikipedia.org").tst_();
|
||||
}
|
||||
@Test public void Site_slash_trailing() {
|
||||
fxt.Raw_("http://en.wikipedia.org/").Protocol_tid_(Xoo_protocol_itm.Tid_http).Site_("en.wikipedia.org").tst_();
|
||||
}
|
||||
@Test public void Site_dot_1() {
|
||||
fxt.Raw_("http://wikipedia.org").Site_("wikipedia.org").Site_name_("wikipedia").Site_domain_("org").tst_();
|
||||
}
|
||||
@Test public void Page_encoded() {
|
||||
fxt.Raw_("http://site/A%27s").Site_("site").Page_("A's").tst_();
|
||||
}
|
||||
@Test public void Args() {
|
||||
fxt.Raw_("http://site/page?a=b").Site_("site").Args_("a", "b").tst_();
|
||||
}
|
||||
@Test public void Args_protocol_less() {
|
||||
fxt.Raw_("Special:Search/Earth?fulltext=yes").Segs_("Special:Search").Page_("Earth").Args_("fulltext", "yes").tst_();
|
||||
}
|
||||
@Test public void Err_protocol_missing() {
|
||||
fxt.Raw_("httpen.wikipedia.org").Err_(Gfo_url.Err_protocol_missing).tst_();
|
||||
}
|
||||
@Test public void Err_protocol_missing__site_only() {
|
||||
fxt.Raw_("site").Site_("site").Err_(Gfo_url.Err_protocol_missing).tst_();
|
||||
}
|
||||
@Test public void Err_protocol_missing__site_and_page() {
|
||||
fxt.Raw_("site/page").Site_("site").Page_("page").Err_(Gfo_url.Err_protocol_missing).tst_();
|
||||
}
|
||||
@Test public void Err_protocol_missing__page_anchor() {
|
||||
fxt.Raw_("page#a").Page_("page").Anchor_("a").Err_(Gfo_url.Err_protocol_missing).tst_();
|
||||
}
|
||||
@Test public void Legacy() {
|
||||
fxt.Reset().Raw_("http://en.wikipedia.org/wiki/A" ).Page_("A").tst_();
|
||||
fxt.Reset().Raw_("http://en.wikipedia.org/wiki/A?").Page_("A").Args_("", "").tst_();
|
||||
fxt.Reset().Raw_("http://en.wikipedia.org/wiki/A#").Page_("A").tst_();
|
||||
fxt.Reset().Raw_("http://en.wikipedia.org/wiki/A%27s").Page_("A's").tst_();
|
||||
fxt.Reset().Raw_("https://en.wikipedia.org/wiki/A").Page_("A").tst_();
|
||||
fxt.Reset().Raw_("http://en.m.wikipedia.org/wiki/A").Page_("A").tst_();
|
||||
fxt.Reset().Raw_("http://en.wikipedia.org/w/index.php?title=A").Args_("title", "A").tst_();
|
||||
}
|
||||
@Test public void Relative() {
|
||||
fxt.Raw_("//en.wikipedia.org").Protocol_tid_(Xoo_protocol_itm.Tid_http).Site_("en.wikipedia.org").tst_();
|
||||
}
|
||||
@Test public void Parse_site_fast() {
|
||||
fxt.Parse_site_fast_tst("http://a.org/B" , "a.org");
|
||||
fxt.Parse_site_fast_tst("http://a.org" , "a.org");
|
||||
fxt.Parse_site_fast_tst("//a.org/B" , "a.org");
|
||||
fxt.Parse_site_fast_tst("//a.org/B:C" , "a.org");
|
||||
}
|
||||
}
|
||||
class Gfo_url_parser_chkr implements Tst_chkr {
|
||||
public Class<?> TypeOf() {return Gfo_url.class;}
|
||||
public Gfo_url_parser_chkr Protocol_tid_(byte v) {this.protocol_tid = v; return this;} private byte protocol_tid;
|
||||
public Gfo_url_parser_chkr Site_(String v) {this.site = v; return this;} private String site;
|
||||
public Gfo_url_parser_chkr Site_sub_(String v) {this.site_sub = v; return this;} private String site_sub;
|
||||
public Gfo_url_parser_chkr Site_name_(String v) {this.site_name = v; return this;} private String site_name;
|
||||
public Gfo_url_parser_chkr Site_domain_(String v) {this.site_domain = v; return this;} private String site_domain;
|
||||
public Gfo_url_parser_chkr Segs_(String v) {segs.Add(v); return this;} List_adp segs = List_adp_.new_();
|
||||
public Gfo_url_parser_chkr Page_(String v) {this.page = v; return this;} private String page;
|
||||
public Gfo_url_parser_chkr Anchor_(String v) {this.anchor = v; return this;} private String anchor;
|
||||
public Gfo_url_parser_chkr Args_(String k, String v) {args.Add(new Gfo_url_arg_chkr(k, v)); return this;} List_adp args = List_adp_.new_();
|
||||
public Gfo_url_parser_chkr Err_(byte v) {err = v; return this;} private byte err;
|
||||
public Gfo_url_parser_chkr Reset() {
|
||||
protocol_tid = Xoo_protocol_itm.Tid_null;
|
||||
site = site_sub = site_name = site_domain = page = anchor = null;
|
||||
err = Gfo_url.Err_none;
|
||||
segs.Clear();
|
||||
args.Clear();
|
||||
return this;
|
||||
}
|
||||
ByteAryAry_chkr bry_ary_chkr = new ByteAryAry_chkr();
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Gfo_url actl = (Gfo_url)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(err == Gfo_url.Err_none, path, "err", err, actl.Err());
|
||||
rv += mgr.Tst_val(protocol_tid == Xoo_protocol_itm.Tid_null, path, "protocol_tid", protocol_tid, actl.Protocol_tid());
|
||||
rv += mgr.Tst_val(site == null, path, "site", site, String_.new_u8(actl.Site()));
|
||||
rv += mgr.Tst_val(site_sub == null, path, "site_sub", site_sub, String_.new_u8(actl.Site_sub()));
|
||||
rv += mgr.Tst_val(site_name == null, path, "site_name", site_name, String_.new_u8(actl.Site_name()));
|
||||
rv += mgr.Tst_val(site_domain == null, path, "site_domain", site_domain, String_.new_u8(actl.Site_domain()));
|
||||
bry_ary_chkr.Val_(Bry_.Ary(segs.To_str_ary()));
|
||||
rv += bry_ary_chkr.Chk(mgr, "segs", actl.Segs());
|
||||
rv += mgr.Tst_val(page == null, path, "page", page, String_.new_u8(actl.Page()));
|
||||
rv += mgr.Tst_val(anchor == null, path, "anchor", anchor, String_.new_u8(actl.Anchor()));
|
||||
mgr.Tst_sub_ary((Gfo_url_arg_chkr[])args.To_ary(Gfo_url_arg_chkr.class), actl.Args(), "args", rv);
|
||||
return rv;
|
||||
}
|
||||
public Gfo_url_parser_chkr Raw_(String v) {this.raw = v; return this;} private String raw;
|
||||
public void tst_() {
|
||||
byte[] bry = Bry_.new_u8(raw);
|
||||
Gfo_url url = new Gfo_url();
|
||||
parser.Parse(url, bry, 0, bry.length);
|
||||
Tst_mgr tst_mgr = new Tst_mgr();
|
||||
tst_mgr.Tst_obj(this, url);
|
||||
} Gfo_url_parser parser = new Gfo_url_parser();
|
||||
public void Parse_site_fast_tst(String raw, String expd) {
|
||||
byte[] raw_bry = Bry_.new_u8(raw);
|
||||
parser.Parse_site_fast(site_data, raw_bry, 0, raw_bry.length);
|
||||
String actl = String_.new_u8(raw_bry, site_data.Site_bgn(), site_data.Site_end());
|
||||
Tfds.Eq(expd, actl);
|
||||
} Gfo_url_site_data site_data = new Gfo_url_site_data();
|
||||
}
|
||||
class Gfo_url_arg_chkr implements Tst_chkr {
|
||||
public Gfo_url_arg_chkr(String key, String val) {this.key = key; this.val = val;} private String key; String val;
|
||||
public Class<?> TypeOf() {return Gfo_url_arg.class;}
|
||||
public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
|
||||
Gfo_url_arg actl = (Gfo_url_arg)actl_obj;
|
||||
int rv = 0;
|
||||
rv += mgr.Tst_val(key == null, path, "key", key, String_.new_u8(actl.Key_bry()));
|
||||
rv += mgr.Tst_val(val == null, path, "val", val, String_.new_u8(actl.Val_bry()));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class Gfo_usr_dlg_fmt {
|
||||
public boolean Write_prog_cur(int cur, Gfo_usr_dlg usr_dlg) {
|
||||
if (cur < prog_prv + prog_interval) return usr_dlg.Canceled();
|
||||
prog_prv = cur;
|
||||
String pct = DecimalAdp_.CalcPctStr(cur + List_adp_.Base1, end, "00.00");
|
||||
String pct = Decimal_adp_.CalcPctStr(cur + List_adp_.Base1, end, "00.00");
|
||||
usr_dlg.Prog_many(grp_key, msg_key, fmt, Int_.Xto_str_pad_bgn_zero(cur + List_adp_.Base1, endLen), end, pct);
|
||||
return usr_dlg.Canceled();
|
||||
} String fmt; int end, endLen;
|
||||
|
||||
@@ -16,9 +16,31 @@ 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 class Gfo_url_site_data {
|
||||
public boolean Rel() {return rel;} private boolean rel;
|
||||
public int Site_bgn() {return site_bgn;} private int site_bgn;
|
||||
public int Site_end() {return site_end;} private int site_end;
|
||||
public void Atrs_set(boolean rel, int bgn, int end) {this.rel = rel; this.site_bgn = bgn; this.site_end = end;}
|
||||
public class Int_ary {
|
||||
private int[] ary; private int len, max;
|
||||
public Int_ary(int max) {
|
||||
this.len = 0;
|
||||
this.max = max;
|
||||
this.ary = new int[max];
|
||||
}
|
||||
public int[] Ary() {return ary;}
|
||||
public void Clear() {
|
||||
for (int i = 0; i < len; ++i)
|
||||
ary[i] = 0;
|
||||
len = 0;
|
||||
}
|
||||
public int Len() {return len;}
|
||||
public void Add(int v) {
|
||||
if (len == max) {
|
||||
int new_max = max * 2;
|
||||
int[] new_ary = new int[new_max];
|
||||
for (int i = 0; i < len; ++i)
|
||||
new_ary[i] = ary[i];
|
||||
this.ary = new_ary;
|
||||
this.max = new_max;
|
||||
}
|
||||
ary[len] = v;
|
||||
++len;
|
||||
}
|
||||
public int Get_at(int i) {return ary[i];}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx;
|
||||
public class Number_parser {
|
||||
public int Rv_as_int() {return (int)int_val;} long int_val = 0;
|
||||
public DecimalAdp Rv_as_dec() {return dec_val == null ? DecimalAdp_.long_(int_val) : dec_val;} DecimalAdp dec_val = null;
|
||||
public Decimal_adp Rv_as_dec() {return dec_val == null ? Decimal_adp_.long_(int_val) : dec_val;} Decimal_adp dec_val = null;
|
||||
public boolean Has_err() {return has_err;} private boolean has_err;
|
||||
public boolean Has_frac() {return has_frac;} private boolean has_frac;
|
||||
public boolean Hex_enabled() {return hex_enabled;} public Number_parser Hex_enabled_(boolean v) {hex_enabled = v; return this;} private boolean hex_enabled;
|
||||
@@ -169,7 +169,7 @@ public class Number_parser {
|
||||
if (exp_neg) frc_multiplier *= exp_multiplier; // divide, so apply to frc
|
||||
else full_val *= exp_multiplier; // multiply, so apply to full_val
|
||||
}
|
||||
dec_val = DecimalAdp_.divide_(full_val, frc_multiplier);
|
||||
dec_val = Decimal_adp_.divide_(full_val, frc_multiplier);
|
||||
}
|
||||
else {
|
||||
if (has_neg) int_val *= -1;
|
||||
|
||||
@@ -29,19 +29,19 @@ public class Number_parser_tst {
|
||||
fxt.Test_int("00001", 1);
|
||||
}
|
||||
@Test public void Decimal() {
|
||||
fxt.Test_dec("1.23", DecimalAdp_.parse_("1.23"));
|
||||
fxt.Test_dec("1.023", DecimalAdp_.parse_("1.023"));
|
||||
fxt.Test_dec("-1.23", DecimalAdp_.parse_("-1.23"));
|
||||
fxt.Test_dec("1.23", Decimal_adp_.parse_("1.23"));
|
||||
fxt.Test_dec("1.023", Decimal_adp_.parse_("1.023"));
|
||||
fxt.Test_dec("-1.23", Decimal_adp_.parse_("-1.23"));
|
||||
}
|
||||
@Test public void Double_long() {
|
||||
fxt.Test_dec(".42190046219457", DecimalAdp_.parse_(".42190046219457"));
|
||||
fxt.Test_dec(".42190046219457", Decimal_adp_.parse_(".42190046219457"));
|
||||
}
|
||||
@Test public void Exponent() {
|
||||
fxt.Test_int("1E2", 100);
|
||||
fxt.Test_dec("1.234E2", DecimalAdp_.parse_("123.4"));
|
||||
fxt.Test_dec("1.234E-2", DecimalAdp_.parse_(".01234"));
|
||||
fxt.Test_dec("123.4E-2", DecimalAdp_.parse_("1.234"));
|
||||
fxt.Test_dec("+6.0E-3", DecimalAdp_.parse_(".006"));
|
||||
fxt.Test_dec("1.234E2", Decimal_adp_.parse_("123.4"));
|
||||
fxt.Test_dec("1.234E-2", Decimal_adp_.parse_(".01234"));
|
||||
fxt.Test_dec("123.4E-2", Decimal_adp_.parse_("1.234"));
|
||||
fxt.Test_dec("+6.0E-3", Decimal_adp_.parse_(".006"));
|
||||
}
|
||||
@Test public void Err() {
|
||||
fxt.Test_err("+", true);
|
||||
@@ -77,10 +77,10 @@ class Number_parser_fxt {
|
||||
int actl = parser.Parse(raw_bry, 0, raw_bry.length).Rv_as_int();
|
||||
Tfds.Eq(expd, actl, raw);
|
||||
}
|
||||
public void Test_dec(String raw, DecimalAdp expd) {
|
||||
public void Test_dec(String raw, Decimal_adp expd) {
|
||||
byte[] raw_bry = Bry_.new_a7(raw);
|
||||
DecimalAdp actl = parser.Parse(raw_bry, 0, raw_bry.length).Rv_as_dec();
|
||||
Tfds.Eq(expd.Xto_decimal(), actl.Xto_decimal(), raw);
|
||||
Decimal_adp actl = parser.Parse(raw_bry, 0, raw_bry.length).Rv_as_dec();
|
||||
Tfds.Eq(expd.To_double(), actl.To_double(), raw);
|
||||
}
|
||||
public void Test_err(String raw, boolean expd) {
|
||||
byte[] raw_bry = Bry_.new_a7(raw);
|
||||
|
||||
@@ -109,11 +109,9 @@ public class Url_encoder implements Url_encoder_interface {
|
||||
byte[] bry = Bry_.new_u8(str); Decode(bry, 0, bry.length, tmp_bfr, true); return tmp_bfr.Xto_str_and_clear();
|
||||
}
|
||||
}
|
||||
public byte[] Decode(byte[] bry) {
|
||||
synchronized (thread_lock) {
|
||||
Decode(bry, 0, bry.length, tmp_bfr, false); return tmp_bfr.Xto_bry_and_clear();
|
||||
}
|
||||
}
|
||||
public byte[] Decode(byte[] bry) {return Decode(tmp_bfr, bry, 0, bry.length);}
|
||||
public byte[] Decode(byte[] bry, int bgn, int end) {return Decode(tmp_bfr, bry, bgn, end);}
|
||||
public byte[] Decode(Bry_bfr bfr, byte[] bry, int bgn, int end) {Decode(bry, bgn, end, bfr , false); return bfr.Xto_bry_and_clear();}
|
||||
public byte[] Decode_lax(byte[] bry) {
|
||||
synchronized (thread_lock) {
|
||||
Decode(bry, 0, bry.length, tmp_bfr, false); return tmp_bfr.Xto_bry_and_clear();
|
||||
@@ -297,9 +295,9 @@ class Url_encoder_itm_html_ent implements Url_encoder_itm {
|
||||
}
|
||||
else {
|
||||
Xop_amp_trie_itm itm = (Xop_amp_trie_itm)o;
|
||||
byte[] bry_utf8 = itm.Utf8_bry(); // NOTE: must utf8 encode val; EX: is 160 but must become 192,160
|
||||
for (int i = 0; i < bry_utf8.length; i++)
|
||||
Url_encoder_itm_hex.Encode_byte(bry_utf8[i], bfr, Byte_ascii.Dot);
|
||||
byte[] bry_u8 = itm.U8_bry(); // NOTE: must utf8 encode val; EX: is 160 but must become 192,160
|
||||
for (int i = 0; i < bry_u8.length; i++)
|
||||
Url_encoder_itm_hex.Encode_byte(bry_u8[i], bfr, Byte_ascii.Dot);
|
||||
return itm.Xml_name_bry().length - 1; // -1 to ignore & in XmlEntityName
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user