1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-05-03 22:30:22 -04:00
parent f4b95f5ce6
commit 0b5aa9aefe
207 changed files with 2339 additions and 1460 deletions

View File

@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
public class Int_ary_parser extends Obj_ary_parser_base {
NumberParser parser = new NumberParser(); int[] ary; int ary_idx;
Number_parser parser = new Number_parser(); int[] ary; int ary_idx;
public int[] Parse_ary(String str, byte dlm) {byte[] bry = Bry_.new_utf8_(str); return Parse_ary(bry, 0, bry.length, dlm);}
public int[] Parse_ary(byte[] bry, int bgn, int end, byte dlm) {
Parse_core(bry, bgn, end, dlm, Byte_ascii.Nil);
@@ -32,8 +32,8 @@ public class Int_ary_parser extends Obj_ary_parser_base {
}
}
@Override protected void Parse_itm(byte[] bry, int bgn, int end) {
parser.Parse(bry, bgn, end); if (parser.HasErr() || parser.HasFrac()) throw Err_.new_fmt_("failed to parse number: {0}", String_.new_utf8_(bry, bgn, end));
ary[ary_idx++] = parser.AsInt();
parser.Parse(bry, bgn, end); if (parser.Has_err() || parser.Has_frac()) throw Err_.new_fmt_("failed to parse number: {0}", String_.new_utf8_(bry, bgn, end));
ary[ary_idx++] = parser.Rv_as_int();
}
public static final Int_ary_parser _ = new Int_ary_parser();
}

View File

@@ -1,89 +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.*;
public class NumberParser_tst {
private NumberParser parser = new NumberParser();
@Test public void Integer() {
tst_Int("1", 1);
tst_Int("1234", 1234);
tst_Int("1234567890", 1234567890);
tst_Int("-1234", -1234);
tst_Int("+1", 1);
tst_Int("00001", 1);
}
@Test public void Decimal() {
tst_Dec("1.23", DecimalAdp_.parse_("1.23"));
tst_Dec("1.023", DecimalAdp_.parse_("1.023"));
tst_Dec("-1.23", DecimalAdp_.parse_("-1.23"));
}
@Test public void Double_long() {
tst_Dec(".42190046219457", DecimalAdp_.parse_(".42190046219457"));
}
@Test public void Exponent() {
tst_Int("1E2", 100);
tst_Dec("1.234E2", DecimalAdp_.parse_("123.4"));
tst_Dec("1.234E-2", DecimalAdp_.parse_(".01234"));
tst_Dec("123.4E-2", DecimalAdp_.parse_("1.234"));
tst_Dec("+6.0E-3", DecimalAdp_.parse_(".006"));
}
@Test public void Err() {
tst_Err("+", true);
tst_Err("-", true);
tst_Err("a", true);
tst_Err("1-2", false);
tst_Err("1..1", true);
tst_Err("1,,1", true);
tst_Err("1", false);
}
@Test public void Hex() {
Hex_tst("0x1" , 1);
Hex_tst("0xF" , 15);
Hex_tst("0x20" , 32);
Hex_tst("x20" , 0, false);
Hex_tst("d" , 0, false); // PURPOSE: d was being converted to 13; no.w:Hovedbanen; DATE:2014-04-13
}
private void tst_Int(String raw, int expd) {
byte[] raw_bry = Bry_.new_ascii_(raw);
int actl = parser.Parse(raw_bry, 0, raw_bry.length).AsInt();
Tfds.Eq(expd, actl, raw);
}
private void tst_Dec(String raw, DecimalAdp expd) {
byte[] raw_bry = Bry_.new_ascii_(raw);
DecimalAdp actl = parser.Parse(raw_bry, 0, raw_bry.length).AsDec();
Tfds.Eq(expd.Xto_decimal(), actl.Xto_decimal(), raw);
}
private void tst_Err(String raw, boolean expd) {
byte[] raw_bry = Bry_.new_ascii_(raw);
boolean actl = parser.Parse(raw_bry, 0, raw_bry.length).HasErr();
Tfds.Eq(expd, actl, raw);
}
private void Hex_tst(String raw, int expd_val) {Hex_tst(raw, expd_val, true);}
private void Hex_tst(String raw, int expd_val, boolean expd_pass) {
parser.Hex_enabled_(true);
byte[] raw_bry = Bry_.new_ascii_(raw);
int actl = parser.Parse(raw_bry, 0, raw_bry.length).AsInt();
if (expd_pass) {
Tfds.Eq(expd_val, actl, raw);
Tfds.Eq(true, !parser.HasErr());
}
else
Tfds.Eq(false, !parser.HasErr());
parser.Hex_enabled_(false);
}
}

View File

@@ -16,19 +16,24 @@ 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 NumberParser {
public int AsInt() {return (int)int_val;} long int_val = 0;
public DecimalAdp AsDec() {return dec_val == null ? DecimalAdp_.long_(int_val) : dec_val;} DecimalAdp dec_val = null;
public boolean HasErr() {return hasErr;} private boolean hasErr;
public boolean HasFrac() {return hasFrac;} private boolean hasFrac;
public boolean Hex_enabled() {return hex_enabled;} public NumberParser Hex_enabled_(boolean v) {hex_enabled = v; return this;} private boolean hex_enabled;
public NumberParser Parse(byte[] src) {return Parse(src, 0, src.length);}
public NumberParser Parse(byte[] ary, int bgn, int end) {
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 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;
public Number_parser Ignore_chars_(byte[] v) {this.ignore_chars = v; return this;} private byte[] ignore_chars;
public Number_parser Ignore_space_at_end_y_() {this.ignore_space_at_end = true; return this;} private boolean ignore_space_at_end;
public void Clear() {
ignore_chars = null;
}
public Number_parser Parse(byte[] src) {return Parse(src, 0, src.length);}
public Number_parser Parse(byte[] ary, int bgn, int end) {
int loop_bgn = end - 1, loop_end = bgn - 1, exp_multiplier = 1, factor = 10;
long multiplier = 1, frc_multiplier = 1;
int_val = 0; dec_val = null; boolean comma_nil = true;
long frc_int = 0;
hasErr = false; hasFrac = false; boolean has_exp = false, has_neg = false, exp_neg = false, has_plus = false, has_num = false;
has_err = false; has_frac = false; boolean has_exp = false, has_neg = false, exp_neg = false, has_plus = false, has_num = false;
boolean input_is_hex = false;
if (hex_enabled) {
if (loop_end + 2 < end) { // ArrayOutOfBounds check
@@ -64,30 +69,31 @@ public class NumberParser {
has_num = true;
break;
case Byte_ascii.Dot:
if (hasFrac) return IsErr_();
if (has_frac) return Has_err_y_();
frc_int = int_val;
int_val = 0;
frc_multiplier = multiplier;
multiplier = 1;
hasFrac = true;
has_frac = true;
break;
case Byte_ascii.Comma:
if (comma_nil)
comma_nil = false;
else
return IsErr_();
return Has_err_y_();
break;
case Byte_ascii.Dash:
if (has_neg) return IsErr_();
if (has_neg) return Has_err_y_();
has_neg = true;
break;
case Byte_ascii.Space:
if (i == bgn) {} // space at bgn
if (i == bgn) {} // space at bgn
else if (i == end - 1 && ignore_space_at_end) {} // ignore space at end; DATE:2015-04-29
else
return IsErr_();
return Has_err_y_();
break;
case Byte_ascii.Plus:
if (has_plus) return IsErr_();
if (has_plus) return Has_err_y_();
has_plus = true;
break;
case Byte_ascii.Ltr_e:
@@ -98,7 +104,7 @@ public class NumberParser {
has_num = true;
}
else {
if (has_exp) return IsErr_();
if (has_exp) return Has_err_y_();
exp_neg = has_neg;
exp_multiplier = (int)Math_.Pow(10, int_val);
int_val = 0;
@@ -119,7 +125,7 @@ public class NumberParser {
has_num = true;
}
else
return IsErr_();
return Has_err_y_();
break;
case Byte_ascii.Ltr_a:
case Byte_ascii.Ltr_b:
@@ -132,20 +138,31 @@ public class NumberParser {
has_num = true;
}
else
return IsErr_();
return Has_err_y_();
break;
case Byte_ascii.Ltr_x:
case Byte_ascii.Ltr_X:
if (input_is_hex)
return (factor == 16) ? this : IsErr_(); // check for '0x'
return (factor == 16) ? this : Has_err_y_(); // check for '0x'
else
return IsErr_();
return Has_err_y_();
default:
return IsErr_();
if (ignore_chars != null) {
int ignore_chars_len = ignore_chars.length;
boolean ignored = false;
for (int j = 0; j < ignore_chars_len; ++j) {
if (cur == ignore_chars[j]) {
ignored = true;
break;
}
}
if (ignored) continue;
}
return Has_err_y_();
}
}
if (!has_num) return IsErr_(); // handles situations wherein just symbols; EX: "+", ".", "-.", " , " etc.
if (hasFrac) {
if (!has_num) return Has_err_y_(); // handles situations wherein just symbols; EX: "+", ".", "-.", " , " etc.
if (has_frac) {
long full_val = (((int_val * frc_multiplier) + frc_int));
if (has_neg) full_val *= -1;
if (has_exp) {
@@ -160,5 +177,5 @@ public class NumberParser {
}
return this;
}
NumberParser IsErr_() {hasErr = true; return this;}
private Number_parser Has_err_y_() {has_err = true; return this;}
}

View File

@@ -0,0 +1,103 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
import org.junit.*;
public class Number_parser_tst {
private final Number_parser_fxt fxt = new Number_parser_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Integer() {
fxt.Test_int("1", 1);
fxt.Test_int("1234", 1234);
fxt.Test_int("1234567890", 1234567890);
fxt.Test_int("-1234", -1234);
fxt.Test_int("+1", 1);
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"));
}
@Test public void Double_long() {
fxt.Test_dec(".42190046219457", DecimalAdp_.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"));
}
@Test public void Err() {
fxt.Test_err("+", true);
fxt.Test_err("-", true);
fxt.Test_err("a", true);
fxt.Test_err("1-2", false);
fxt.Test_err("1..1", true);
fxt.Test_err("1,,1", true);
fxt.Test_err("1", false);
}
@Test public void Hex() {
fxt.Test_hex("0x1" , 1);
fxt.Test_hex("0xF" , 15);
fxt.Test_hex("0x20" , 32);
fxt.Test_hex("x20" , 0, false);
fxt.Test_hex("d" , 0, false); // PURPOSE: d was being converted to 13; no.w:Hovedbanen; DATE:2014-04-13
}
@Test public void Ignore() {
fxt.Init_ignore("\n\t");
fxt.Test_int("1" , 1);
fxt.Test_int("1\n" , 1);
fxt.Test_int("1\t" , 1);
fxt.Test_int("1\n2" , 12);
fxt.Test_err("1\r" , true);
}
}
class Number_parser_fxt {
private final Number_parser parser = new Number_parser();
public void Clear() {parser.Clear();}
public void Init_ignore(String chars) {parser.Ignore_chars_(Bry_.new_ascii_(chars));}
public void Test_int(String raw, int expd) {
byte[] raw_bry = Bry_.new_ascii_(raw);
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) {
byte[] raw_bry = Bry_.new_ascii_(raw);
DecimalAdp actl = parser.Parse(raw_bry, 0, raw_bry.length).Rv_as_dec();
Tfds.Eq(expd.Xto_decimal(), actl.Xto_decimal(), raw);
}
public void Test_err(String raw, boolean expd) {
byte[] raw_bry = Bry_.new_ascii_(raw);
boolean actl = parser.Parse(raw_bry, 0, raw_bry.length).Has_err();
Tfds.Eq(expd, actl, raw);
}
public void Test_hex(String raw, int expd_val) {Test_hex(raw, expd_val, true);}
public void Test_hex(String raw, int expd_val, boolean expd_pass) {
parser.Hex_enabled_(true);
byte[] raw_bry = Bry_.new_ascii_(raw);
int actl = parser.Parse(raw_bry, 0, raw_bry.length).Rv_as_int();
if (expd_pass) {
Tfds.Eq(expd_val, actl, raw);
Tfds.Eq(true, !parser.Has_err());
}
else
Tfds.Eq(false, !parser.Has_err());
parser.Hex_enabled_(false);
}
}

View File

@@ -22,7 +22,7 @@ public class Url_encoder implements Url_encoder_interface {
private Url_encoder_itm[] encode_ary = new Url_encoder_itm[256], decode_ary = new Url_encoder_itm[256];
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
private Url_encoder anchor_encoder = null;
private Object thread_guard = new Object();
private Object thread_lock = new Object();
public void Itms_ini(byte primary_encode_marker) {
Url_encoder_itm_hex hex = new Url_encoder_itm_hex(primary_encode_marker);
for (int i = 0; i < 256; i++) {
@@ -72,26 +72,26 @@ public class Url_encoder implements Url_encoder_interface {
return this;
}
public byte[] Encode_http(Io_url url) {
synchronized (thread_guard) {
synchronized (thread_lock) {
tmp_bfr.Add(Io_url.Http_file_bry);
Encode(tmp_bfr, url.RawBry());
return tmp_bfr.Xto_bry_and_clear();
}
}
public String Encode_str(String str) {
synchronized (thread_guard) {
synchronized (thread_lock) {
byte[] bry = Bry_.new_utf8_(str); Encode(tmp_bfr, bry, 0, bry.length); return tmp_bfr.Xto_str_and_clear();
}
}
public byte[] Encode_bry(String str) {
synchronized (thread_guard) {
synchronized (thread_lock) {
byte[] bry = Bry_.new_utf8_(str); Encode(tmp_bfr, bry, 0, bry.length); return tmp_bfr.Xto_bry_and_clear();
}
}
public byte[] Encode(byte[] bry) {Encode(tmp_bfr, bry, 0, bry.length); return tmp_bfr.Xto_bry_and_clear();}
public Bry_bfr Encode(Bry_bfr bfr, byte[] bry) {Encode(bfr, bry, 0, bry.length); return bfr;}
public void Encode(Bry_bfr bfr, byte[] bry, int bgn, int end) {
synchronized (thread_guard) {
synchronized (thread_lock) {
for (int i = bgn; i < end; i++) {
byte b = bry[i];
if (anchor_encoder != null && b == Byte_ascii.Hash) {
@@ -105,22 +105,22 @@ public class Url_encoder implements Url_encoder_interface {
}
}
public String Decode_str(String str) {
synchronized (thread_guard) {
synchronized (thread_lock) {
byte[] bry = Bry_.new_utf8_(str); Decode(bry, 0, bry.length, tmp_bfr, true); return tmp_bfr.Xto_str_and_clear();
}
}
public byte[] Decode(byte[] bry) {
synchronized (thread_guard) {
synchronized (thread_lock) {
Decode(bry, 0, bry.length, tmp_bfr, false); return tmp_bfr.Xto_bry_and_clear();
}
}
public byte[] Decode_lax(byte[] bry) {
synchronized (thread_guard) {
synchronized (thread_lock) {
Decode(bry, 0, bry.length, tmp_bfr, false); return tmp_bfr.Xto_bry_and_clear();
}
}
public void Decode(byte[] bry, int bgn, int end, Bry_bfr bfr, boolean fail_when_invalid) {
synchronized (thread_guard) {
synchronized (thread_lock) {
for (int i = bgn; i < end; i++) {
byte b = bry[i];
if (anchor_encoder != null && b == Byte_ascii.Hash) {