1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

v2.11.3.1

This commit is contained in:
gnosygnu
2015-11-15 21:08:17 -05:00
parent d9f45cec19
commit 8a5d58a973
418 changed files with 2694 additions and 1621 deletions

View File

@@ -0,0 +1,59 @@
/*
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.langs.gfs.*;
public class Bool_ implements GfoInvkAble {
public static final String Cls_val_name = "boolean";
public static final Class<?> Cls_ref_type = Boolean.class;
public static final boolean N = false , Y = true;
public static final byte N_byte = 0 , Y_byte = 1 , __byte = 127;
public static final int N_int = 0 , Y_int = 1 , __int = -1;
public static final byte[] N_bry = new byte[] {Byte_ascii.Ltr_n}, Y_bry = new byte[] {Byte_ascii.Ltr_y};
public static final String True_str = "true", False_str = "false";
public static final byte[] True_bry = Bry_.new_a7(True_str), False_bry = Bry_.new_a7(False_str);
public static boolean cast(Object obj) {try {return (Boolean)obj;} catch (Exception e) {throw Err_.new_type_mismatch_w_exc(e, boolean.class, obj);}}
public static boolean cast_or(Object obj, boolean v) {try {return (Boolean)obj;} catch (Exception e) {Err_.Noop(e); return v;}}
public static boolean parse(String raw) {
if ( String_.Eq(raw, True_str)
|| String_.Eq(raw, "True") // needed for Store_Wtr(){boolVal.toString();}
)
return true;
else if ( String_.Eq(raw, "false")
|| String_.Eq(raw, False_str)
)
return false;
throw Err_.new_parse_type(boolean.class, raw);
}
public static boolean By_int(int v) {return v == Y_int;}
public static int To_int(boolean v) {return v ? Y_int : N_int;}
public static byte To_byte(boolean v) {return v ? Y_byte : N_byte;}
public static String To_str_lower(boolean v) {return v ? True_str : False_str;}
public static final Bool_ Gfs = new Bool_();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_to_str)) {
boolean v = m.ReadBool(GfsCore_.Arg_primitive);
String fmt = m.ReadStrOr("fmt", null);
if (fmt == null) return v ? "true" : "false";
else if (String_.Eq(fmt, "yn")) return v ? "y" : "n";
else if (String_.Eq(fmt, "yes_no")) return v ? "yes" : "no";
else return v ? "true" : "false";
}
else return GfoInvkAble_.Rv_unhandled;
} public static final String Invk_to_str = "to_str";
}

View File

@@ -0,0 +1,55 @@
/*
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 Byte_ {
public static final String Cls_val_name = "byte";
public static final Class<?> Cls_ref_type = Byte.class;
public static final byte
Zero = 0
, Min_value = Byte.MIN_VALUE
, Max_value_127 = 127
;
public static byte cast(Object o) {try {return (Byte)o;} catch (Exception e) {throw Err_.new_type_mismatch_w_exc(e, byte.class, o);}}
public static byte parse(String raw) {return Byte.parseByte(raw);}
public static byte parse_or(String raw, byte or) {
if (raw == null) return or;
try {return parse(raw);}
catch (Exception e) {Err_.Noop(e); return or;}
}
public static byte By_int(int v) {return v > 127 ? (byte)(v - 256) : (byte)v;} // PERF?: (byte)(v & 0xff)
public static int To_int(byte v) {return v < 0 ? (int)v + 256 : v;}
public static String To_str(byte v) {return new Byte(v).toString();}
public static boolean In(byte v, byte... ary) {
for (byte itm : ary)
if (v == itm) return true;
return false;
}
public static int Compare(byte lhs, byte rhs) {
if (lhs == rhs) return CompareAble_.Same;
else if (lhs < rhs) return CompareAble_.Less;
else return CompareAble_.More;
}
public static byte[] Ary(byte... ary) {return ary;}
public static byte[] Ary_by_ints(int... ary) {
int ary_len = ary.length;
byte[] rv = new byte[ary_len];
for (int i = 0; i < ary_len; i++)
rv[i] = By_int(ary[i]);
return rv;
}
}

View File

@@ -0,0 +1,35 @@
/*
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 Byte__tst {
@Test public void int_() {
tst_int_( 0, 0);
tst_int_( 127, 127);
tst_int_( 128, 128); // NOTE: JAVA defines byte as -128 -> 127
tst_int_( 255, 255);
tst_int_( 256, 0); // NOTE: 256 will cast to 1; (byte)256 works same in both JAVA/.NET
} void tst_int_(int v, int expd) {Tfds.Eq((byte)expd, Byte_.By_int(v));} // WORKAROUND/JAVA: expd is of type int b/c java promotes numbers to ints
@Test public void To_int() {
tst_XtoInt( 0, 0);
tst_XtoInt( 127, 127);
tst_XtoInt( 128, 128);
tst_XtoInt( 255, 255);
tst_XtoInt( 256, 0);
} void tst_XtoInt(int v, int expd) {Tfds.Eq(expd, Byte_.To_int((byte)v));} // WORKAROUND/JAVA: v is of type int b/c java promotes numbers to ints
}

View File

@@ -0,0 +1,124 @@
/*
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 Byte_ascii {
public static final byte
Null = 0 , Backfeed = 8, Tab = 9
, Nl = 10, Formfeed = 12, Cr = 13
, Escape = 27
, Space = 32, Bang = 33, Quote = 34
, Hash = 35, Dollar = 36, Percent = 37, Amp = 38, Apos = 39
, Paren_bgn = 40, Paren_end = 41, Star = 42, Plus = 43, Comma = 44
, Dash = 45, Dot = 46, Slash = 47, Num_0 = 48, Num_1 = 49
, Num_2 = 50, Num_3 = 51, Num_4 = 52, Num_5 = 53, Num_6 = 54
, Num_7 = 55, Num_8 = 56, Num_9 = 57, Colon = 58, Semic = 59
, Lt = 60, Eq = 61, Gt = 62, Question = 63, At = 64
, Ltr_A = 65, Ltr_B = 66, Ltr_C = 67, Ltr_D = 68, Ltr_E = 69
, Ltr_F = 70, Ltr_G = 71, Ltr_H = 72, Ltr_I = 73, Ltr_J = 74
, Ltr_K = 75, Ltr_L = 76, Ltr_M = 77, Ltr_N = 78, Ltr_O = 79
, Ltr_P = 80, Ltr_Q = 81, Ltr_R = 82, Ltr_S = 83, Ltr_T = 84
, Ltr_U = 85, Ltr_V = 86, Ltr_W = 87, Ltr_X = 88, Ltr_Y = 89
, Ltr_Z = 90, Brack_bgn = 91, Backslash = 92, Brack_end = 93, Pow = 94 // Circumflex
, Underline = 95, Tick = 96, Ltr_a = 97, Ltr_b = 98, Ltr_c = 99
, Ltr_d = 100, Ltr_e = 101, Ltr_f = 102, Ltr_g = 103, Ltr_h = 104
, Ltr_i = 105, Ltr_j = 106, Ltr_k = 107, Ltr_l = 108, Ltr_m = 109
, Ltr_n = 110, Ltr_o = 111, Ltr_p = 112, Ltr_q = 113, Ltr_r = 114
, Ltr_s = 115, Ltr_t = 116, Ltr_u = 117, Ltr_v = 118, Ltr_w = 119
, Ltr_x = 120, Ltr_y = 121, Ltr_z = 122, Curly_bgn = 123, Pipe = 124
, Curly_end = 125, Tilde = 126
;
public static final byte
Angle_bgn = Lt, Angle_end = Gt
;
public static final byte Max_7_bit = (byte)127, Ascii_min = 0, Ascii_max = 127;
public static boolean Is_sym(byte b) {
switch (b) {
case Byte_ascii.Bang: case Byte_ascii.Quote:
case Byte_ascii.Hash: case Byte_ascii.Dollar: case Byte_ascii.Percent: case Byte_ascii.Amp: case Byte_ascii.Apos:
case Byte_ascii.Paren_bgn: case Byte_ascii.Paren_end: case Byte_ascii.Star: case Byte_ascii.Plus: case Byte_ascii.Comma:
case Byte_ascii.Dash: case Byte_ascii.Dot: case Byte_ascii.Slash:
case Byte_ascii.Colon: case Byte_ascii.Semic:
case Byte_ascii.Lt: case Byte_ascii.Eq: case Byte_ascii.Gt: case Byte_ascii.Question: case Byte_ascii.At:
case Byte_ascii.Brack_bgn: case Byte_ascii.Backslash: case Byte_ascii.Brack_end: case Byte_ascii.Pow:
case Byte_ascii.Underline: case Byte_ascii.Tick:
case Byte_ascii.Curly_bgn: case Byte_ascii.Pipe:
case Byte_ascii.Curly_end: case Byte_ascii.Tilde:
return true;
default:
return false;
}
}
public static boolean Is_ltr(byte b) {
return ( b >= Byte_ascii.Ltr_a && b <= Byte_ascii.Ltr_z
|| b >= Byte_ascii.Ltr_A && b <= Byte_ascii.Ltr_Z);
}
public static boolean Is_ws(byte b) {
switch (b) {
case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Space: return true;
default: return false;
}
}
public static boolean Is_num(byte b) {
return b > Byte_ascii.Slash && b < Byte_ascii.Colon;
}
public static byte To_a7_int(byte b) {return (byte)(b - Byte_ascii.Num_0);}
public static byte To_a7_str(int digit) {
switch (digit) {
case 0: return Byte_ascii.Num_0; case 1: return Byte_ascii.Num_1; case 2: return Byte_ascii.Num_2; case 3: return Byte_ascii.Num_3; case 4: return Byte_ascii.Num_4;
case 5: return Byte_ascii.Num_5; case 6: return Byte_ascii.Num_6; case 7: return Byte_ascii.Num_7; case 8: return Byte_ascii.Num_8; case 9: return Byte_ascii.Num_9;
default: throw Err_.new_("Byte_ascii", "unknown digit", "digit", digit);
}
}
public static String To_str(byte b) {return Char_.To_str((char)b);}
public static byte Case_upper(byte b) {
return b > 96 && b < 123
? (byte)(b - 32)
: b;
}
public static byte Case_lower(byte b) {
return b > 64 && b < 91
? (byte)(b + 32)
: b;
}
public static final byte[] Space_len2 = new byte[] {Space, Space}, Space_len4 = new byte[] {Space, Space, Space, Space};
public static final byte[]
Tab_bry = new byte[] {Byte_ascii.Tab}
, Nl_bry = new byte[] {Byte_ascii.Nl}
, Space_bry = new byte[] {Byte_ascii.Space}
, Bang_bry = new byte[] {Byte_ascii.Bang}
, Quote_bry = new byte[] {Byte_ascii.Quote}
, Hash_bry = new byte[] {Byte_ascii.Hash}
, Dot_bry = new byte[] {Byte_ascii.Dot}
, Angle_bgn_bry = new byte[] {Byte_ascii.Angle_bgn}
, Angle_end_bry = new byte[] {Byte_ascii.Angle_end}
, Comma_bry = new byte[] {Byte_ascii.Comma}
, Colon_bry = new byte[] {Byte_ascii.Colon}
, Eq_bry = new byte[] {Byte_ascii.Eq}
, Amp_bry = new byte[] {Byte_ascii.Amp}
, Lt_bry = new byte[] {Byte_ascii.Lt}
, Gt_bry = new byte[] {Byte_ascii.Gt}
, Brack_bgn_bry = new byte[] {Byte_ascii.Brack_bgn}
, Brack_end_bry = new byte[] {Byte_ascii.Brack_end}
, Apos_bry = new byte[] {Byte_ascii.Apos}
, Pipe_bry = new byte[] {Byte_ascii.Pipe}
, Underline_bry = new byte[] {Byte_ascii.Underline}
, Slash_bry = new byte[] {Byte_ascii.Slash}
, Asterisk_bry = new byte[] {Byte_ascii.Star}
, Dash_bry = new byte[] {Byte_ascii.Dash}
;
}

View File

@@ -0,0 +1,73 @@
/*
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 Char_ {
public static final Class<?> Cls_ref_type = Character.class;
public static final char Null = '\0', NewLine = '\n';
public static boolean IsCaseLower(char c) {return Character.isLowerCase(c);}
public static boolean IsLetterOrDigit(char c) {return Character.isLetterOrDigit(c);}
public static boolean IsLetterEnglish(char c) {
switch (c) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': return true;
default: return false;
}
}
public static boolean IsLetterLowerEnglish(char c) {
switch (c) {
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': return true;
default: return false;
}
}
public static boolean IsNumber(char c) {
switch (c) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return true;
default: return false;
}
}
public static boolean IsWhitespace(char c) {
switch (c) {
case ' ': case '\t': case '\n': case '\r': return true;
default: return false;
}
}
public static boolean In(char match, char... ary) {
for (char itm : ary)
if (itm == match) return true;
return false;
}
public static int To_int_or(char c, int or) {
switch (c) {
case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4;
case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9;
default: return or;
}
}
public static String To_str(char[] ary, int pos, int length) {return new String(ary, pos, length);}
public static String To_str(int b) {return To_str((char)b);}
public static String To_str(char c) {return String.valueOf(c);}
public static char By_int(int i) {return (char)i;}
public static char cast(Object o) {try {return (Character)o;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, char.class, o);}}
public static char parse(String raw) {try {return raw.charAt(0);} catch(Exception exc) {throw Err_.new_parse_exc(exc, char.class, raw);}}
}

View File

@@ -0,0 +1,54 @@
/*
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 Double_ {
public static final String Cls_val_name = "double";
public static final Class<?> Cls_ref_type = Double.class;
public static final double
MinValue = Double.MIN_VALUE
, NaN = Double.NaN
, Inf_pos = Double.POSITIVE_INFINITY
;
public static final byte[]
NaN_bry = Bry_.new_a7("NaN")
, Inf_pos_bry = Bry_.new_a7("INF")
;
public static boolean IsNaN(double v) {return Double.isNaN(v);}
public static double cast(Object o) {try {return (Double)o;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, double.class, o);}}
public static double parse(String raw) {try {return Double.parseDouble(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, double.class, raw);}}
public static double parse_or(String raw, double v) {try {return Double.parseDouble(raw);} catch(Exception e) {Err_.Noop(e); return v;}}
public static double coerce_(Object v) {
try {String s = String_.as_(v); return s == null ? Double_.cast(v) : Double_.parse(s);}
catch (Exception e) {throw Err_.new_cast(e, double.class, v);}
}
public static String To_str(double v) {
int v_int = (int)v;
return v - v_int == 0 ? Int_.To_str(v_int) : Double.toString(v);
}
public static String To_str_loose(double v) {
int v_as_int = (int)v;
return v == v_as_int
? Int_.To_str(v_as_int) // convert to int, and call print String to eliminate any trailing decimal places
: Float_.To_str((float)v); // calling ((float)v).toString is better at removing trailing 0s than String.format("%g", v). note that .net .toString() handles it better; EX:2449.600000000000d; DATE:2014-07-29
}
public static int Compare(double lhs, double rhs) {
if (lhs == rhs) return CompareAble_.Same;
else if (lhs < rhs) return CompareAble_.Less;
else return CompareAble_.More;
}
}

View 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;
import org.junit.*;
public class Double__tst {
private Double__fxt fxt = new Double__fxt();
@Test public void Xto_str_loose() {
fxt.Test_Xto_str_loose(2449.6000000d , "2449.6");
fxt.Test_Xto_str_loose(623.700d , "623.7");
}
}
class Double__fxt {
public void Test_Xto_str_loose(double v, String expd) {Tfds.Eq(expd, Double_.To_str_loose(v));}
}

103
100_core/src/gplx/Env_.java Normal file
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 gplx.core.threads.*;
public class Env_ {
public static void Init(String[] args, String appNameAndExt, Class<?> type) {
mode_testing = false;
mode_debug = String_.In("GPLX_DEBUG_MODE_ENABLED", args);
appArgs = args;
appUrl = JarAdp_.Url_type(type).OwnerDir().GenSubFil(appNameAndExt);
}
public static void Init_swt(String[] args, Class<?> type) { // DATE:2014-06-23
mode_testing = false;
mode_debug = String_.In("GPLX_DEBUG_MODE_ENABLED", args);
appArgs = args;
appUrl = JarAdp_.Url_type(type);
}
public static void Init_drd() {
mode_testing = mode_debug = false;
}
public static void Init_testing() {mode_testing = true;}
public static void Init_testing_n_() {mode_testing = false;}
public static boolean Mode_testing() {return mode_testing;} static boolean mode_testing = true;
public static boolean Mode_debug() {return mode_debug;} static boolean mode_debug = false;
public static String[] AppArgs() {return appArgs;} static String[] appArgs;
public static Io_url AppUrl() {
if (mode_testing) return Io_url_.mem_fil_("mem/testing.jar");
if (appUrl == Io_url_.Empty) throw Err_.new_wo_type("Env_.Init was not called");
return appUrl;
} static Io_url appUrl = Io_url_.Empty;
public static void Exit() {Exit_code(0);}
public static void Exit_code(int code) {System.exit(code);}
public static String UserName() {return System.getProperty("user.name");}
public static void GarbageCollect() {if (mode_testing) return; System.gc();}
public static long TickCount() {return TickCount_Test >= 0 ? TickCount_Test : System.currentTimeMillis();}
public static int TickCount_elapsed_in_sec(long time_bgn) {return (int)(Env_.TickCount() - time_bgn) / 1000;}
public static int TickCount_elapsed_in_frac(long time_bgn) {return (int)(Env_.TickCount() - time_bgn);}
public static long TickCount_Test = -1; // in milliseconds
public static void TickCount_normal() {TickCount_Test = -1;}
public static long System_cpu_count() {return Runtime.getRuntime().availableProcessors();}
public static long System_memory_max() {return Runtime.getRuntime().maxMemory();}
public static long System_memory_total() {return Runtime.getRuntime().totalMemory();}
public static long System_memory_free() {return Runtime.getRuntime().freeMemory();}
public static final String LocalHost = "127.0.0.1";
public static String NewLine_lang() {return mode_testing ? "\n" : "\n";}
public static String GenHdr(boolean forSourceCode, String programName, String hdr_bgn, String hdr_end) {
String newLine = Op_sys.Lnx.Nl_str();
String lineEnd = Op_sys.Lnx.Nl_str();
String codeBgn = forSourceCode ? "/*" + newLine : "";
String codeEnd = forSourceCode ? "*/" + newLine : "";
String codeHdr = forSourceCode ? "This file is part of {0}." + newLine + newLine : "";
String fmt = String_.Concat
( codeBgn
, codeHdr
, hdr_bgn
, "Copyright (c) 2012 gnosygnu@gmail.com", newLine
, newLine
, "This program is free software: you can redistribute it and/or modify", lineEnd
, "it under the terms of the GNU Affero General Public License as", lineEnd
, "published by the Free Software Foundation, either version 3 of the", lineEnd
, "License, or (at your option) any later version.", newLine
, newLine
, "This program is distributed in the hope that it will be useful,", lineEnd
, "but WITHOUT ANY WARRANTY; without even the implied warranty of", lineEnd
, "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the", lineEnd
, "GNU Affero General Public License for more details.", newLine
, newLine
, "You should have received a copy of the GNU Affero General Public License", lineEnd
, "along with this program. If not, see <http://www.gnu.org/licenses/>.", newLine
, codeEnd
, hdr_end
);
return String_.Format(fmt, programName);
}
public static String Env_prop__user_language() {return Env_prop(Env_prop_key__user_language);}
public static String Env_prop__java_version() {return Env_prop(Env_prop_key__java_version);}
public static String Env_prop(String key) {
return System.getProperty(key);
}
private static final String
Env_prop_key__user_language = "user.language"
, Env_prop_key__java_version = "java.version"
;
public static void Term_add(GfoInvkAble invk, String cmd) {
Thread_adp thread = Thread_adp_.invk_(invk, cmd);
Runtime.getRuntime().addShutdownHook(thread.Under_thread());
}
}

View File

@@ -25,6 +25,7 @@ public class Err extends RuntimeException {
this.trace = is_gplx ? Err_.Trace_lang(this) : trace; // NOTE: Err_ factory methods pass in null stack trace for gplx excs; call Stack_trace here, note that trace will not show constructor
Msgs_add(type, msg, args);
}
public boolean Logged() {return logged;} public Err Logged_y_() {logged = true; return this;} private boolean logged;
public int Trace_ignore() {return trace_ignore;} public Err Trace_ignore_add_1_() {++trace_ignore; return this;} private int trace_ignore = 0;
public Err Args_add(Object... args) {msgs_ary[msgs_idx - 1].Args_add(args); return this;} // i - 1 to get current
@gplx.Internal protected boolean Type_match(String type) {

View File

@@ -0,0 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
public class Float_ {
public static final String Cls_val_name = "float";
public static final Class<?> Cls_ref_type = Float.class;
public static final float NaN = Float.NaN;;
public static boolean IsNaN(float v) {return Float.isNaN(v);}
public static float cast(Object obj) {try {return (Float)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, float.class, obj);}}
public static float parse(String raw) {try {return Float.parseFloat(raw);} catch(Exception exc) {throw Err_.new_parse_exc(exc, float.class, raw);}}
public static String To_str(float v) {
int v_int = (int)v;
return v - v_int == 0 ? Int_.To_str(v_int) : Float.toString(v);
}
public static float Div(int val, int divisor) {return (float)val / (float)divisor;}
public static float Div(long val, long divisor) {return (float)val / (float)divisor;}
public static int RoundUp(float val) {
int rv = (int)val;
return (rv == val) ? rv : rv + 1;
}
}

View File

@@ -0,0 +1,65 @@
/*
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 GfsCtx {
public Ordered_hash Vars() {return vars;} Ordered_hash vars = Ordered_hash_.New();
public boolean Fail_if_unhandled() {return fail_if_unhandled;} public GfsCtx Fail_if_unhandled_(boolean v) {fail_if_unhandled = v; return this;} private boolean fail_if_unhandled;
public Gfo_usr_dlg Usr_dlg() {return usr_dlg;} public GfsCtx Usr_dlg_(Gfo_usr_dlg v) {usr_dlg = v; return this;} Gfo_usr_dlg usr_dlg;
public boolean Help_browseMode() {return help_browseMode;} public GfsCtx Help_browseMode_(boolean v) {help_browseMode = v; return this;} private boolean help_browseMode;
public List_adp Help_browseList() {return help_browseList;} List_adp help_browseList = List_adp_.new_();
public Object MsgSrc() {return msgSrc;} public GfsCtx MsgSrc_(Object v) {msgSrc = v; return this;} Object msgSrc;
public boolean Match(String k, String match) {
if (help_browseMode) {
help_browseList.Add(match);
return false;
}
else
return String_.Eq(k, match);
}
public boolean MatchPriv(String k, String match) {return help_browseMode ? false : String_.Eq(k, match);}
public boolean MatchIn(String k, String... match) {
if (help_browseMode) {
for (String i : match)
help_browseList.Add(i);
return false;
}
return String_.In(k, match);
}
public boolean Write_note(String fmt, Object... ary) {UsrDlg_.Instance.Note(fmt, ary); return false;}
public boolean Write_warn(String fmt, Object... ary) {UsrDlg_.Instance.Note("! " + fmt, ary); return false;}
public boolean Write_stop(UsrMsg umsg) {UsrDlg_.Instance.Note("* " + umsg.To_str()); return false;}
public boolean Write_stop(String fmt, Object... ary) {UsrDlg_.Instance.Note("* " + fmt, ary); return false;}
public boolean Deny() {return deny;} private boolean deny;
public static final GfsCtx Instance = new GfsCtx();
public static GfsCtx new_() {return new GfsCtx();} GfsCtx() {}
public static GfsCtx rdr_() {
GfsCtx rv = new GfsCtx();
rv.deny = true;
rv.mode = "read";
return rv;
}
public static GfsCtx wtr_() {
GfsCtx rv = new GfsCtx();
rv.deny = true;
rv.mode = Mode_write;
return rv;
}
public String Mode() {return mode;} public GfsCtx Mode_(String v) {mode = v; return this;} private String mode = "regular";
public static final String Mode_write = "write";
public static final int Ikey_null = -1;
}

260
100_core/src/gplx/Int_.java Normal file
View File

@@ -0,0 +1,260 @@
/*
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.core.strings.*; import gplx.langs.gfs.*;
public class Int_ implements GfoInvkAble {
public static final String Cls_val_name = "int";
public static final Class<?> Cls_ref_type = Integer.class;
public static final int Base1 = 1;
public static final int Const_dlm_len = 1;
public static final int Const_position_after_char = 1;
public static final int Null = Int_.Min_value;
public static int coerce_(Object v) {
try {String s = String_.as_(v); return s == null ? Int_.cast(v) : Int_.parse(s);}
catch (Exception e) {throw Err_.new_cast(e, int.class, v);}
}
public static int[] Ary_empty = new int[0];
public static int[] Ary(int... v) {return v;}
public static int[] Ary_copy(int[] ary) {return Ary_copy(ary, ary.length);}
public static int[] Ary_copy(int[] ary, int new_len) {
int old_len = ary.length;
int[] rv = new int[new_len];
for (int i = 0; i < old_len; i++)
rv[i] = ary[i];
return rv;
}
public static void Ary_copy_to(int[] src, int src_len, int[] trg) {
for (int i = 0; i < src_len; ++i)
trg[i] = src[i];
}
public static int[] AryRng(int bgn, int end) {
int len = end - bgn + 1;
int[] rv = new int[len];
for (int i = 0; i < len; i++)
rv[i] = bgn + i;
return rv;
}
public static boolean Bounds_chk(int bgn, int end, int len) {return bgn > -1 && end < len;}
public static int parse_or(String raw, int or) {
if (raw == null) return or;
int rawLen = String_.Len(raw); if (rawLen == 0) return or;
int rv = 0, tmp = 0, factor = 1;
for (int i = rawLen; i > 0; i--) {
char c = String_.CharAt(raw, i - 1);
switch (c) {
case '0': tmp = 0; break; case '1': tmp = 1; break; case '2': tmp = 2; break; case '3': tmp = 3; break; case '4': tmp = 4; break;
case '5': tmp = 5; break; case '6': tmp = 6; break; case '7': tmp = 7; break; case '8': tmp = 8; break; case '9': tmp = 9; break;
case '-': rv *= -1; continue; // NOTE: note continue
default: return or;
}
rv += (tmp * factor);
factor *= 10;
}
return rv;
}
public static int EnsureLessThan(int v, int max) {return v >= max ? max : v;}
public static boolean In(int v, int comp0, int comp1) {return v == comp0 || v == comp1;}
public static boolean In(int v, int... ary) {
for (int itm : ary)
if (v == itm) return true;
return false;
}
public static int BoundEnd(int v, int end) {return v >= end ? end - 1 : v;}
public static int Min(int lhs, int rhs) {return lhs < rhs ? lhs : rhs;}
public static int Max(int lhs, int rhs) {return lhs > rhs ? lhs : rhs;}
public static int ModIfNeg1(int v, int or) {return v == -1 ? or : v;}
public static boolean RangeCheck(int v, int max) {return v >= 0 && v < max;}
public static void RangeCheckOrFail_list(int v, int max, String s) {if (v < 0 || v >= max) throw Err_.new_wo_type("bounds check failed", "msg", s, "v", v, "min", 0, "max", max - 1);}
public static void RangeCheckOrFail(int v, int min, int max, String s) {if (v < min || v >= max) throw Err_.new_wo_type("bounds check failed", "msg", s, "v", v, "min", min, "max", max);}
public static boolean Between(int v, int lhs, int rhs) {
int lhsCompare = v == lhs ? 0 : (v < lhs ? -1 : 1);
int rhsCompare = v == rhs ? 0 : (v < rhs ? -1 : 1);
return (lhsCompare * rhsCompare) != 1; // 1 when v is (a) greater than both or (b) less than both
}
public static int Div(int v, float divisor) {return (int)((float)v / divisor);}
public static int DivAndRoundUp(int v, int divisor) {
int whole = v / divisor;
int partial = v % divisor == 0 ? 0 : 1;
return whole + partial;
}
public static int Mult(int v, float multiplier) {
float product = ((float)v * multiplier); // WORKAROUND (DotNet): (int)((float)v * multiplier) returns 0 for 100 and .01f
return (int)product;
}
public static int Compare(int lhs, int rhs) {
if (lhs == rhs) return CompareAble_.Same;
else if (lhs < rhs) return CompareAble_.Less;
else return CompareAble_.More;
}
public static int DigitCount(int v) {
int log10 = Log10(v);
return v > -1 ? log10 + 1 : log10 * -1 + 2;
}
public static int Log10(int v) {
if (v == 0) return 0;
int sign = 1;
if (v < 0) {
if (v == Int_.Min_value) return -9; // NOTE: Int_.Min_value * -1 = Int_.Min_value
v *= -1;
sign = -1;
}
int rv = Log10AryLen - 2; // rv will only happen when v == Int_.Max_value
int bgn = 0;
if (v > 1000) { // optimization to reduce number of ops to < 5
bgn = 3;
if (v > 1000000) bgn = 6;
}
for (int i = bgn; i < Log10AryLen; i++) {
if (v < Log10Ary[i]) {rv = i - 1; break;}
}
return rv * sign;
} public static int[] Log10Ary = new int[] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, Int_.Max_value}; public static int Log10AryLen = 11;
public Int_ FailIfNeg1(String key, int val) {
if (val < 0) throw Err_.new_wo_type("key must be >= 0", "key", key, "val", val);
return this;
}
public static String To_str_pad_bgn_space(int v, int reqdPlaces) {return To_str_pad_bgn_zero(v, reqdPlaces, Byte_ascii.Space, true);} // EX: 1, 3 returns " 1"
public static String To_str_pad_bgn_zero(int v, int reqdPlaces) {return To_str_pad_bgn_zero(v, reqdPlaces, Byte_ascii.Num_0, true);} // EX: 1, 3 returns "001"
static String To_str_pad_bgn_zero(int val, int places, byte pad_chr, boolean bgn) {
int len = DigitCount(val);
int pad_len = places - len; if (pad_len < 0) return Int_.To_str(val);
Bry_bfr bfr = Bry_bfr.new_();
boolean neg = val < 0;
if (bgn) { // special logic to handle negative numbers; EX: -1 -> "-001", not "00-1"
if (neg) {
bfr.Add_byte(Byte_ascii.Dash);
val *= -1;
--len;
}
}
else
bfr.Add_int_fixed(val, len);
bfr.Add_byte_repeat(pad_chr, pad_len);
if (bgn) bfr.Add_int_fixed(val, len); // NOTE: neg handled above
return bfr.To_str();
}
public static int read_(Object o) {String s = String_.as_(o); return s != null ? Int_.parse(s) : Int_.cast(o);}
public static int parse(String raw) {try {return Integer.parseInt(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, int.class, raw);}}
public static int cast(Object obj) {try {return (Integer)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, int.class, obj);}}
public static int cast_or(Object obj, int or) {try {return (Integer)obj;} catch(Exception e) {Err_.Noop(e); return or;}}
public static int Xby_double_(double v) {return (int)v;}
public static String To_str(int v) {return new Integer(v).toString();}
public static String To_str_fmt(int v, String fmt) {return new java.text.DecimalFormat(fmt).format(v);}
public static boolean TypeMatch(Class<?> type) {return type == int.class || type == Integer.class;}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_XtoStr_PadBgn)) {
int v = m.ReadInt(GfsCore_.Arg_primitive), pad = m.ReadInt("pad");
return ctx.Deny() ? (Object)this : To_str_pad_bgn_zero(v, pad);
}
else if (ctx.Match(k, "Add")) {
int v = m.ReadInt(GfsCore_.Arg_primitive), operand = m.ReadInt("operand");
return ctx.Deny() ? (Object)this : v + operand;
}
else return GfoInvkAble_.Rv_unhandled;
} public static final String Invk_XtoStr_PadBgn = "XtoStr_PadBgn";
public static final Int_ Gfs = new Int_();
public static int To_int_hex(byte[] src) {return To_int_hex(src, 0, src.length);}
public static int To_int_hex(byte[] src, int bgn, int end) {
int rv = 0; int factor = 1;
for (int i = end - 1; i >= bgn; i--) {
int val = To_int_hex(src[i]);
rv += (val * factor);
factor *= 16;
}
return rv;
}
public static int To_int_hex(byte b) {
switch (b) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
return b - Byte_ascii.Num_0;
case Byte_ascii.Ltr_A: case Byte_ascii.Ltr_B: case Byte_ascii.Ltr_C: case Byte_ascii.Ltr_D: case Byte_ascii.Ltr_E: case Byte_ascii.Ltr_F:
return b - Byte_ascii.Ltr_A + 10;
case Byte_ascii.Ltr_a: case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_e: case Byte_ascii.Ltr_f:
return b - Byte_ascii.Ltr_a + 10;
default:
return -1;
}
}
public static String To_str_hex(int v) {return To_str_hex(Bool_.Y, Bool_.Y, v);}
public static String To_str_hex(boolean zero_pad, boolean upper, int v) {
String rv = Integer.toHexString(v);
int rv_len = String_.Len(rv);
if (zero_pad && rv_len < 8) rv = String_.Repeat("0", 8 - rv_len) + rv;
return upper ? String_.Upper(rv) : rv;
}
public static String To_str(int[] ary) {return To_str(ary, " ");}
public static String To_str(int[] ary, String dlm) {
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < ary.length; i++)
sb.Add_spr_unless_first(Int_.To_str(ary[i]), dlm, i);
return sb.To_str();
}
public static int[] Ary_parse(String raw_str, int reqd_len, int[] or) {
byte[] raw_bry = Bry_.new_a7(raw_str);
int raw_bry_len = raw_bry.length;
int[] rv = new int[reqd_len];
int cur_val = 0, cur_mult = 1, cur_idx = reqd_len - 1; boolean signed = false;
for (int i = raw_bry_len - 1; i > -2; i--) {
byte b = i == -1 ? Byte_ascii.Comma : raw_bry[i];
switch (b) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
if (signed) return or;
cur_val += (b - Byte_ascii.Num_0) * cur_mult;
cur_mult *= 10;
break;
case Byte_ascii.Space: case Byte_ascii.Nl: case Byte_ascii.Cr: case Byte_ascii.Tab:
break;
case Byte_ascii.Comma:
if (cur_idx < 0) return or;
rv[cur_idx--] = cur_val;
cur_val = 0; cur_mult = 1;
signed = false;
break;
case Byte_ascii.Dash:
if (signed) return or;
cur_val *= -1;
signed = true;
break;
case Byte_ascii.Plus: // noop; all values positive by default
if (signed) return or;
signed = true;
break;
default:
return or;
}
}
return cur_idx == -1 ? rv : or; // cur_idx == -1 checks for unfilled; EX: Ary_parse("1,2", 3, null) is unfilled
}
public static int[] Ary_parse(String raw_str, String spr) {
String[] ary = String_.Split(raw_str, spr);
int len = ary.length;
int[] rv = new int[len];
for (int i = 0; i < len; i++)
rv[i] = Int_.parse(ary[i]);
return rv;
}
public static byte[] To_bry(int v) {return Bry_.new_a7(To_str(v));}
public static final int
Min_value = Integer.MIN_VALUE
, Max_value = Integer.MAX_VALUE
, Neg1 = -1
, Neg1_count = -1
;
}

View File

@@ -0,0 +1,115 @@
/*
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 Int__tst {
@Test public void XtoStr_PadBgn() {
// tst_XtoStr_PadLeft_Zeroes(1 , 3, "001"); // pad
// tst_XtoStr_PadLeft_Zeroes(123 , 3, "123"); // no pad
// tst_XtoStr_PadLeft_Zeroes(1234 , 3, "1234"); // val exceeds pad; confirm noop
tst_XtoStr_PadLeft_Zeroes(-1 , 3, "-01"); // negative
tst_XtoStr_PadLeft_Zeroes(-12 , 3, "-12"); // negative
tst_XtoStr_PadLeft_Zeroes(-123 , 3, "-123"); // negative
tst_XtoStr_PadLeft_Zeroes(-1234 , 3, "-1234"); // negative
} void tst_XtoStr_PadLeft_Zeroes(int val, int zeros, String expd) {Tfds.Eq(expd, Int_.To_str_pad_bgn_zero(val, zeros));}
@Test public void parseOr_() {
tst_ParseOr("", -1); // empty
tst_ParseOr("123", 123); // single
tst_ParseOr("1a", -1); // fail
} void tst_ParseOr(String raw, int expd) {Tfds.Eq(expd, Int_.parse_or(raw, -1));}
@Test public void Between() {
tst_Between(1, 0, 2, true); // simple true
tst_Between(3, 0, 2, false); // simple false
tst_Between(0, 0, 2, true); // bgn true
tst_Between(2, 0, 2, true); // end true
} void tst_Between(int val, int lhs, int rhs, boolean expd) {Tfds.Eq(expd, Int_.Between(val, lhs, rhs));}
@Test public void Xto_fmt() {
tst_XtoStr_fmt(1, "1");
tst_XtoStr_fmt(1000, "1,000");
} void tst_XtoStr_fmt(int v, String expd) {Tfds.Eq(expd, Int_.To_str_fmt(v, "#,###"));}
@Test public void AryRng() {
tst_AryRng(1, 3, Int_.Ary(1, 2, 3));
} void tst_AryRng(int bgn, int end, int[] expd) {Tfds.Eq_ary(expd, Int_.AryRng(bgn, end));}
@Test public void Log10_pos() {
tst_Log10(0, 0);
tst_Log10(1, 0);
tst_Log10(9, 0);
tst_Log10(10, 1);
tst_Log10(100, 2);
tst_Log10(1000000, 6);
tst_Log10(1000000000, 9);
tst_Log10(Int_.Max_value, 9);
}
@Test public void Log10_neg() {
tst_Log10(-1, 0);
tst_Log10(-10, -1);
tst_Log10(-100, -2);
tst_Log10(-1000000, -6);
tst_Log10(-1000000000, -9);
tst_Log10(Int_.Min_value, -9);
tst_Log10(Int_.Min_value + 1, -9);
}
void tst_Log10(int val, int expd) {Tfds.Eq(expd, Int_.Log10(val));}
@Test public void DigitCount() {
tst_DigitCount(0, 1);
tst_DigitCount(9, 1);
tst_DigitCount(100, 3);
tst_DigitCount(-1, 2);
tst_DigitCount(-100, 4);
} void tst_DigitCount(int val, int expd) {Tfds.Eq(expd, Int_.DigitCount(val), Int_.To_str(val));}
@Test public void Log10() {
tst_Log10( 0, 0);
tst_Log10( 1, 0);
tst_Log10( 2, 0);
tst_Log10( 10, 1);
tst_Log10( 12, 1);
tst_Log10( 100, 2);
tst_Log10( 123, 2);
tst_Log10( 1000, 3);
tst_Log10( 1234, 3);
tst_Log10( 10000, 4);
tst_Log10( 12345, 4);
tst_Log10( 100000, 5);
tst_Log10( 123456, 5);
tst_Log10( 1000000, 6);
tst_Log10( 1234567, 6);
tst_Log10( 10000000, 7);
tst_Log10( 12345678, 7);
tst_Log10( 100000000, 8);
tst_Log10( 123456789, 8);
tst_Log10( 1000000000, 9);
tst_Log10( 1234567890, 9);
tst_Log10(Int_.Max_value, 9);
}
@Test public void Xto_int_hex_tst() {
Xto_int_hex("007C", 124);
} void Xto_int_hex(String raw, int expd) {Tfds.Eq(expd, Int_.To_int_hex(Bry_.new_a7(raw)));}
@Test public void Ary_parse() {
Ary_parse__tst("1,2,3" , 3, Int_.Ary_empty, 1, 2, 3);
Ary_parse__tst("123,321,213" , 3, Int_.Ary_empty, 123, 321, 213);
Ary_parse__tst(" 1, 2,3" , 3, Int_.Ary_empty, 1, 2, 3);
Ary_parse__tst("-1,+2,-3" , 3, Int_.Ary_empty, -1, 2, -3);
Ary_parse__tst(Int_.To_str(Int_.Min_value) , 1, Int_.Ary_empty, Int_.Min_value);
Ary_parse__tst(Int_.To_str(Int_.Max_value) , 1, Int_.Ary_empty, Int_.Max_value);
Ary_parse__tst("1,2" , 1, Int_.Ary_empty);
Ary_parse__tst("1" , 2, Int_.Ary_empty);
Ary_parse__tst("a" , 1, Int_.Ary_empty);
Ary_parse__tst("1-2," , 1, Int_.Ary_empty);
}
void Ary_parse__tst(String raw, int reqd_len, int[] or, int... expd) {Tfds.Eq_ary(expd, Int_.Ary_parse(raw, reqd_len, or));}
}

View File

@@ -0,0 +1,95 @@
/*
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 Int_ary_ {
public static int[] Parse_list_or(byte[] src, int[] or) {
try {
if (Bry_.Len_eq_0(src)) return or; // null, "" should return [0]
int raw_len = src.length;
int[] rv = null; int rv_idx = 0, rv_len = 0;
int pos = 0;
int num_bgn = -1, num_end = -1;
boolean itm_done = false, itm_is_rng = false;
int rng_bgn = Int_.Min_value;
while (true) {
boolean pos_is_last = pos == raw_len;
if ( itm_done
|| pos_is_last
) {
if (num_bgn == -1) return or; // empty itm; EX: "1,"; "1,,2"
int num = Bry_.To_int_or(src, num_bgn, num_end, Int_.Min_value);
if (num == Int_.Min_value) return or; // not a number; parse failed
if (rv_len == 0) { // rv not init'd
rv_len = (raw_len / 2) + 1; // default rv_len to len of String / 2; + 1 to avoid fraction rounding down
rv = new int[rv_len];
}
int add_len = 1;
if (itm_is_rng) {
add_len = num - rng_bgn + List_adp_.Base1;
if (add_len == 0) return or; // bgn >= end;
}
if (add_len + rv_idx > rv_len) { // ary out of space; resize
rv_len = (add_len + rv_idx) * 2;
rv = (int[])Array_.Resize(rv, rv_len);
}
if (itm_is_rng) {
for (int i = rng_bgn; i <= num; i++)
rv[rv_idx++] = i;
}
else {
rv[rv_idx++] = num;
}
num_bgn = num_end = -1;
itm_done = itm_is_rng = false;
rng_bgn = Int_.Min_value;
if (pos_is_last) break;
}
byte b = src[pos];
switch (b) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
if (num_bgn == -1) // num_bgn not set
num_bgn = pos;
num_end = pos + 1; // num_end is always after pos; EX: "9": num_end = 1; "98,7": num_end=2
break;
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Nl: case Byte_ascii.Cr: // NOTE: parseNumList replaces ws with '', so "1 1" will become "11"
break;
case Byte_ascii.Comma:
if (pos == raw_len -1) return or; // eos; EX: "1,"
if (num_bgn == -1) return or; // empty itm; EX: ","; "1,,2"
itm_done = true;
break;
case Byte_ascii.Dash:
if (pos == raw_len -1) return or; // eos; EX: "1-"
if (num_bgn == -1) return or; // no rng_bgn; EX: "-2"
rng_bgn = Bry_.To_int_or(src, num_bgn, pos, Int_.Min_value);
if (rng_bgn == Int_.Min_value) return or;
num_bgn = -1;
itm_is_rng = true;
break;
default:
return or;
}
++pos;
}
return (rv_idx == rv_len) // on the off-chance that rv_len == rv_idx; EX: "1"
? rv
: (int[])Array_.Resize(rv, rv_idx);
} catch (Exception e) {Err_.Noop(e); return or;}
}
}

View File

@@ -0,0 +1,44 @@
/*
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 Int_ary__tst {
private Int_ary__fxt fxt = new Int_ary__fxt();
@Test public void Parse_list_or_() {
fxt.Test_Parse_list_or("1", 1);
fxt.Test_Parse_list_or("123", 123);
fxt.Test_Parse_list_or("1,2,123", 1, 2, 123);
fxt.Test_Parse_list_or("1,2,12,123", 1, 2, 12, 123);
fxt.Test_Parse_list_or("1-5", 1, 2, 3, 4, 5);
fxt.Test_Parse_list_or("1-1", 1);
fxt.Test_Parse_list_or("1-3,7,11-13,21", 1, 2, 3, 7, 11, 12, 13, 21);
fxt.Test_Parse_list_empty("1 2"); // NOTE: MW would gen 12; treat as invalid
fxt.Test_Parse_list_empty("1,"); // eos
fxt.Test_Parse_list_empty("1,,2"); // empty comma
fxt.Test_Parse_list_empty("1-"); // eos
fxt.Test_Parse_list_empty("3-1"); // bgn > end
fxt.Test_Parse_list_empty("1,a,2");
fxt.Test_Parse_list_empty("a-1,2");
fxt.Test_Parse_list_empty("-1"); // no rng bgn
}
}
class Int_ary__fxt {
public void Test_Parse_list_empty(String raw) {Tfds.Eq_ary(Int_.Ary_empty, Int_ary_.Parse_list_or(Bry_.new_a7(raw), Int_.Ary_empty));}
public void Test_Parse_list_or(String raw, int... expd) {Tfds.Eq_ary(expd, Int_ary_.Parse_list_or(Bry_.new_a7(raw), Int_.Ary_empty));}
}

View File

@@ -0,0 +1,33 @@
/*
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 JarAdp_ {
public static DateAdp ModifiedTime_type(Class<?> type) {if (type == null) throw Err_.new_null();
Io_url url = Url_type(type);
return Io_mgr.Instance.QueryFil(url).ModifiedTime();
}
public static Io_url Url_type(Class<?> type) {if (type == null) throw Err_.new_null();
String codeBase = type.getProtectionDomain().getCodeSource().getLocation().getPath();
if (Op_sys.Cur().Tid_is_wnt())
codeBase = String_.Mid(codeBase, 1); // codebase always starts with /; remove for wnt
codeBase = String_.Replace(codeBase, "/", Op_sys.Cur().Fsys_dir_spr_str()); // java always returns DirSpr as /; change to Env_.DirSpr to handle windows
try {codeBase = java.net.URLDecoder.decode(codeBase, "UTF-8");}
catch (java.io.UnsupportedEncodingException e) {Err_.Noop(e);}
return Io_url_.new_fil_(codeBase);
}
}

View File

@@ -0,0 +1,112 @@
/*
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 Long_ {
public static final String Cls_val_name = "long";
public static final Class<?> Cls_ref_type = Long.class;
public static final int Log10Ary_len = 21;
public static long[] Log10Ary = new long[]
{ 1, 10, 100, 1000, 10000
, 100000, 1000000, 10000000, 100000000, 1000000000
, Long_.Pow(10, 10), Long_.Pow(10, 11), Long_.Pow(10, 12), Long_.Pow(10, 13), Long_.Pow(10, 14)
, Long_.Pow(10, 15), Long_.Pow(10, 16), Long_.Pow(10, 17), Long_.Pow(10, 18), Long_.Pow(10, 19)
, Long_.Max_value
};
public static long parse(String raw) {try {return Long.parseLong(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, long.class, raw);}}
public static long cast(Object obj) {try {return (Long)obj;} catch(Exception e) {throw Err_.new_type_mismatch_w_exc(e, long.class, obj);}}
public static long coerce_(Object v) {
try {String s = String_.as_(v); return s == null ? Long_.cast(v) : Long_.parse(s);}
catch (Exception e) {throw Err_.new_cast(e, long.class, v);}
}
public static String To_str(long v) {return Long.toString(v);}
public static String To_str_PadBgn(long v, int reqdPlaces) {return String_.Pad(To_str(v), reqdPlaces, "0", true);} // ex: 1, 3 returns 001
public static long parse_or(String raw, long or) {
if (raw == null) return or;
try {
int rawLen = String_.Len(raw);
if (raw == null || rawLen == 0) return or;
long rv = 0, factor = 1; int tmp = 0;
for (int i = rawLen; i > 0; i--) {
tmp = Char_.To_int_or(String_.CharAt(raw, i - 1), Int_.Min_value);
if (tmp == Int_.Min_value) return or;
rv += (tmp * factor);
factor *= 10;
}
return rv;
} catch (Exception e) {Err_.Noop(e); return or;}
}
public static int Compare(long lhs, long rhs) {
if (lhs == rhs) return CompareAble_.Same;
else if (lhs < rhs) return CompareAble_.Less;
else return CompareAble_.More;
}
public static int FindIdx(long[] ary, long find_val) {
int ary_len = ary.length;
int adj = 1;
int prv_pos = 0;
int prv_len = ary_len;
int cur_len = 0;
int cur_idx = 0;
long cur_val = 0;
while (true) {
cur_len = prv_len / 2;
if (prv_len % 2 == 1) ++cur_len;
cur_idx = prv_pos + (cur_len * adj);
if (cur_idx < 0) cur_idx = 0;
else if (cur_idx >= ary_len) cur_idx = ary_len - 1;
cur_val = ary[cur_idx];
if (find_val < cur_val) adj = -1;
else if (find_val > cur_val) adj = 1;
else if (find_val == cur_val) return cur_idx;
if (cur_len == 1) {
if (adj == -1 && cur_idx > 0)
return --cur_idx;
return cur_idx;
}
prv_len = cur_len;
prv_pos = cur_idx;
}
}
public static int DigitCount(long v) {
int adj = Int_.Base1;
if (v < 0) {
if (v == Long_.Min_value) return 19; // NOTE: Long_.Min_value * -1 = Long_.Min_value
v *= -1;
++adj;
}
return FindIdx(Log10Ary, v) + adj;
}
public static long Pow(int val, int exp) {
long rv = val;
for (int i = 1; i < exp; i++)
rv *= val;
return rv;
}
public static long Int_merge(int hi, int lo) {return (long)hi << 32 | (lo & 0xFFFFFFFFL);}
public static int Int_split_lo(long v) {return (int)(v);}
public static int Int_split_hi(long v) {return (int)(v >> 32);}
public static final long
Min_value = Long.MIN_VALUE
, Max_value = Long.MAX_VALUE
;
}
/* alternate for Int_merge; does not work in java
public static long MergeInts(int lo, int hi) {return (uint)(hi << 32) | (lo & 0xffffffff);}
public static int SplitLo(long v) {return (int)(((ulong)v & 0x00000000ffffffff));}
public static int SplitHi(long v) {return (int)(((ulong)v & 0xffffffff00000000)) >> 32;}
*/

View File

@@ -0,0 +1,49 @@
/*
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 Long__tst {
@Test public void DigitCount() {
tst_DigitCount(0, 1);
tst_DigitCount(1, 1);
tst_DigitCount(9, 1);
tst_DigitCount(10, 2);
tst_DigitCount(100, 3);
tst_DigitCount(10000, 5);
tst_DigitCount(100000, 6);
tst_DigitCount(1000000, 7);
tst_DigitCount(1000000000, 10);
tst_DigitCount(10000000000L, 11);
tst_DigitCount(100000000000L, 12);
tst_DigitCount(10000000000000000L, 17);
tst_DigitCount(-1, 2);
} void tst_DigitCount(long val, int expd) {Tfds.Eq(expd, Long_.DigitCount(val));}
@Test public void Int_merge() {
tst_Int_merge(123, 456, 528280977864L);
tst_Int_merge(123, 457, 528280977865L);
}
void tst_Int_merge(int hi, int lo, long expd) {
Tfds.Eq(expd, Long_.Int_merge(hi, lo));
Tfds.Eq(hi, Long_.Int_split_hi(expd));
Tfds.Eq(lo, Long_.Int_split_lo(expd));
}
@Test public void parse_or() {
parse_or_tst("10000000000", 10000000000L);
}
void parse_or_tst(String raw, long expd) {Tfds.Eq(expd, Long_.parse_or(raw, -1));}
}

View File

@@ -0,0 +1,86 @@
/*
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 Op_sys {
Op_sys(byte tid, byte sub_tid, String os_name, byte bitness, String nl_str, byte fsys_dir_spr_byte, boolean fsys_case_match) {
this.tid = tid; this.sub_tid = sub_tid; this.os_name = os_name; this.bitness = bitness; this.nl_str = nl_str; this.fsys_dir_spr_byte = fsys_dir_spr_byte; this.fsys_dir_spr_str = Char_.To_str((char)fsys_dir_spr_byte); this.fsys_case_match = fsys_case_match;
}
public byte Tid() {return tid;} private final byte tid;
public byte Sub_tid() {return sub_tid;} private final byte sub_tid;
public String Os_name() {return os_name;} private String os_name;
public byte Bitness() {return bitness;} private final byte bitness;
public String Bitness_str() {return (bitness == Bitness_32 ? "32" : "64");}
public String Nl_str() {return nl_str;} private final String nl_str;
public String Fsys_dir_spr_str() {return fsys_dir_spr_str;} private final String fsys_dir_spr_str;
public byte Fsys_dir_spr_byte() {return fsys_dir_spr_byte;} private final byte fsys_dir_spr_byte;
public String Fsys_http_frag_to_url_str(String raw) {return fsys_dir_spr_byte == Byte_ascii.Slash ? raw : String_.Replace(raw, Lnx.Fsys_dir_spr_str(), fsys_dir_spr_str);}
public boolean Fsys_case_match() {return fsys_case_match;} private final boolean fsys_case_match;
public String Fsys_case_match_str(String s) {return String_.CaseNormalize(fsys_case_match, s);}
public boolean Tid_is_wnt() {return tid == Tid_wnt;}
public boolean Tid_is_lnx() {return tid == Tid_lnx;}
public boolean Tid_is_osx() {return tid == Tid_osx;}
public boolean Tid_is_drd() {return tid == Tid_drd;}
public String To_str() {return os_name + Bitness_str();}
public static final byte Tid_nil = 0, Tid_wnt = 1, Tid_lnx = 2, Tid_osx = 3, Tid_drd = 4;
public static final byte Sub_tid_unknown = 0, Sub_tid_win_xp = 1, Sub_tid_win_7 = 2, Sub_tid_win_8 = 3;
public static final byte Bitness_32 = 1, Bitness_64 = 2;
public static final char Dir_spr_char_lnx = '\n';
public static final Op_sys Lnx = new_unx_flavor_(Tid_lnx, "linux", Bitness_32);
public static final Op_sys Osx = new_unx_flavor_(Tid_osx, "macosx", Bitness_32);
public static final Op_sys Drd = new_unx_flavor_(Tid_drd, "windows", Bitness_32);
public static final Op_sys Wnt = new_wnt_(Sub_tid_unknown, Bitness_32);
public static Op_sys Cur() {return cur_op_sys;} static Op_sys cur_op_sys = new_auto_identify_();
public static String Fsys_path_to_lnx(String v) {
return cur_op_sys.Tid_is_wnt() ? String_.Replace(v, Wnt.fsys_dir_spr_str, Lnx.fsys_dir_spr_str) : v;
}
public static String Fsys_path_to_wnt(String v) {
return cur_op_sys.Tid_is_wnt() ? String_.Replace(v, Lnx.fsys_dir_spr_str, Wnt.fsys_dir_spr_str) : v;
}
private static Op_sys new_wnt_(byte bitness, byte sub_tid) {return new Op_sys(Tid_wnt , sub_tid , "windows", bitness, "\r\n", Byte_ascii.Backslash , Bool_.N);}
private static Op_sys new_unx_flavor_(byte tid, String os_name, byte bitness) {return new Op_sys(tid , Sub_tid_unknown , os_name , bitness, "\n" , Byte_ascii.Slash , Bool_.Y);}
static final String GRP_KEY = "gplx.op_sys";
// public static Op_sys Cur_() {cur_op_sys = new_auto_identify_(); return cur_op_sys;}
static Op_sys new_auto_identify_() {
String os_name = "";
try {
String bitness_str = System.getProperty("sun.arch.data.model"); if (bitness_str == null) return Drd;
bitness_str = bitness_str.toLowerCase();
byte bitness_byte = Bitness_32;
if (String_.Eq(bitness_str, "32")) bitness_byte = Bitness_32;
else if (String_.Eq(bitness_str, "64")) bitness_byte = Bitness_64;
else throw Err_.new_wo_type("unknown bitness; expecting 32 or 64; System.getProperty(\"bit.level\")", "val", bitness_str);
os_name = System.getProperty("os.name").toLowerCase();
if (String_.Has_at_bgn(os_name, "win")) {
String os_version = System.getProperty("os.version").toLowerCase();// "Windows 7".equals(osName) && "6.1".equals(osVersion);
byte sub_tid = Sub_tid_unknown;
if (String_.Eq(os_name, "windows xp") && String_.Eq(os_version, "5.1")) sub_tid = Sub_tid_win_xp;
else if (String_.Eq(os_name, "windows 7") && String_.Eq(os_version, "6.1")) sub_tid = Sub_tid_win_7;
else if (String_.Eq(os_name, "windows 8")) sub_tid = Sub_tid_win_8;
return new_wnt_(bitness_byte, sub_tid);
}
else if (String_.Eq(os_name, "linux")) return new_unx_flavor_(Tid_lnx, os_name, bitness_byte);
else if (String_.Has_at_bgn(os_name, "mac")) return new_unx_flavor_(Tid_osx, os_name, bitness_byte); // EX:Mac OS X
else throw Err_.new_wo_type("unknown os_name; expecting windows, linux, mac; System.getProperty(\"os.name\")", "val", os_name);
} catch (Exception exc) {Drd.os_name = os_name; return Drd;}
}
public static void OpSysIsDroid() {
cur_op_sys = Drd;
}
}

View File

@@ -0,0 +1,34 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
public class Op_sys_ {
public static boolean Wnt_invalid_char(byte b) {
switch (b) {
case Byte_ascii.Slash:
case Byte_ascii.Backslash:
case Byte_ascii.Lt:
case Byte_ascii.Gt:
case Byte_ascii.Colon:
case Byte_ascii.Pipe:
case Byte_ascii.Question:
case Byte_ascii.Star:
case Byte_ascii.Quote: return true;
default: return false;
}
}
}

View File

@@ -0,0 +1,355 @@
/*
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.core.threads.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.management.RuntimeErrorException;
import gplx.core.brys.fmtrs.*;
import gplx.core.strings.*; import gplx.langs.gfs.*;
public class ProcessAdp implements GfoInvkAble, RlsAble {
public boolean Enabled() {return enabled;} public ProcessAdp Enabled_(boolean v) {enabled = v; return this;} private boolean enabled = true;
public byte Exe_exists() {return exe_exists;} public ProcessAdp Exe_exists_(byte v) {exe_exists = v; return this;} private byte exe_exists = Bool_.__byte;
public Io_url Exe_url() {return exe_url;} public ProcessAdp Exe_url_(Io_url val) {exe_url = val; exe_exists = Bool_.__byte; return this;} Io_url exe_url;
public String Args_str() {return args_str;} public ProcessAdp Args_str_(String val) {args_str = val; return this;} private String args_str = "";
public Bry_fmtr Args_fmtr() {return args_fmtr;} Bry_fmtr args_fmtr = Bry_fmtr.new_("");
public byte Run_mode() {return run_mode;} public ProcessAdp Run_mode_(byte v) {run_mode = v; return this;} private byte run_mode = Run_mode_sync_block;
public static final byte Run_mode_async = 0, Run_mode_sync_block = 1, Run_mode_sync_timeout = 2;
public int Exit_code() {return exit_code;} int exit_code;
public boolean Exit_code_pass() {return exit_code == Exit_pass;}
public String Rslt_out() {return rslt_out;} private String rslt_out;
public Io_url Working_dir() {return working_dir;} public ProcessAdp Working_dir_(Io_url v) {working_dir = v; return this;} Io_url working_dir;
public ProcessAdp Cmd_args(String cmd, String args) {this.Exe_url_(Io_url_.new_fil_(cmd)); this.args_fmtr.Fmt_(args); return this;}
public ProcessAdp WhenBgn_add(GfoInvkAbleCmd cmd) {whenBgnList.Add(cmd); return this;}
public ProcessAdp WhenBgn_del(GfoInvkAbleCmd cmd) {whenBgnList.Del(cmd); return this;}
public int Thread_timeout() {return thread_timeout;} public ProcessAdp Thread_timeout_seconds_(int v) {thread_timeout = v * 1000; return this;} int thread_timeout = 0;
public int Thread_interval() {return thread_interval;} public ProcessAdp Thread_interval_(int v) {thread_interval = v; return this;} int thread_interval = 20;
public String Thread_kill_name() {return thread_kill_name;} public ProcessAdp Thread_kill_name_(String v) {thread_kill_name = v; return this;} private String thread_kill_name = "";
public Io_url Tmp_dir() {return tmp_dir;} @gplx.Virtual public ProcessAdp Tmp_dir_(Io_url v) {tmp_dir = v; return this;} Io_url tmp_dir;
private ProcessAdp WhenBgn_run() {return Invk_cmds(whenBgnList);} List_adp whenBgnList = List_adp_.new_();
public ProcessAdp WhenEnd_add(GfoInvkAbleCmd cmd) {whenEndList.Add(cmd); return this;}
public ProcessAdp WhenEnd_del(GfoInvkAbleCmd cmd) {whenEndList.Del(cmd); return this;}
public Gfo_usr_dlg Prog_dlg() {return prog_dlg;} public ProcessAdp Prog_dlg_(Gfo_usr_dlg v) {prog_dlg = v; return this;} Gfo_usr_dlg prog_dlg;
public String Prog_fmt() {return prog_fmt;} public ProcessAdp Prog_fmt_(String v) {prog_fmt = v; return this;} private String prog_fmt = ""; // NOTE: set to "", else cmds that do not set prog_fmt will fail on fmtr.Fmt(null)
private GfoInvkAble owner;
private ProcessAdp WhenEnd_run() {return Invk_cmds(whenEndList);} List_adp whenEndList = List_adp_.new_();
private ProcessAdp Invk_cmds(List_adp list) {
for (Object o : list)
((GfoInvkAbleCmd)o).Invk();
return this;
}
public ProcessAdp Run(Object... args) {
if (String_.Len_eq_0(exe_url.Raw())) return this; // noop if exe_url is "";
if (!args_fmtr.Fmt_null()) {
Bry_bfr tmp_bfr = Bry_bfr.new_();
args_fmtr.Bld_bfr_many(tmp_bfr, args);
args_str = tmp_bfr.To_str_and_clear();
}
prog_dlg.Log_many(GRP_KEY, "run", "running process: ~{0} ~{1}", exe_url.Raw(), args_str);
exit_code = Exit_init;
switch (run_mode) {
case Run_mode_async: return Run_async();
case Run_mode_sync_timeout: return Run_wait();
case Run_mode_sync_block: return Run_wait_sync();
default: throw Err_.new_unhandled(run_mode);
}
}
public String[] Xto_process_bldr_args(String... args) {
String args_str = args_fmtr.Bld_str_many(args);
return Xto_process_bldr_args_utl(exe_url, args_str);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_enabled)) return enabled;
else if (ctx.Match(k, Invk_enabled_)) enabled = m.ReadBool("v");
else if (ctx.Match(k, Invk_cmd)) return exe_url.Raw();
else if (ctx.Match(k, Invk_cmd_)) this.Exe_url_(Bry_fmtr_eval_mgr_.Eval_url(cmd_url_eval, m.ReadBry("cmd")));
else if (ctx.Match(k, Invk_args)) return String_.new_u8(args_fmtr.Fmt());
else if (ctx.Match(k, Invk_args_)) args_fmtr.Fmt_(m.ReadBry("v"));
else if (ctx.Match(k, Invk_cmd_args_)) {this.Exe_url_(Bry_fmtr_eval_mgr_.Eval_url(cmd_url_eval, m.ReadBry("cmd"))); args_fmtr.Fmt_(m.ReadBry("args"));}
else if (ctx.Match(k, Invk_mode_)) run_mode = m.ReadByte("v");
else if (ctx.Match(k, Invk_timeout_)) thread_timeout = m.ReadInt("v");
else if (ctx.Match(k, Invk_tmp_dir_)) tmp_dir = m.ReadIoUrl("v");
else if (ctx.Match(k, Invk_owner)) return owner;
else return GfoInvkAble_.Rv_unhandled;
return this;
}
static final String Invk_cmd = "cmd", Invk_cmd_ = "cmd_", Invk_args = "args", Invk_args_ = "args_", Invk_cmd_args_ = "cmd_args_", Invk_enabled = "enabled", Invk_enabled_ = "enabled_", Invk_mode_ = "mode_", Invk_timeout_ = "timeout_", Invk_tmp_dir_ = "tmp_dir_", Invk_owner = "owner";
Bry_fmtr_eval_mgr cmd_url_eval;
public static ProcessAdp ini_(GfoInvkAble owner, Gfo_usr_dlg usr_dlg, ProcessAdp process, Bry_fmtr_eval_mgr cmd_url_eval, byte run_mode, int timeout, String cmd_url_fmt, String args_fmt, String... args_keys) {
process.Run_mode_(run_mode).Thread_timeout_seconds_(timeout);
process.cmd_url_eval = cmd_url_eval;
Io_url cmd_url = Bry_fmtr_eval_mgr_.Eval_url(cmd_url_eval, Bry_.new_u8(cmd_url_fmt));
process.Exe_url_(cmd_url).Tmp_dir_(cmd_url.OwnerDir());
process.Args_fmtr().Fmt_(args_fmt).Keys_(args_keys);
process.owner = owner;
process.Prog_dlg_(usr_dlg);
return process; // return process for chaining
}
public static String Escape_ampersands_if_process_is_cmd(boolean os_is_wnt, String exe_url, String exe_args) {
return ( os_is_wnt
&& String_.Eq(exe_url, "cmd"))
? String_.Replace(exe_args, "&", "^&") // escape ampersands
: exe_args
;
}
private Bry_fmtr notify_fmtr = Bry_fmtr.new_("", "process_exe_name", "process_exe_args", "process_seconds"); Bry_bfr notify_bfr = Bry_bfr.reset_(255);
public Process UnderProcess() {return process;} Process process;
public void Rls() {if (process != null) process.destroy();}
public ProcessAdp Run_wait_sync() {
if (Env_.Mode_testing()) return Test_runs_add();
Process_bgn();
Process_start();
Process_run_and_end();
return this;
}
public ProcessAdp Run_start() {
if (Env_.Mode_testing()) return Test_runs_add();
Process_bgn();
Process_start();
return this;
}
public ProcessAdp Run_async() {
if (Env_.Mode_testing()) return Test_runs_add();
Process_bgn();
Thread_ProcessAdp_async thread = new Thread_ProcessAdp_async(this);
thread.start();
return this;
}
public ProcessAdp Run_wait() {
if (Env_.Mode_testing()) return Test_runs_add();
int notify_interval = 100; int notify_checkpoint = notify_interval;
int elapsed = 0;
try {
Process_bgn();
Thread_ProcessAdp_sync thread = new Thread_ProcessAdp_sync(this);
thread.start();
// thread_timeout = 15000;
boolean thread_run = false;
notify_fmtr.Fmt_(prog_fmt);
while (thread.isAlive()) {
thread_run = true;
long prv = Env_.TickCount();
Thread_adp_.Sleep(thread_interval);
// try {thread.join(thread_interval);}
// catch (InterruptedException e) {throw Err_.err_key_(e, "gplx.ProcessAdp", "thread interrupted at join");}
long cur = Env_.TickCount();
int dif = (int)(cur - prv);
elapsed += dif;
if (prog_dlg != null) {
if (elapsed > notify_checkpoint) {
elapsed = notify_checkpoint;
notify_checkpoint += notify_interval;
notify_fmtr.Bld_bfr_many(notify_bfr, exe_url.NameAndExt(), args_str, elapsed / 1000);
prog_dlg.Prog_none(GRP_KEY, "notify.prog", notify_bfr.To_str_and_clear());
}
}
if (thread_timeout == 0) break;
if (elapsed > thread_timeout) {
thread.interrupt();
thread.Cancel();
try {thread.join();}
catch (InterruptedException e) {throw Err_.new_exc(e, "core", "thread interrupted at timeout");}
break;
}
}
if (!thread_run) {
try {thread.join();}
catch (InterruptedException e) {throw Err_.new_exc(e, "core", "thread interrupted at join 2");}
}
} catch (Exception exc) {
Tfds.Write(Err_.Message_gplx_full(exc));
}
if (elapsed != notify_checkpoint) {
notify_fmtr.Bld_bfr_many(notify_bfr, exe_url.NameAndExt(), args_str, elapsed / 1000);
if (prog_dlg != null) prog_dlg.Prog_none(GRP_KEY, "notify.prog", notify_bfr.To_str_and_clear());
}
return this;
}
public synchronized void Process_post(String result) {
exit_code = process.exitValue();
rslt_out = result;
WhenEnd_run();
process.destroy();
}
String Kill() {
if (thread_kill_name == String_.Empty) return "";
// Runtime rt = Runtime.getRuntime();
String kill_exe = "", kill_args = "";
if (Op_sys.Cur().Tid_is_wnt()) {
kill_exe = "taskkill";
kill_args = "/F /IM ";
}
else {
kill_exe = "kill";
kill_args = "-9 ";
}
kill_args += thread_kill_name;
ProcessAdp kill_process = new ProcessAdp().Exe_url_(Io_url_.new_fil_(kill_exe)).Args_str_(kill_args).Thread_kill_name_("");
boolean pass = kill_process.Run_wait().Exit_code_pass();
return "killed|" + kill_exe + "|" + kill_args + "|" + pass + "|" + exe_url.Raw() + "|" + args_str;
}
synchronized void Process_bgn() {
exit_code = Exit_init;
rslt_out = "";
WhenBgn_run();
pb = new ProcessBuilder(Xto_process_bldr_args_utl(exe_url, args_str));
pb.redirectErrorStream(true); // NOTE: need to redirectErrorStream or rdr.readLine() will hang; see inkscape and Ostfriesland Verkehr-de.svg
if (working_dir != null)
pb.directory(new File(working_dir.Xto_api()));
else if (!exe_url.OwnerDir().EqNull()) // only set workingDir if ownerDir is not null; NOTE: workingDir necessary for AdvMame; probably not a bad thing to do
pb.directory(new File(exe_url.OwnerDir().Xto_api()));
} ProcessBuilder pb;
protected Process Process_start() {
try {process = pb.start();}
catch (IOException e) {
java.util.List<String> command_list = pb.command();
String[] command_ary = new String[command_list.size()];
command_ary = command_list.toArray(command_ary);
throw Err_.new_exc(e, "core", "process start failed", "args", String_.Concat_with_str(" ", command_ary));
}
return process;
}
void Process_run_and_end() {
String_bldr sb = String_bldr_.new_();
BufferedReader rdr = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
String line = "";
while ((line = rdr.readLine()) != null)
sb.Add_str_w_crlf(line);
process.waitFor();
}
catch (InterruptedException e) {throw Err_.new_exc(e, "core", "thread interrupted at wait_for", "exe_url", exe_url.Xto_api(), "exeArgs", args_str);}
catch (IOException e) {throw Err_.new_exc(e, "core", "io error", "exe_url", exe_url.Xto_api(), "exeArgs", args_str);}
exit_code = process.exitValue();
WhenEnd_run();
process.destroy();
rslt_out = sb.To_str_and_clear();
}
public void Process_term() {
try {
process.getInputStream().close();
process.getErrorStream().close();
} catch (IOException e) {}
process.destroy();
}
public static void run_wait_(Io_url url) {
ProcessAdp process = new ProcessAdp().Exe_url_(url);
process.Run_start();
process.Process_run_and_end();
return;
}
public static final List_adp Test_runs = List_adp_.new_();
private ProcessAdp Test_runs_add() {Test_runs.Add(exe_url.Raw() + " " + args_str); exit_code = Exit_pass; return this;}
public static int run_wait_arg_(Io_url url, String arg) {
ProcessAdp process = new ProcessAdp();
process.Exe_url_(url).Args_str_(arg).Run_wait();
return process.Exit_code();
}
private static final String GRP_KEY = "gplx.process";
public static final int Exit_pass = 0, Exit_init = -1;
public static String[] Xto_process_bldr_args_utl(Io_url exe_url, String args_str) {
List_adp list = List_adp_.new_();
list.Add(exe_url.Xto_api());
String_bldr sb = String_bldr_.new_();
int len = String_.Len(args_str);
boolean in_quotes = false;
for (int i = 0; i < len; i++) {
char c = String_.CharAt(args_str, i);
if (c == ' ' && !in_quotes) { // space encountered; assume arg done
list.Add(sb.To_str());
sb.Clear();
}
else if (c == '"') // NOTE: ProcessBuilder seems to have issues with quotes; do not call sb.Add()
in_quotes = !in_quotes;
else
sb.Add(c);
}
if (sb.Has_some()) list.Add(sb.To_str());
return list.To_str_ary();
}
}
class Thread_ProcessAdp_async extends Thread {
public Thread_ProcessAdp_async(ProcessAdp process_adp) {this.process_adp = process_adp;} ProcessAdp process_adp;
public boolean Done() {return done;} boolean done = false;
public void Cancel() {process_adp.UnderProcess().destroy();}
public void run() {
process_adp.Run_wait();
}
}
class Thread_ProcessAdp_sync extends Thread {
public Thread_ProcessAdp_sync(ProcessAdp process_adp) {this.process_adp = process_adp;} private final ProcessAdp process_adp;
public boolean Done() {return done;} private boolean done = false;
public void Cancel() {
process_adp.UnderProcess().destroy();
}
public synchronized void run() {
done = false;
try {
Process process = process_adp.Process_start();
StreamGobbler input_gobbler = new StreamGobbler("input", process.getInputStream());
StreamGobbler error_gobbler = new StreamGobbler("error", process.getErrorStream());
input_gobbler.start();
error_gobbler.start();
try {process.waitFor();}
catch (InterruptedException e) {
this.Cancel();
String kill_rslt = process_adp.Kill();
process_adp.Process_post(kill_rslt);
done = false;
return;
}
while (input_gobbler.isAlive()) {
try {input_gobbler.join(50);}
catch (InterruptedException e) {throw Err_.new_exc(e, "core", "thread interrupted at input gobbler");}
}
while (error_gobbler.isAlive()) {
try {error_gobbler.join(50);}
catch (InterruptedException e) {throw Err_.new_exc(e, "core", "thread interrupted at error gobbler");}
}
String result = input_gobbler.Rslt() + "\n" + error_gobbler.Rslt();
process_adp.Process_post(result);
} catch (Exception e) { // NOTE: warn; do not throw, else multiple errors if timidity not available; PAGE:fr.u:Pentatoniques_altérées/Gammes_avec_deux_notes_altérées DATE:2015-05-08
Gfo_usr_dlg_.Instance.Warn_many("", "", "process.sync failed; cmd=~{0} args=~{1}", process_adp.Exe_url().Raw(), process_adp.Args_str());
}
finally {done = true;}
}
}
class StreamGobbler extends Thread {
private final String name; private final InputStream stream;
public StreamGobbler (String name, InputStream stream) {this.name = name; this.stream = stream;}
public String Rslt() {return rslt;} private String rslt;
public void run () {
try {
String_bldr sb = String_bldr_.new_();
InputStreamReader isr = new InputStreamReader(stream);
BufferedReader br = new BufferedReader(isr);
while (true) {
String s = br.readLine();
if (s == null) break;
sb.Add(s);
}
stream.close();
rslt = sb.To_str_and_clear();
}
catch (Exception e) {throw Err_.new_exc(e, "io", "failed reading stream", "name", name);}
}
}

View File

@@ -0,0 +1,32 @@
/*
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 ProcessAdp_tst {
private ProcessAdp_fxt fxt = new ProcessAdp_fxt();
@Test public void Escape_ampersands_if_process_is_cmd() {
fxt.Test_Escape_ampersands_if_process_is_cmd(Bool_.Y, "cmd" , "/c \"http://a.org?b=c&d=e\"", "/c \"http://a.org?b=c^&d=e\"");
fxt.Test_Escape_ampersands_if_process_is_cmd(Bool_.Y, "cmd1", "/c \"http://a.org?b=c&d=e\"", "/c \"http://a.org?b=c&d=e\"");
fxt.Test_Escape_ampersands_if_process_is_cmd(Bool_.N, "cmd" , "/c \"http://a.org?b=c&d=e\"", "/c \"http://a.org?b=c&d=e\"");
}
}
class ProcessAdp_fxt {
public void Test_Escape_ampersands_if_process_is_cmd(boolean os_is_wnt, String exe_url, String exe_args, String expd) {
Tfds.Eq(expd, ProcessAdp.Escape_ampersands_if_process_is_cmd(os_is_wnt, exe_url, exe_args));
}
}

View File

@@ -0,0 +1,22 @@
/*
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 Short_ {
public static final Class<?> Cls_ref_type = Short.class;
public static short cast(Object obj) {try {return (Short)obj;} catch(Exception exc) {throw Err_.new_type_mismatch_w_exc(exc, short.class, obj);}}
}

View File

@@ -221,9 +221,9 @@ class TfdsMsgBldr {
}
sb.Add_fmt_line("{0}: {1} {2} {3}"
, Int_.To_str_pad_bgn_zero(itm.Idx(), 4)
, String_.PadBgn(itm.Lhs(), lhsLenMax, " ")
, itm.Lhs() // String_.PadBgn(itm.Lhs(), lhsLenMax, " ")
, eq_str
, String_.PadBgn(itm.Rhs(), rhsLenMax, " ")
, itm.Rhs() // String_.PadBgn(itm.Rhs(), rhsLenMax, " ")
);
}
// String compSym = isEq ? " " : "!=";

View File

@@ -0,0 +1,81 @@
/*
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 Type_adp_ {
public static boolean Eq(Class<?> lhs, Class<?> rhs) {
if (lhs == null && rhs == null) return true;
else if (lhs == null || rhs == null) return false;
else return lhs.equals(rhs);
}
public static boolean Eq_typeSafe(Object o, Class<?> expd) {if (o == null) return false;
Class<?> actl = o.getClass();
return Object_.Eq(expd, actl);
}
public static boolean IsAssignableFrom(Class<?> lhs, Class<?> rhs) {return lhs.isAssignableFrom(rhs);}
public static boolean Implements_intf_obj(Object cur, Class<?> type) {return cur == null ? false : IsAssignableFrom(type, cur.getClass());}
public static boolean Is_array(Class<?> t) {return t.isArray();}
public static Class<?> ClassOf_obj(Object o) {return o.getClass();}
public static Class<?> ClassOf_primitive(Object o) {
Class<?> rv = o.getClass();
if (rv == Integer.class) rv = int.class;
else if (rv == Long.class) rv = long.class;
else if (rv == Byte.class) rv = byte.class;
else if (rv == Short.class) rv = short.class;
return rv;
}
public static String FullNameOf_obj(Object o) {return FullNameOf_type(o.getClass());}
public static String FullNameOf_type(Class<?> type) {return type.getCanonicalName();}
public static String NameOf_type(Class<?> type) {return type.getName();}
public static String NameOf_obj(Object obj) {return obj == null ? String_.Null_mark : obj.getClass().getName();}
public static int To_tid_obj(Object o) {
if (o == null) return Tid__null;
Class<?> type = o.getClass();
return To_tid_type(type);
}
public static int To_tid_type(Class<?> type) {
if (Type_adp_.Eq(type, Int_.Cls_ref_type)) return Tid__int;
else if (Type_adp_.Eq(type, String_.Cls_ref_type)) return Tid__str;
else if (Type_adp_.Eq(type, byte[].class)) return Tid__bry;
else if (Type_adp_.Eq(type, Bool_.Cls_ref_type)) return Tid__bool;
else if (Type_adp_.Eq(type, Byte_.Cls_ref_type)) return Tid__byte;
else if (Type_adp_.Eq(type, Long_.Cls_ref_type)) return Tid__long;
else if (Type_adp_.Eq(type, Double_.Cls_ref_type)) return Tid__double;
else if (Type_adp_.Eq(type, Decimal_adp_.Cls_ref_type)) return Tid__decimal;
else if (Type_adp_.Eq(type, DateAdp_.Cls_ref_type)) return Tid__date;
else if (Type_adp_.Eq(type, Float_.Cls_ref_type)) return Tid__float;
else if (Type_adp_.Eq(type, Short_.Cls_ref_type)) return Tid__short;
else if (Type_adp_.Eq(type, Char_.Cls_ref_type)) return Tid__char;
else return Tid__obj;
}
public static final int
Tid__obj = 0
, Tid__null = 1
, Tid__bool = 2
, Tid__byte = 3
, Tid__short = 4
, Tid__int = 5
, Tid__long = 6
, Tid__float = 7
, Tid__double = 8
, Tid__char = 9
, Tid__str = 10
, Tid__bry = 11
, Tid__date = 12
, Tid__decimal = 13
;
}

78
100_core/src/gplx/Yn.java Normal file
View File

@@ -0,0 +1,78 @@
/*
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 Yn {
public static final String Y = "y", N = "n";
public static boolean parse_by_char_or(String v, boolean or) {
if (String_.Eq(v, Y)) return true;
else if (String_.Eq(v, N)) return false;
else return or;
}
public static boolean parse_or_n_(String v) {return parse_or(v, false);}
public static int parse_as_int(String v) {
if (v == null) return Bool_.__int;
else if (String_.Eq(v, "y")) return Bool_.Y_int;
else if (String_.Eq(v, "n")) return Bool_.N_int;
else return Bool_.__int;
}
public static boolean parse_or(String v, boolean or) {
int v_int = parse_as_int(v);
switch (v_int) {
case Bool_.N_int: return false;
case Bool_.Y_int: return true;
case Bool_.__int: return or;
default: throw Err_.new_unhandled(v_int);
}
}
public static boolean parse(String v) {
int v_int = parse_as_int(v);
if (v_int == Bool_.__int) Err_.new_unhandled(v);
return v_int == Bool_.Y_int;
}
public static String To_str(boolean v) {return v ? "y" : "n";}
public static String To_nullable_str(byte v) {
switch (v) {
case Bool_.Y_byte: return "y";
case Bool_.N_byte: return "n";
case Bool_.__byte: return "?";
default: throw Err_.new_unhandled(v);
}
}
public static byte To_nullable_byte(String v) {
if (v != null && String_.Len(v) == 1) {
char c = String_.CharAt(v, 0);
switch (c) {
case 'y': return Bool_.Y_byte;
case 'n': return Bool_.N_byte;
case '?': return Bool_.__byte;
}
}
throw Err_.new_unhandled(v);
}
public static boolean store_bool_or(SrlMgr mgr, String key, boolean or) {
String v = mgr.SrlStrOr(key, "");
return mgr.Type_rdr() ? parse_or(v, or) : or;
}
public static boolean coerce_(Object o) {String s = String_.as_(o); return s != null ? parse_or(s, false) : Bool_.cast(o);}
public static boolean readOrFalse_(DataRdr rdr, String key) {return read_(rdr, key, false);}
public static boolean readOrTrue_(DataRdr rdr, String key) {return read_(rdr, key, true);}
static boolean read_(DataRdr rdr, String key, boolean or) {
String v = rdr.ReadStrOr(key, null);
return parse_or(v, or);
}
}

View File

@@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys; import gplx.*; import gplx.core.*;
public interface Bfr_arg {
void Bfr_arg__clear();
boolean Bfr_arg__exists();
void Bfr_arg__add(Bry_bfr bfr);
}

View File

@@ -0,0 +1,37 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys; import gplx.*; import gplx.core.*;
import gplx.core.brys.args.*; import gplx.core.brys.fmtrs.*;
public class Bfr_arg_ {
public static Bfr_arg__int New_int(int v) {return new Bfr_arg__int(v);}
public static Bfr_arg__byte New_byte(byte v) {return new Bfr_arg__byte(v);}
public static Bfr_arg__bry New_bry(String v) {return new Bfr_arg__bry(Bry_.new_u8(v));}
public static Bfr_arg__bry New_bry(byte[] v) {return new Bfr_arg__bry(v);}
public static Bfr_arg__bry_fmtr New_bry_fmtr__null() {return new Bfr_arg__bry_fmtr(null, null);}
public static Bfr_arg__bry_fmtr New_bry_fmtr(Bry_fmtr v, Bfr_arg... arg_ary) {return new Bfr_arg__bry_fmtr(v, arg_ary);}
public static final Bfr_arg Noop = new Bfr_arg___noop();
public static void Clear(Bfr_arg... ary) {
for (Bfr_arg arg : ary)
arg.Bfr_arg__clear();
}
}
class Bfr_arg___noop implements gplx.core.brys.Bfr_arg {
public void Bfr_arg__clear() {}
public boolean Bfr_arg__exists() {return false;}
public void Bfr_arg__add(Bry_bfr bfr) {}
}

View File

@@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys; import gplx.*; import gplx.core.*;
public abstract class Bfr_arg_base implements Bfr_arg {
@gplx.Virtual public void Bfr_arg__clear() {}
@gplx.Virtual public boolean Bfr_arg__exists() {return true;}
public abstract void Bfr_arg__add(Bry_bfr bfr);
}

View File

@@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys; import gplx.*; import gplx.core.*;
public interface Bry_split_wkr {
int Split(byte[] src, int itm_bgn, int itm_end);
}

View File

@@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__bry extends gplx.core.brys.Bfr_arg_base {
private final byte[] bry;
public Bfr_arg__bry(byte[] v) {this.bry = v;}
@Override public void Bfr_arg__add(Bry_bfr bfr) {bfr.Add(bry);}
}

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__bry_ary extends gplx.core.brys.Bfr_arg_base {
private byte[][] bry_ary;
public Bfr_arg__bry_ary Set(byte[][] v) {this.bry_ary = v; return this;}
@Override public void Bfr_arg__add(Bry_bfr bfr) {
for (byte[] bry : bry_ary)
bfr.Add(bry);
}
}

View File

@@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.core.brys.fmtrs.*;
public class Bfr_arg__bry_fmtr extends gplx.core.brys.Bfr_arg_base {
private Bry_fmtr fmtr; private Object[] arg_ary;
public Bfr_arg__bry_fmtr(Bry_fmtr fmtr, Object[] arg_ary) {Set(fmtr, arg_ary);}
public Bfr_arg__bry_fmtr Set(Bry_fmtr fmtr, Object... arg_ary) {
this.fmtr = fmtr; this.arg_ary = arg_ary;
return this;
}
@Override public void Bfr_arg__add(Bry_bfr bfr) {fmtr.Bld_bfr_many(bfr, arg_ary);}
}

View File

@@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__byte extends gplx.core.brys.Bfr_arg_base {
private final byte byt;
public Bfr_arg__byte(byte byt) {this.byt = byt;}
@Override public void Bfr_arg__add(Bry_bfr bfr) {bfr.Add_byte(byt);}
}

View File

@@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__decimal_int extends gplx.core.brys.Bfr_arg_base {
public int Val() {return val;} public Bfr_arg__decimal_int Val_(int v) {val = v; return this;} int val;
public Bfr_arg__decimal_int Places_(int v) {places = v; multiple = (int)Math_.Pow(10, v); return this;} int multiple = 1000, places = 3;
@Override public void Bfr_arg__add(Bry_bfr bfr) {
bfr.Add_int_variable(val / multiple).Add_byte(Byte_ascii.Dot).Add_int_fixed(val % multiple, places);
}
}

View File

@@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__int extends gplx.core.brys.Bfr_arg_base {
private int val, val_digits;
public Bfr_arg__int(int v) {Set(v);}
public Bfr_arg__int Set(int v) {
this.val = Int_.cast(v);
this.val_digits = Int_.DigitCount(val);
return this;
}
@Override public void Bfr_arg__add(Bry_bfr bfr) {bfr.Add_int_digits(val_digits, val);}
}

View File

@@ -0,0 +1,55 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bfr_arg__time extends gplx.core.brys.Bfr_arg_base {
public Bfr_arg__time() {
units_len = units.length;
}
public long Seconds() {return seconds;} public Bfr_arg__time Seconds_(long v) {seconds = v; return this;} long seconds;
byte[][] segs = new byte[][]
{ Bry_.new_a7("d")
, Bry_.new_a7("h")
, Bry_.new_a7("m")
, Bry_.new_a7("s")
};
int[] units = new int[] {86400, 3600, 60, 1};
int units_len;
byte[] spr = new byte[] {Byte_ascii.Space};
@Override public void Bfr_arg__add(Bry_bfr bfr) {
if (seconds == 0) { // handle 0 separately (since it will always be < than units[*]
bfr.Add_int_fixed(0, 2).Add(segs[units_len - 1]);
return;
}
long val = seconds;
boolean dirty = false;
for (int i = 0; i < units_len; i++) {
long unit = units[i];
long seg = 0;
if (val >= unit) { // unit has value; EX: 87000 > 86400, so unit is 1 day
seg = val / unit;
val = val - (seg * unit);
}
if (seg > 0 || dirty) { // dirty check allows for 0 in middle units (EX: 1h 0m 1s)
if (dirty) bfr.Add(spr);
if (seg < 10) bfr.Add_byte(Byte_ascii.Num_0); // 0 pad
bfr.Add_long_variable(seg).Add(segs[i]);
dirty = true;
}
}
}
}

View File

@@ -0,0 +1,42 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.args; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import org.junit.*;
public class Bfr_arg__time_tst {
@Test public void Basic() {
Time_fmtr_arg_fxt fxt = new Time_fmtr_arg_fxt().Clear();
fxt.XferAry( 1, "01s"); // seconds
fxt.XferAry( 62, "01m 02s"); // minutes
fxt.XferAry( 3723, "01h 02m 03s"); // hours
fxt.XferAry( 93784, "01d 02h 03m 04s"); // days
fxt.XferAry( 0, "00s"); // handle 0 seconds
fxt.XferAry( 3601, "01h 00m 01s"); // handle 0 in middle unit
}
}
class Time_fmtr_arg_fxt {
public Time_fmtr_arg_fxt Clear() {
if (arg == null) arg = new Bfr_arg__time();
return this;
} Bfr_arg__time arg;
public void XferAry(int seconds, String expd) {
Bry_bfr bfr = Bry_bfr.reset_(255);
arg.Seconds_(seconds);
arg.Bfr_arg__add(bfr);
Tfds.Eq(expd, bfr.To_str());
}
}

View File

@@ -0,0 +1,266 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.core.brys.*; import gplx.core.primitives.*; import gplx.core.strings.*;
public class Bry_fmtr {
public byte[] Fmt() {return fmt;} private byte[] fmt = Bry_.Empty;
public boolean Fmt_null() {return fmt.length == 0;}
public Bry_fmtr_eval_mgr Eval_mgr() {return eval_mgr;} public Bry_fmtr Eval_mgr_(Bry_fmtr_eval_mgr v) {eval_mgr = v; return this;} Bry_fmtr_eval_mgr eval_mgr = Bry_fmtr_eval_mgr_gfs.Instance;
public Bry_fmtr Fmt_(byte[] v) {fmt = v; dirty = true; return this;} public Bry_fmtr Fmt_(String v) {return Fmt_(Bry_.new_u8(v));}
public Bry_fmtr Keys_(String... ary) {
if (keys == null) keys = Hash_adp_.new_();
else keys.Clear();
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++)
keys.Add(Bry_obj_ref.New(Bry_.new_u8(ary[i])), Int_obj_val.new_(i));
dirty = true;
return this;
} Hash_adp keys = null;
public void Bld_bfr(Bry_bfr bfr, byte[]... args) {
if (dirty) Compile();
int args_len = args.length;
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg) {
int arg_idx = itm.ArgIdx;
if (arg_idx < args_len)
bfr.Add(args[arg_idx]);
else
bfr.Add(missing_bgn).Add_int_variable(arg_idx + missing_adj).Add(missing_end);
}
else
bfr.Add(itm.Dat);
}
}
public void Bld_bfr_none(Bry_bfr bfr) {
if (dirty) Compile();
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg)
bfr.Add_byte(char_escape).Add_byte(char_arg_bgn).Add_int_variable(itm.ArgIdx).Add_byte(char_arg_end);
else
bfr.Add(itm.Dat);
}
}
public void Bld_bfr(Bry_bfr bfr, Bfr_arg... args) {
if (dirty) Compile();
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg)
args[itm.ArgIdx].Bfr_arg__add(bfr);
else
bfr.Add(itm.Dat);
}
}
public void Bld_bfr_one(Bry_bfr bfr, Object val) {
Bld_bfr_one_ary[0] = val;
Bld_bfr_ary(bfr, Bld_bfr_one_ary);
} Object[] Bld_bfr_one_ary = new Object[1];
public void Bld_bfr_many(Bry_bfr bfr, Object... args) {Bld_bfr_ary(bfr, args);}
public void Bld_bfr_ary(Bry_bfr bfr, Object[] args) {
if (dirty) Compile();
int args_len = args.length;
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg) {
int arg_idx = itm.ArgIdx;
if (arg_idx > -1 && arg_idx < args_len)
bfr.Add_obj(args[itm.ArgIdx]);
else
bfr.Add_byte(char_escape).Add_byte(char_arg_bgn).Add_int_variable(arg_idx).Add_byte(char_arg_end);
}
else
bfr.Add(itm.Dat);
}
}
public byte[] Bld_bry_none(Bry_bfr bfr) {Bld_bfr_ary(bfr, Object_.Ary_empty); return bfr.To_bry_and_clear();}
public byte[] Bld_bry_many(Bry_bfr bfr, Object... args) {
Bld_bfr_ary(bfr, args);
return bfr.To_bry_and_clear();
}
public String Bld_str_many(Bry_bfr bfr, String fmt, Object... args) {
this.Fmt_(fmt).Bld_bfr_many(bfr, args);
return bfr.To_str_and_clear();
}
public String Bld_str_many(String... args) {
if (dirty) Compile();
String_bldr rv = String_bldr_.new_();
int args_len = args.length;
for (int i = 0; i < itms_len; i++) {
Bry_fmtr_itm itm = itms[i];
if (itm.Arg) {
int arg_idx = itm.ArgIdx;
if (arg_idx < args_len)
rv.Add(args[arg_idx]);
else
rv.Add(missing_bgn).Add(arg_idx + missing_adj).Add(missing_end);
}
else
rv.Add(itm.DatStr());
}
return rv.To_str();
} private Bry_fmtr_itm[] itms; int itms_len;
public byte[] Missing_bgn() {return missing_bgn;} public Bry_fmtr Missing_bgn_(byte[] v) {missing_bgn = v; return this;} private byte[] missing_bgn = missing_bgn_static; static byte[] missing_bgn_static = Bry_.new_u8("~{"), missing_end_static = Bry_.new_u8("}");
public byte[] Missing_end() {return missing_end;} public Bry_fmtr Missing_end_(byte[] v) {missing_end = v; return this;} private byte[] missing_end = missing_end_static;
public int Missing_adj() {return missing_adj;} public Bry_fmtr Missing_adj_(int v) {missing_adj = v; return this;} int missing_adj;
public boolean Fail_when_invalid_escapes() {return fail_when_invalid_escapes;} public Bry_fmtr Fail_when_invalid_escapes_(boolean v) {fail_when_invalid_escapes = v; return this;} private boolean fail_when_invalid_escapes = true;
public Bry_fmtr Compile() {
synchronized (this) { // THREAD: DATE:2015-04-29
Bry_bfr lkp_bfr = Bry_bfr.new_(16);
int fmt_len = fmt.length; int fmt_end = fmt_len - 1; int fmt_pos = 0;
byte[] trg_bry = new byte[fmt_len]; int trg_pos = 0;
boolean lkp_is_active = false, lkp_is_numeric = true;
byte nxt_byte, tmp_byte;
List_adp list = List_adp_.new_();
fmt_args_exist = false;
while (true) {
if (fmt_pos > fmt_end) break;
byte cur_byte = fmt[fmt_pos];
if (lkp_is_active) {
if (cur_byte == char_arg_end) {
if (lkp_is_numeric)
list.Add(Bry_fmtr_itm.arg_(lkp_bfr.To_int(0) - baseInt));
else {
byte[] key_fmt = lkp_bfr.To_bry();
Object idx_ref = keys.Get_by(Bry_obj_ref.New(key_fmt));
if (idx_ref == null) {
int lkp_bfr_len = lkp_bfr.Len();
byte[] lkp_bry = lkp_bfr.Bfr();
trg_bry[trg_pos++] = char_escape;
trg_bry[trg_pos++] = char_arg_bgn;
for (int i = 0; i < lkp_bfr_len; i++)
trg_bry[trg_pos++] = lkp_bry[i];
trg_bry[trg_pos++] = char_arg_end;
}
else {
list.Add(Bry_fmtr_itm.arg_(((Int_obj_val)idx_ref).Val() - baseInt));
}
}
lkp_is_active = false;
lkp_bfr.Clear();
fmt_args_exist = true;
}
else {
lkp_bfr.Add_byte(cur_byte);
switch (cur_byte) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
break;
default:
lkp_is_numeric = false;
break;
}
}
fmt_pos += 1;
}
else if (cur_byte == char_escape) {
if (fmt_pos == fmt_end) {
if (fail_when_invalid_escapes)
throw Err_.new_wo_type("escape char encountered but no more chars left");
else {
trg_bry[trg_pos] = cur_byte;
break;
}
}
nxt_byte = fmt[fmt_pos + 1];
if (nxt_byte == char_arg_bgn) {
if (trg_pos > 0) {list.Add(Bry_fmtr_itm.dat_(trg_bry, trg_pos)); trg_pos = 0;} // something pending; add it to list
int eval_lhs_bgn = fmt_pos + 2;
if (eval_lhs_bgn < fmt_len && fmt[eval_lhs_bgn] == char_eval_bgn) { // eval found
fmt_pos = Compile_eval_cmd(fmt, fmt_len, eval_lhs_bgn, list);
continue;
}
else {
lkp_is_active = true;
lkp_is_numeric = true;
}
}
else { // ~{0}; ~~ -> ~; ~n -> newLine; ~t -> tab
if (nxt_byte == char_escape) tmp_byte = char_escape;
else if (nxt_byte == char_escape_nl) tmp_byte = Byte_ascii.Nl;
else if (nxt_byte == char_escape_tab) tmp_byte = Byte_ascii.Tab;
else {
if (fail_when_invalid_escapes) throw Err_.new_wo_type("unknown escape code", "code", Char_.By_int(nxt_byte), "fmt_pos", fmt_pos + 1);
else
tmp_byte = cur_byte;
}
trg_bry[trg_pos++] = tmp_byte;
}
fmt_pos += 2;
}
else {
trg_bry[trg_pos++] = cur_byte;
fmt_pos += 1;
}
}
if (lkp_is_active) throw Err_.new_wo_type("idx mode not closed");
if (trg_pos > 0) {list.Add(Bry_fmtr_itm.dat_(trg_bry, trg_pos)); trg_pos = 0;}
itms = (Bry_fmtr_itm[])list.To_ary(Bry_fmtr_itm.class);
itms_len = itms.length;
return this;
}
}
int Compile_eval_cmd(byte[] fmt, int fmt_len, int eval_lhs_bgn, List_adp list) {
int eval_lhs_end = Bry_find_.Find_fwd(fmt, char_eval_end, eval_lhs_bgn + Int_.Const_dlm_len, fmt_len); if (eval_lhs_end == Bry_find_.Not_found) throw Err_.new_wo_type("eval_lhs_end_invalid: could not find eval_lhs_end", "snip", String_.new_u8(fmt, eval_lhs_bgn, fmt_len));
byte[] eval_dlm = Bry_.Mid(fmt, eval_lhs_bgn , eval_lhs_end + Int_.Const_dlm_len);
int eval_rhs_bgn = Bry_find_.Find_fwd(fmt, eval_dlm , eval_lhs_end + Int_.Const_dlm_len, fmt_len); if (eval_rhs_bgn == Bry_find_.Not_found) throw Err_.new_wo_type("eval_rhs_bgn_invalid: could not find eval_rhs_bgn", "snip", String_.new_u8(fmt, eval_lhs_end, fmt_len));
byte[] eval_cmd = Bry_.Mid(fmt, eval_lhs_end + Int_.Const_dlm_len, eval_rhs_bgn);
byte[] eval_rslt = eval_mgr.Eval(eval_cmd);
int eval_rhs_end = eval_rhs_bgn + Int_.Const_dlm_len + eval_dlm.length;
if (eval_rslt == null) eval_rslt = Bry_.Mid(fmt, eval_lhs_bgn - 2, eval_rhs_end); // not found; return original argument
list.Add(Bry_fmtr_itm.dat_bry_(eval_rslt));
return eval_rhs_end;
}
static final String GRP_KEY = "gplx.Bry_fmtr";
public boolean Fmt_args_exist() {return fmt_args_exist;} private boolean fmt_args_exist;
boolean dirty = true;
int baseInt = 0;
public static final byte char_escape = Byte_ascii.Tilde, char_arg_bgn = Byte_ascii.Curly_bgn, char_arg_end = Byte_ascii.Curly_end, char_escape_nl = Byte_ascii.Ltr_n, char_escape_tab = Byte_ascii.Ltr_t, char_eval_bgn = Byte_ascii.Lt, char_eval_end = Byte_ascii.Gt;
public static final Bry_fmtr Null = new Bry_fmtr().Fmt_("");
public static Bry_fmtr tmp_() {return new Bry_fmtr().Fmt_("").Keys_();}
public static Bry_fmtr new_(String fmt, String... keys) {return new Bry_fmtr().Fmt_(fmt).Keys_(keys);} // NOTE: keys may seem redundant, but are needed to align ordinals with proc; EX: fmt may be "~{A} ~{B}" or "~{B} ~{A}"; call will always be Bld(a, b); passing in "A", "B" guarantees A is 0 and B is 1;
public static Bry_fmtr new_(byte[] fmt, String... keys) {return new Bry_fmtr().Fmt_(fmt).Keys_(keys);} // NOTE: keys may seem redundant, but are needed to align ordinals with proc; EX: fmt may be "~{A} ~{B}" or "~{B} ~{A}"; call will always be Bld(a, b); passing in "A", "B" guarantees A is 0 and B is 1;
public static Bry_fmtr new_() {return new Bry_fmtr();}
public static Bry_fmtr keys_(String... keys) {return new Bry_fmtr().Keys_(keys);}
public static Bry_fmtr new_bry_(byte[] fmt, String... keys) {return new Bry_fmtr().Fmt_(fmt).Keys_(keys);}
public static String New_fmt_str(String key, Object[] args) {
tmp_bfr.Clear();
tmp_bfr.Add_str_u8(key);
tmp_bfr.Add_byte(Byte_ascii.Colon);
int args_len = args.length;
for (int i = 0; i < args_len; i++) { // add " 0='~{0}'"
tmp_bfr.Add_byte(Byte_ascii.Space);
tmp_bfr.Add_int_variable(i);
tmp_bfr.Add_byte(Byte_ascii.Eq);
tmp_bfr.Add_byte(Byte_ascii.Apos);
tmp_bfr.Add_byte(Byte_ascii.Tilde);
tmp_bfr.Add_byte(Byte_ascii.Curly_bgn);
tmp_bfr.Add_int_variable(i);
tmp_bfr.Add_byte(Byte_ascii.Curly_end);
tmp_bfr.Add_byte(Byte_ascii.Apos);
}
return tmp_bfr.To_str_and_clear();
} static Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
public void Bld_bfr_many_and_set_fmt(Object... args) {
Bry_bfr bfr = Bry_bfr.new_();
this.Bld_bfr_many(bfr, args);
byte[] bry = bfr.To_bry_and_clear();
this.Fmt_(bry).Compile();
}
public static String Escape_tilde(String v) {return String_.Replace(v, "~", "~~");}
}

View File

@@ -0,0 +1,22 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public interface Bry_fmtr_eval_mgr {
boolean Enabled(); void Enabled_(boolean v);
byte[] Eval(byte[] cmd);
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bry_fmtr_eval_mgr_ {
public static Io_url Eval_url(Bry_fmtr_eval_mgr eval_mgr, byte[] fmt) {
if (eval_mgr == null) return Io_url_.new_any_(String_.new_u8(fmt));
Bry_bfr bfr = Bry_bfr.reset_(255);
Bry_fmtr fmtr = Bry_fmtr.tmp_();
fmtr.Eval_mgr_(eval_mgr).Fmt_(fmt).Bld_bfr_none(bfr);
return Io_url_.new_any_(bfr.To_str_and_clear());
}
}

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.langs.gfs.*;
public class Bry_fmtr_eval_mgr_gfs implements Bry_fmtr_eval_mgr {
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public byte[] Eval(byte[] cmd) {
return enabled ? Bry_.new_u8(Object_.Xto_str_strict_or_null_mark(GfsCore.Instance.ExecText(String_.new_u8(cmd)))) : null;
}
public static final Bry_fmtr_eval_mgr_gfs Instance = new Bry_fmtr_eval_mgr_gfs(); Bry_fmtr_eval_mgr_gfs() {}
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
public class Bry_fmtr_itm {
public boolean Arg;
public int ArgIdx;
public byte[] Dat;
public String DatStr() {
if (datStr == null) datStr = String_.new_u8(Dat);
return datStr;
} String datStr;
public static Bry_fmtr_itm arg_(int idx) {return new Bry_fmtr_itm(true, idx, Bry_.Empty);}
public static Bry_fmtr_itm dat_(byte[] dat, int len) {return new Bry_fmtr_itm(false, -1, Bry_.Mid(dat, 0, len));}
public static Bry_fmtr_itm dat_bry_(byte[] bry) {return new Bry_fmtr_itm(false, -1, bry);}
Bry_fmtr_itm(boolean arg, int argIdx, byte[] dat) {
this.Arg = arg; this.ArgIdx = argIdx; this.Dat = dat;
}
}

View File

@@ -0,0 +1,78 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import org.junit.*;
public class Bry_fmtr_tst {
@Test public void Idx_text() {tst_Format("a", "a");}
@Test public void Idx_1() {tst_Format("a", "~{0}", "a");}
@Test public void Idx_3() {tst_Format("abc", "~{0}~{1}~{2}", "a", "b", "c");}
@Test public void Idx_mix() {tst_Format("abcde", "a~{0}c~{1}e", "b", "d");}
@Test public void Key_basic() {tst("~{key}" , String_.Ary("key") , ary_("a") , "a");}
@Test public void Key_mult() {tst("~{key1}~{key2}" , String_.Ary("key1", "key2") , ary_("a", "b") , "ab");}
@Test public void Key_mix() {tst("~{key1}~{1}" , String_.Ary("key1", "key2") , ary_("a", "b") , "ab");}
@Test public void Key_repeat() {tst("~{key1}~{key1}" , String_.Ary("key1") , ary_("a") , "aa");}
@Test public void Simple() {
Bry_fmtr fmtr = Bry_fmtr.new_("0~{key1}1~{key2}2", "key1", "key2");
Tfds.Eq("0.1,2", fmtr.Bld_str_many(".", ","));
}
@Test public void Cmd() {
Bry_fmtr_tst_mok mok = new Bry_fmtr_tst_mok();
Bry_fmtr fmtr = Bry_fmtr.new_("0~{key1}2~{<>3<>}4", "key1").Eval_mgr_(mok);
Tfds.Eq("012~{<>3<>}4", fmtr.Bld_str_many("1"));
mok.Enabled_(true);
Tfds.Eq("01234", fmtr.Bld_str_many("1"));
}
@Test public void Err_missing_idx() {tst_Format("~{0}", "~{0}");}
String[] ary_(String... ary) {return ary;}
void tst(String fmt, String[] keys, String[] args, String expd) {
Bry_fmtr fmtr = new Bry_fmtr().Fmt_(Bry_.new_u8(fmt));
fmtr.Keys_(keys);
String actl = fmtr.Bld_str_many(args);
Tfds.Eq(expd, actl);
}
void tst_Format(String expd, String fmt, String... args) {
Bry_fmtr fmtr = new Bry_fmtr().Fmt_(fmt);
Tfds.Eq(expd, fmtr.Bld_str_many(args));
}
@Test public void Bld_bfr_many_and_set_fmt() {
Bry_fmtr_fxt fxt = new Bry_fmtr_fxt().Clear();
fxt.Bld_bfr_many_and_set_fmt("a~{0}c", Object_.Ary("b"), "abc");
}
@Test public void Escape_tilde() {
Tfds.Eq("~~~~~~", Bry_fmtr.Escape_tilde("~~~"));
}
}
class Bry_fmtr_tst_mok implements Bry_fmtr_eval_mgr {
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {enabled = v;} private boolean enabled;
public byte[] Eval(byte[] cmd) {
return enabled ? cmd : null;
}
}
class Bry_fmtr_fxt {
public Bry_fmtr_fxt Clear() {
if (fmtr == null) {
fmtr = Bry_fmtr.new_();
}
return this;
} private Bry_fmtr fmtr;
public void Bld_bfr_many_and_set_fmt(String fmt, Object[] args, String expd) {
fmtr.Fmt_(fmt);
fmtr.Bld_bfr_many_and_set_fmt(args);
Tfds.Eq(expd, String_.new_a7(fmtr.Fmt()));
}
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.brys.fmtrs; import gplx.*; import gplx.core.*; import gplx.core.brys.*;
import gplx.core.brys.*;
public class Bry_fmtr_vals extends gplx.core.brys.Bfr_arg_base {
private final Bry_fmtr fmtr; private Object[] vals;
Bry_fmtr_vals(Bry_fmtr fmtr) {this.fmtr = fmtr;}
public Bry_fmtr_vals Vals_(Object... v) {this.vals = v; return this;}
@Override public void Bfr_arg__add(Bry_bfr bfr) {
fmtr.Bld_bfr_ary(bfr, vals);
}
public static Bry_fmtr_vals new_fmt(String fmt, String... keys) {
Bry_fmtr fmtr = Bry_fmtr.new_(fmt, keys);
return new Bry_fmtr_vals(fmtr);
}
public static Bry_fmtr_vals new_(Bry_fmtr fmtr) {return new Bry_fmtr_vals(fmtr);}
}

View File

@@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
public class GfoFld {
public String Key() {return key;} private String key;
public ClassXtn Type() {return type;} ClassXtn type;
public static final GfoFld Null = new_(String_.Null_mark, ObjectClassXtn.Instance);
public static GfoFld new_(String key, ClassXtn c) {
GfoFld rv = new GfoFld();
rv.key = key; rv.type = c;
return rv;
}
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
public interface GfoFldList {
int Count();
boolean Has(String key);
int Idx_of(String key);
GfoFld Get_at(int i);
GfoFld FetchOrNull(String key);
GfoFldList Add(String key, ClassXtn c);
String To_str();
}

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class GfoFldList_ {
public static final GfoFldList Null = new GfoFldList_null();
public static GfoFldList new_() {return new GfoFldList_base();}
public static GfoFldList str_(String... names) {
GfoFldList rv = new GfoFldList_base();
for (String name : names)
rv.Add(name, StringClassXtn.Instance);
return rv;
}
}
class GfoFldList_base implements GfoFldList {
public int Count() {return hash.Count();}
public boolean Has(String key) {return hash.Has(key);}
public int Idx_of(String key) {
Object rv = idxs.Get_by(key);
return rv == null ? List_adp_.NotFound : Int_.cast(rv);
}
public GfoFld Get_at(int i) {return (GfoFld)hash.Get_at(i);}
public GfoFld FetchOrNull(String key) {return (GfoFld)hash.Get_by(key);}
public GfoFldList Add(String key, ClassXtn c) {
GfoFld fld = GfoFld.new_(key, c);
hash.Add(key, fld);
idxs.Add(key, idxs.Count());
return this;
}
public String To_str() {
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < hash.Count(); i++) {
GfoFld fld = this.Get_at(i);
sb.Add(fld.Key()).Add("|");
}
return sb.To_str();
}
Ordered_hash hash = Ordered_hash_.New(); Hash_adp idxs = Hash_adp_.new_(); // PERF: idxs used for Idx_of; need to recalc if Del ever added
}
class GfoFldList_null implements GfoFldList {
public int Count() {return 0;}
public boolean Has(String key) {return false;}
public int Idx_of(String key) {return List_adp_.NotFound;}
public GfoFld Get_at(int i) {return GfoFld.Null;}
public GfoFld FetchOrNull(String key) {return null;}
public GfoFldList Add(String key, ClassXtn typx) {return this;}
public String To_str() {return "<<GfoFldList_.Null>>";}
}

View 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.core.gfo_ndes; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class GfoNde implements GfoInvkAble {
public GfoFldList Flds() {return flds;} GfoFldList flds;
public Hash_adp EnvVars() {return envVars;} Hash_adp envVars = Hash_adp_.new_();
public String Name() {return name;} public GfoNde Name_(String v) {name = v; return this;} private String name;
public Object ReadAt(int i) {ChkIdx(i); return ary[i];}
public void WriteAt(int i, Object val) {ChkIdx(i); ary[i] = val;}
public Object Read(String key) {int i = IndexOfOrFail(key); return ary[i];}
public void Write(String key, Object val) {int i = IndexOfOrFail(key); ary[i] = val;}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return Read(k);}
public GfoNdeList Subs() {return subs;} GfoNdeList subs = GfoNdeList_.new_();
public GfoFldList SubFlds() {return subFlds;} GfoFldList subFlds = GfoFldList_.new_();
public void XtoStr_wtr(DataWtr wtr) {XtoStr_wtr(this, wtr);}// TEST
public String To_str() {
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < aryLen; i++) {
String key = i >= flds.Count() ? "<< NULL " + i + " >>" : flds.Get_at(i).Key();
String val = i >= aryLen ? "<< NULL " + i + " >>" : Object_.Xto_str_strict_or_null_mark(ary[i]);
sb.Add(key).Add("=").Add(val);
}
return sb.To_str();
}
int IndexOfOrFail(String key) {
int i = flds.Idx_of(key);
if ((i < 0 || i >= aryLen)) throw Err_.new_wo_type("field name not found", "name", key, "index", i, "count", this.Flds().Count());
return i;
}
boolean ChkIdx(int i) {if (i < 0 || i >= aryLen) throw Err_.new_missing_idx(i, aryLen); return true;}
Object[] ary; int type; int aryLen;
@gplx.Internal protected GfoNde(int type, String name, GfoFldList flds, Object[] ary, GfoFldList subFlds, GfoNde[] subAry) {
this.type = type; this.name = name; this.flds = flds; this.ary = ary; aryLen = Array_.Len(ary); this.subFlds = subFlds;
for (GfoNde sub : subAry)
subs.Add(sub);
}
static void XtoStr_wtr(GfoNde nde, DataWtr wtr) {
if (nde.type == GfoNde_.Type_Leaf) {
wtr.WriteLeafBgn("flds");
for (int i = 0; i < nde.ary.length; i++)
wtr.WriteData(nde.Flds().Get_at(i).Key(), nde.ReadAt(i));
wtr.WriteLeafEnd();
}
else {
if (nde.type == GfoNde_.Type_Node) // never write node info for root
wtr.WriteTableBgn(nde.Name(), nde.SubFlds());
for (int i = 0; i < nde.Subs().Count(); i++) {
GfoNde sub = nde.Subs().FetchAt_asGfoNde(i);
XtoStr_wtr(sub, wtr);
}
if (nde.type == GfoNde_.Type_Node)
wtr.WriteNodeEnd();
}
}
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
public class GfoNdeFxt {
public GfoNde root_(GfoNde... subs) {return GfoNde_.root_(subs);}
public GfoNde tbl_(String name, GfoNde... rows) {return GfoNde_.tbl_(name, GfoFldList_.Null, rows);}
public GfoNde nde_(String name, GfoFldList flds, GfoNde... subs) {return GfoNde_.tbl_(name, flds, subs);}
public GfoNde row_(GfoFldList flds, Object... vals) {return GfoNde_.vals_(flds, vals);}
public GfoNde row_vals_(Object... vals) {return GfoNde_.vals_(GfoFldList_by_count_(vals.length), vals);}
public GfoNde csv_dat_(GfoNde... rows) {return GfoNde_.tbl_("", GfoFldList_.Null, rows);}
public GfoNde csv_hdr_(GfoFldList flds, GfoNde... rows) {return GfoNde_.tbl_("", flds, rows);}
public static GfoNdeFxt new_() {return new GfoNdeFxt();}
static GfoFldList GfoFldList_by_count_(int count) {
GfoFldList rv = GfoFldList_.new_();
for (int i = 0; i < count; i++)
rv.Add("fld" + Int_.To_str(i), StringClassXtn.Instance);
return rv;
}
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
import gplx.lists.*; /*ComparerAble*/
public interface GfoNdeList {
int Count();
GfoNde FetchAt_asGfoNde(int index);
void Add(GfoNde rcd);
void Del(GfoNde rcd);
void Clear();
void Sort_by(ComparerAble comparer);
}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
import gplx.lists.*; /*ComparerAble*/
public class GfoNdeList_ {
public static final GfoNdeList Null = new GfoNdeList_null();
public static GfoNdeList new_() {return new GfoNdeList_base();}
}
class GfoNdeList_base implements GfoNdeList {
public int Count() {return list.Count();}
public GfoNde FetchAt_asGfoNde(int i) {return (GfoNde)list.Get_at(i);}
public void Add(GfoNde rcd) {list.Add(rcd);}
public void Del(GfoNde rcd) {list.Del(rcd);}
public void Clear() {list.Clear();}
public void Sort_by(ComparerAble comparer) {list.Sort_by(comparer);}
List_adp list = List_adp_.new_();
}
class GfoNdeList_null implements GfoNdeList {
public int Count() {return 0;}
public GfoNde FetchAt_asGfoNde(int index) {return null;}
public void Add(GfoNde rcd) {}
public void Del(GfoNde rcd) {}
public void Clear() {}
public void Sort_by(ComparerAble comparer) {}
}

View File

@@ -0,0 +1,46 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_ndes; import gplx.*; import gplx.core.*;
public class GfoNde_ {
public static final GfoNde[] Ary_empty = new GfoNde[0];
public static GfoNde[] ary_(GfoNde... ary) {return ary;}
public static GfoNde as_(Object obj) {return obj instanceof GfoNde ? (GfoNde)obj : null;}
public static GfoNde root_(GfoNde... subs) {return new GfoNde(GfoNde_.Type_Root, "RootName", GfoFldList_.Null, Object_.Ary_empty, GfoFldList_.Null, subs);}
public static GfoNde tbl_(String name, GfoFldList flds, GfoNde... rows) {return new GfoNde(GfoNde_.Type_Node, name, flds, Object_.Ary_empty, flds, rows);}
public static GfoNde vals_(GfoFldList flds, Object[] ary) {return new GfoNde(GfoNde_.Type_Leaf, "row", flds, ary, GfoFldList_.Null, Ary_empty);}
public static GfoNde vals_params_(GfoFldList flds, Object... ary) {return new GfoNde(GfoNde_.Type_Leaf, "row", flds, ary, GfoFldList_.Null, Ary_empty);}
public static GfoNde nde_(String name, Object[] ary, GfoNde... subs) {return new GfoNde(GfoNde_.Type_Node, name, GfoFldList_.Null, ary, GfoFldList_.Null, subs);}
public static GfoNde rdr_(DataRdr rdr) {
try {
List_adp rows = List_adp_.new_();
GfoFldList flds = GfoFldList_.new_();
int fldLen = rdr.FieldCount();
for (int i = 0; i < fldLen; i++)
flds.Add(rdr.KeyAt(i), ObjectClassXtn.Instance);
while (rdr.MoveNextPeer()) {
Object[] valAry = new Object[fldLen];
for (int i = 0; i < fldLen; i++)
valAry[i] = rdr.ReadAt(i);
rows.Add(GfoNde_.vals_(flds, valAry));
}
return GfoNde_.tbl_("", flds, (GfoNde[])rows.To_ary(GfoNde.class));
}
finally {rdr.Rls();}
}
@gplx.Internal protected static final int Type_Leaf = 1, Type_Node = 2, Type_Root = 3;
}

View File

@@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_regys; import gplx.*; import gplx.core.*;
public interface GfoMsgParser {
GfoMsg ParseToMsg(String s);
}

View File

@@ -0,0 +1,95 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_regys; import gplx.*; import gplx.core.*;
import gplx.langs.gfs.*;
public class GfoRegy implements GfoInvkAble {
public int Count() {return hash.Count();}
public Hash_adp Parsers() {return parsers;} Hash_adp parsers = Hash_adp_.new_();
public GfoRegyItm FetchOrNull(String key) {return (GfoRegyItm)hash.Get_by(key);}
public Object FetchValOrFail(String key) {
GfoRegyItm rv = (GfoRegyItm)hash.Get_by(key); if (rv == null) throw Err_.new_wo_type("regy does not have key", "key", key);
return rv.Val();
}
public Object FetchValOrNull(String key) {return FetchValOr(key, null);}
public Object FetchValOr(String key, Object or) {
GfoRegyItm itm = FetchOrNull(key);
return itm == null ? or : itm.Val();
}
public void Del(String key) {hash.Del(key);}
public void RegObj(String key, Object val) {RegItm(key, val, GfoRegyItm.ValType_Obj, Io_url_.Empty);}
public void RegDir(Io_url dirUrl, String match, boolean recur, String chopBgn, String chopEnd) {
Io_url[] filUrls = Io_mgr.Instance.QueryDir_args(dirUrl).FilPath_(match).Recur_(recur).ExecAsUrlAry();
if (filUrls.length == 0 && !Io_mgr.Instance.ExistsDir(dirUrl)) {UsrDlg_.Instance.Stop(UsrMsg.new_("dirUrl does not exist").Add("dirUrl", dirUrl.Xto_api())); return;}
for (Io_url filUrl : filUrls) {
String key = filUrl.NameAndExt();
int pos = String_.Find_none;
if (String_.EqNot(chopBgn, "")) {
pos = String_.FindFwd(key, chopBgn);
if (pos == String_.Len(key) - 1)
throw Err_.new_wo_type(Err_ChopBgn, "key", key, "chopBgn", chopBgn);
else if (pos != String_.Find_none)
key = String_.Mid(key, pos + 1);
}
if (String_.EqNot(chopEnd, "")) {
pos = String_.FindBwd(key, chopEnd);
if (pos == 0)
throw Err_.new_wo_type(Err_ChopEnd, "key", key, "chopEnd", chopEnd);
else if (pos != String_.Find_none)
key = String_.MidByLen(key, 0, pos);
}
if (hash.Has(key)) throw Err_.new_wo_type(Err_Dupe, "key", key, "filUrl", filUrl);
RegItm(key, null, GfoRegyItm.ValType_Url, filUrl);
}
}
public void RegObjByType(String key, String val, String type) {
Object o = val;
if (String_.EqNot(type, StringClassXtn.Key_const)) {
ParseAble parser = (ParseAble)parsers.Get_by(type);
if (parser == null) throw Err_.new_wo_type("could not find parser", "type", type, "key", key, "val", val);
o = parser.ParseAsObj(val);
}
RegItm(key, o, GfoRegyItm.ValType_Obj, Io_url_.Empty);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_RegDir)) {
Io_url dir = m.ReadIoUrl("dir");
String match = m.ReadStrOr("match", "*.*");
boolean recur = m.ReadBoolOr("recur", false);
String chopBgn = m.ReadStrOr("chopBgn", "");
String chopEnd = m.ReadStrOr("chopEnd", ".");
if (ctx.Deny()) return this;
RegDir(dir, match, recur, chopBgn, chopEnd);
}
else if (ctx.Match(k, Invk_RegObj)) {
String key = m.ReadStr("key");
String val = m.ReadStr("val");
String type = m.ReadStrOr("type", StringClassXtn.Key_const);
if (ctx.Deny()) return this;
RegObjByType(key, val, type);
}
else return GfoInvkAble_.Rv_unhandled;
return this;
} public static final String Invk_RegDir = "RegDir", Invk_RegObj = "RegObj";
void RegItm(String key, Object val, int valType, Io_url url) {
hash.Add_if_dupe_use_nth(key, new GfoRegyItm(key, val, valType, url));
}
Hash_adp hash = Hash_adp_.new_();
public static final String Err_ChopBgn = "chopBgn results in null key", Err_ChopEnd = "chopEnd results in null key", Err_Dupe = "key already registered";
public static final GfoRegy Instance = new GfoRegy(); GfoRegy() {}
@gplx.Internal protected static GfoRegy new_() {return new GfoRegy();}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_regys; import gplx.*; import gplx.core.*;
public class GfoRegyItm {
public String Key() {return key;} private String key;
public Object Val() {return val;} Object val;
public Io_url Url() {return url;} Io_url url;
public int ValType() {return valType;} int valType;
public GfoRegyItm(String key, Object val, int valType, Io_url url) {this.key = key; this.val = val; this.valType = valType; this.url = url;}
public static final int
ValType_Obj = 1
, ValType_Url = 2
, ValType_B64 = 3
;
}

View 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.core.gfo_regys; import gplx.*; import gplx.core.*;
import org.junit.*;
public class GfoRegy_RegDir_tst {
@Before public void setup() {
regy = GfoRegy.new_();
Io_mgr.Instance.InitEngine_mem();
root = Io_url_.mem_dir_("mem/root");
} GfoRegy regy; Io_url root;
@Test public void Basic() {
ini_fil("101_tsta.txt");
ini_fil("102_tstb.txt");
ini_fil("103_tstc.png");
ini_fil("dir1", "104_tstd.txt");
regy.RegDir(root, "*.txt", false, "_", ".");
tst_Count(2);
tst_Exists("tsta");
tst_Exists("tstb");
}
@Test public void Err_dupe() {
ini_fil("101_tsta.txt");
ini_fil("102_tsta.txt");
try {regy.RegDir(root, "*.txt", false, "_", ".");}
catch (Exception e) {Tfds.Err_has(e, GfoRegy.Err_Dupe); return;}
Tfds.Fail_expdError();
}
@Test public void Err_chopBgn() {
ini_fil("123_");
try {regy.RegDir(root, "*", false, "_", ".");}
catch (Exception e) {Tfds.Err_has(e, GfoRegy.Err_ChopBgn); return;}
Tfds.Fail_expdError();
}
@Test public void Err_chopEnd() {
ini_fil(".txt");
try {regy.RegDir(root, "*.txt", false, "_", ".");}
catch (Exception e) {Tfds.Err_has(e, GfoRegy.Err_ChopEnd); return;}
Tfds.Fail_expdError();
}
void tst_Count(int expd) {Tfds.Eq(expd, regy.Count());}
void tst_Exists(String expd) {
GfoRegyItm itm = regy.FetchOrNull(expd);
Tfds.Eq_nullNot(itm);
}
void ini_fil(String... nest) {Io_mgr.Instance.SaveFilStr(root.GenSubFil_nest(nest), "");}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.gfo_regys; import gplx.*; import gplx.core.*;
import org.junit.*;
public class GfoRegy_basic_tst {
@Before public void setup() {
regy = GfoRegy.new_();
} GfoRegy regy;
@Test public void RegObjByType() {
regy.Parsers().Add("Io_url", Io_url_.Parser);
Io_url expd = Io_url_.new_any_("C:\\fil.txt");
regy.RegObjByType("test", expd.Xto_api(), "Io_url");
Io_url actl = (Io_url)regy.FetchValOr("test", Io_url_.Empty);
Tfds.Eq(expd.Xto_api(), actl.Xto_api());
}
}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.brys.fmtrs.*;
public class IoEngine_xrg_downloadFil {
public String Src() {return src;} public IoEngine_xrg_downloadFil Src_(String v) {src = v; return this;} private String src;
public Io_url Trg() {return trg;} public IoEngine_xrg_downloadFil Trg_(Io_url v) {trg = v; return this;} private Io_url trg;

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.langs.gfs.*;
public class IoItmFil extends IoItm_base {
@Override public int TypeId() {return IoItmFil.Type_Fil;} @Override public boolean Type_dir() {return false;} @Override public boolean Type_fil() {return true;} public static final int Type_Fil = 2;
public boolean Exists() {return size != Size_invalid;} // NOTE: questionable logic, but preserved for historical reasons; requires that length be set to -1 if !.exists

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.langs.gfs.*;
public abstract class IoItm_base implements GfoInvkAble, CompareAble {
public abstract int TypeId(); public abstract boolean Type_dir(); public abstract boolean Type_fil();
public Io_url Url() {return ownerDir == null ? url : ownerDir.Url().GenSubFil(name); /*NOTE: must call .Url*/} Io_url url;

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.langs.gfs.*;
public class IoUrlInfoRegy implements GfoInvkAble {
public void Reg(IoUrlInfo info) {hash.Add_if_dupe_use_nth(info.Key(), info);}
public IoUrlInfo Match(String raw) {

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
import gplx.core.strings.*; import gplx.langs.gfs.*;
public class IoUrlTypeRegy implements GfoInvkAble {
public String[] FetchAryOr(String key, String... or) {
IoUrlTypeGrp itm = (IoUrlTypeGrp)hash.Get_by(key);

View File

@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.stores.*; /*GfoNdeRdr_*/
import gplx.core.gfo_regys.*;
public class IoZipWkr {
public Io_url ExeUrl() {return (Io_url)GfoRegy.Instance.FetchValOrFail(Regy_ExeUrl);}
public String ExeArgFmt() {return (String)GfoRegy.Instance.FetchValOrFail(Regy_ExeArgFmt);}

View File

@@ -16,10 +16,10 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.brys.*;
import gplx.core.brys.args.*; import gplx.core.brys.fmtrs.*;
public class Io_download_fmt {
private final Io_size_fmtr_arg size_fmtr_arg = new Io_size_fmtr_arg(), rate_fmtr_arg = new Io_size_fmtr_arg().Suffix_(Bry_.new_a7("ps"));
private final Bry_fmtr_arg_time prog_left_fmtr_arg = new Bry_fmtr_arg_time(); private final Bry_fmtr_arg_decimal_int prog_pct_fmtr_arg = new Bry_fmtr_arg_decimal_int().Places_(2);
private final Bfr_arg__time prog_left_fmtr_arg = new Bfr_arg__time(); private final Bfr_arg__decimal_int prog_pct_fmtr_arg = new Bfr_arg__decimal_int().Places_(2);
private long time_checkpoint_interval = 250;
private long time_checkpoint = 0;
private long time_prv = 0;

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.ios; import gplx.*; import gplx.core.*;
import gplx.core.brys.*;
public class Io_size_ {
public static String To_str(long val) {
long cur = val; int pow = 0;
@@ -98,10 +99,10 @@ public class Io_size_ {
return val == Int_.Min_value ? cur : (val * Io_mgr.Len_mb_long);
}
}
class Io_size_fmtr_arg implements Bry_fmtr_arg {
class Io_size_fmtr_arg extends gplx.core.brys.Bfr_arg_base {
public long Val() {return val;} public Io_size_fmtr_arg Val_(long v) {val = v; return this;} long val;
public byte[] Suffix() {return suffix;} public Io_size_fmtr_arg Suffix_(byte[] v) {suffix = v; return this;} private byte[] suffix;
public void Fmt__do(Bry_bfr bfr) {
@Override public void Bfr_arg__add(Bry_bfr bfr) {
long cur = val; int pow = 0;
while (cur >= 1024) {
cur /= 1024;

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.core.log_msgs; import gplx.*; import gplx.core.*;
import gplx.core.brys.fmtrs.*;
public class Gfo_msg_itm implements Gfo_msg_obj {
public Gfo_msg_itm(Gfo_msg_grp owner, int uid, byte cmd, byte[] key_bry, byte[] fmt, boolean add_to_owner) {
this.owner = owner; this.uid = uid; this.cmd = cmd; this.key_bry = key_bry; this.fmt = fmt;

View File

@@ -16,20 +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.core.primitives; import gplx.*; import gplx.core.*;
public class Bry_obj_ref {
public byte[] Val() {return val;} public Bry_obj_ref Val_(byte[] v) {val = v; return this;} private byte[] val;
@Override public int hashCode() {return CalcHashCode(val, 0, val.length);}
@Override public boolean equals(Object obj) {return obj == null ? false : Bry_.Eq(val, ((Bry_obj_ref)obj).Val());} // NOTE: strange, but null check needed; throws null error; EX.WP: File:Eug<75>ne Delacroix - La libert<72> guidant le peuple.jpg
import gplx.core.brys.*;
public class Bry_obj_ref implements gplx.core.brys.Bfr_arg {
public byte[] Val() {return val;} private byte[] val;
public int Val_bgn() {return val_bgn;} private int val_bgn;
public int Val_end() {return val_end;} private int val_end;
public Bry_obj_ref Val_(byte[] val) {this.val = val; this.val_bgn = 0; this.val_end = val.length; return this;}
public Bry_obj_ref Mid_(byte[] val, int val_bgn, int val_end) {this.val = val; this.val_bgn = val_bgn; this.val_end = val_end; return this;}
@Override public int hashCode() {return CalcHashCode(val, val_bgn, val_end);}
@Override public boolean equals(Object obj) {
if (obj == null) return false; // NOTE: strange, but null check needed; throws null error; EX.WP: File:Eug<75>ne Delacroix - La libert<72> guidant le peuple.jpg
Bry_obj_ref comp = (Bry_obj_ref)obj;
return Bry_.Match(val, val_bgn, val_end, comp.val, comp.val_bgn, comp.val_end);
}
public void Bfr_arg__clear() {val = null;}
public boolean Bfr_arg__exists() {return val != null && val_end > val_bgn;}
public void Bfr_arg__add(Bry_bfr bfr) {
if (Bfr_arg__exists())
bfr.Add_mid(val, val_bgn, val_end);
}
public static int CalcHashCode(byte[] ary, int bgn, int end) {
int rv = 0;
for (int i = bgn; i < end; i++)
rv = (31 * rv) + ary[i];
return rv;
}
public static Bry_obj_ref null_() {return new_(null);}
public static Bry_obj_ref new_(byte[] val) {
Bry_obj_ref rv = new Bry_obj_ref();
rv.val = val;
return rv;
} private Bry_obj_ref() {}
public static Bry_obj_ref New_empty() {return New(Bry_.Empty);}
public static Bry_obj_ref New(byte[] val) {return new Bry_obj_ref().Val_(val);}
}

View File

@@ -16,6 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import gplx.core.gfo_ndes.*;
public class DsvDataRdrOpts {
public boolean HasHeader() {return hasHeader;} public DsvDataRdrOpts HasHeader_(boolean val) {hasHeader = val; return this;} private boolean hasHeader = false;
public String NewLineSep() {return newLineSep;} public DsvDataRdrOpts NewLineSep_(String val) {newLineSep = val; return this;} private String newLineSep = String_.CrLf;

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import gplx.core.strings.*; import gplx.stores.*;
import gplx.core.strings.*; import gplx.core.gfo_ndes.*; import gplx.stores.*;
import gplx.core.texts.*; /*CharStream*/
public class DsvDataRdr_ {
public static DataRdr dsv_(String text) {return DsvParser.dsv_().ParseAsRdr(text);}

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import org.junit.*; import gplx.core.strings.*;
import org.junit.*; import gplx.core.strings.*; import gplx.core.gfo_ndes.*;
public class DsvDataRdr_csv_dat_tst {
@Before public void setup() {
fx.Parser_(DsvParser.csv_(false, GfoFldList_.Null));

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import org.junit.*;
import org.junit.*; import gplx.core.gfo_ndes.*;
public class DsvDataRdr_dsv_hdr_tst {
@Before public void setup() {fx.Clear();} DsvDataRdr_fxt fx = DsvDataRdr_fxt.new_();
@Test public void Names() {

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import org.junit.*;
import org.junit.*; import gplx.core.gfo_ndes.*;
public class DsvDataRdr_dsv_misc_tst {
@Before public void setup() {fx.Clear();} DsvDataRdr_fxt fx = DsvDataRdr_fxt.new_();
@Test public void CmdDlm_NearMatches() {

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import org.junit.*;
import org.junit.*; import gplx.core.gfo_ndes.*;
public class DsvDataRdr_layout_tst {
@Test public void TableName() {
run_parse_lines("table0, ,\" \",#");

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import gplx.core.strings.*;
import gplx.core.strings.*; import gplx.core.gfo_ndes.*;
public class DsvDataWtr extends DataWtr_base implements DataWtr {
public void InitWtr(String key, Object val) {
if (key == DsvStoreLayout.Key_const) layout = (DsvStoreLayout)val;

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import org.junit.*;
import org.junit.*; import gplx.core.gfo_ndes.*;
public class DsvDataWtr_csv_tst {
@Test public void Dat_Val_0() {
root = fx_nde.csv_dat_(); this.AddCsvRow(root);

View File

@@ -16,7 +16,7 @@ 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.langs.dsvs; import gplx.*; import gplx.langs.*;
import org.junit.*;
import org.junit.*; import gplx.core.gfo_ndes.*;
public class DsvDataWtr_tbls_tst {
@Before public void setup() {
DsvStoreLayout layout = DsvStoreLayout.dsv_brief_();

View File

@@ -0,0 +1,90 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
import gplx.core.gfo_regys.*;
public class GfsCore implements GfoInvkAble {
public GfoInvkAble Root() {return root;}
@gplx.Internal protected GfsRegy Root_as_regy() {return root;} GfsRegy root = GfsRegy.new_();
public void Clear() {root.Clear();}
public GfoMsgParser MsgParser() {return msgParser;} public GfsCore MsgParser_(GfoMsgParser v) {msgParser = v; return this;} GfoMsgParser msgParser;
public void Del(String key) {root.Del(key);}
public void AddLib(GfsLibIni... ary) {for (GfsLibIni itm : ary) itm.Ini(this);}
public void AddCmd(GfoInvkAble invk, String key) {root.AddCmd(invk, key);}
public void AddObj(GfoInvkAble invk, String key) {root.AddObj(invk, key);}
public void AddDeep(GfoInvkAble invk, String... ary) {
GfoInvkCmdMgrOwner cur = (GfoInvkCmdMgrOwner)((GfsRegyItm)root.Get_by(ary[0])).InvkAble();
for (int i = 1; i < ary.length - 1; i++)
cur = (GfoInvkCmdMgrOwner)cur.InvkMgr().Invk(GfsCtx.Instance, 0, ary[i], GfoMsg_.Null, cur);
cur.InvkMgr().Add_cmd(ary[ary.length - 1], invk);
}
public String FetchKey(GfoInvkAble invk) {return root.FetchByType(invk).Key();}
public Object ExecOne(GfsCtx ctx, GfoMsg msg) {return GfsCore_.Exec(ctx, root, msg, null, 0);}
public Object ExecOne_to(GfsCtx ctx, GfoInvkAble invk, GfoMsg msg) {return GfsCore_.Exec(ctx, invk, msg, null, 0);}
public Object ExecMany(GfsCtx ctx, GfoMsg rootMsg) {
Object rv = null;
for (int i = 0; i < rootMsg.Subs_count(); i++) {
GfoMsg subMsg = (GfoMsg)rootMsg.Subs_getAt(i);
rv = GfsCore_.Exec(ctx, root, subMsg, null, 0);
}
return rv;
}
public void ExecRegy(String key) {
GfoRegyItm itm = GfoRegy.Instance.FetchOrNull(key);
if (itm == null) {UsrDlg_.Instance.Warn(UsrMsg.new_("could not find script for key").Add("key", key)); return;}
Io_url url = itm.Url();
if (!Io_mgr.Instance.ExistsFil(url)) {
UsrDlg_.Instance.Warn(UsrMsg.new_("script url does not exist").Add("key", key).Add("url", url));
return;
}
this.ExecText(Io_mgr.Instance.LoadFilStr(url));
}
public Object ExecFile_ignoreMissing(Io_url url) {if (!Io_mgr.Instance.ExistsFil(url)) return null; return ExecText(Io_mgr.Instance.LoadFilStr(url));}
public Object ExecFile(Io_url url) {return ExecText(Io_mgr.Instance.LoadFilStr(url));}
public Object ExecFile_ignoreMissing(GfoInvkAble root, Io_url url) {
if (!Io_mgr.Instance.ExistsFil(url)) return null;
if (msgParser == null) throw Err_.new_wo_type("msgParser is null");
return Exec_bry(Io_mgr.Instance.LoadFilBry(url), root);
}
public Object Exec_bry(byte[] bry) {return Exec_bry(bry, root);}
public Object Exec_bry(byte[] bry, GfoInvkAble root) {
GfoMsg rootMsg = msgParser.ParseToMsg(String_.new_u8(bry));
Object rv = null;
GfsCtx ctx = GfsCtx.new_();
for (int i = 0; i < rootMsg.Subs_count(); i++) {
GfoMsg subMsg = (GfoMsg)rootMsg.Subs_getAt(i);
rv = GfsCore_.Exec(ctx, root, subMsg, null, 0);
}
return rv;
}
public Object ExecText(String text) {
if (msgParser == null) throw Err_.new_wo_type("msgParser is null");
GfsCtx ctx = GfsCtx.new_();
return ExecMany(ctx, msgParser.ParseToMsg(text));
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_ExecFil)) {
Io_url url = m.ReadIoUrl("url");
if (ctx.Deny()) return this;
return ExecFile(url);
}
else return GfoInvkAble_.Rv_unhandled;
// return this;
} public static final String Invk_ExecFil = "ExecFil";
public static final GfsCore Instance = new GfsCore();
@gplx.Internal protected static GfsCore new_() {return new GfsCore();}
}

View File

@@ -0,0 +1,73 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
import gplx.core.strings.*;
class GfsCoreHelp implements GfoInvkAble {
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
String path = m.ReadStrOr("path", "");
if (String_.Eq(path, "")) {
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < core.Root_as_regy().Count(); i++) {
GfsRegyItm itm = (GfsRegyItm)core.Root_as_regy().Get_at(i);
sb.Add_spr_unless_first(itm.Key(), String_.CrLf, i);
}
return sb.To_str();
}
else return Exec(ctx, core.Root_as_regy(), path);
}
public static Err Err_Unhandled(String objPath, String key) {return Err_.new_wo_type("obj does not handle msgKey", "objPath", objPath, "key", key).Trace_ignore_add_1_();}
static Err Err_Unhandled(String[] itmAry, int i) {
String_bldr sb = String_bldr_.new_();
for (int j = 0; j < i; j++)
sb.Add_spr_unless_first(itmAry[j], ".", j);
return Err_Unhandled(sb.To_str(), itmAry[i]);
}
static Object Exec(GfsCtx rootCtx, GfoInvkAble rootInvk, String path) {
String[] itmAry = String_.Split(path, ".");
GfoInvkAble invk = rootInvk;
GfsCtx ctx = GfsCtx.new_();
Object curRv = null;
for (int i = 0; i < itmAry.length; i++) {
String itm = itmAry[i];
curRv = invk.Invk(ctx, 0, itm, GfoMsg_.Null);
if (curRv == GfoInvkAble_.Rv_unhandled) throw Err_Unhandled(itmAry, i);
invk = GfoInvkAble_.as_(curRv);
}
GfsCoreHelp helpData = GfsCoreHelp.as_(curRv);
if (helpData != null) { // last itm is actually Method
return "";
}
else {
ctx = GfsCtx.new_().Help_browseMode_(true);
invk.Invk(ctx, 0, "", GfoMsg_.Null);
String_bldr sb = String_bldr_.new_();
for (int i = 0; i < ctx.Help_browseList().Count(); i++) {
String s = (String)ctx.Help_browseList().Get_at(i);
sb.Add_spr_unless_first(s, String_.CrLf, i);
}
return sb.To_str();
}
}
public static GfsCoreHelp as_(Object obj) {return obj instanceof GfsCoreHelp ? (GfsCoreHelp)obj : null;}
public static GfsCoreHelp new_(GfsCore core) {
GfsCoreHelp rv = new GfsCoreHelp();
rv.core = core;
return rv;
} GfsCoreHelp() {}
GfsCore core;
}

View File

@@ -0,0 +1,96 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
public class GfsCore_ {
public static final String Arg_primitive = "v";
public static Object Exec(GfsCtx ctx, GfoInvkAble owner_invk, GfoMsg owner_msg, Object owner_primitive, int depth) {
if (owner_msg.Args_count() == 0 && owner_msg.Subs_count() == 0 && String_.Eq(owner_msg.Key(), "")) {UsrDlg_.Instance.Warn("empty msg"); return GfoInvkAble_.Rv_unhandled;}
if (owner_primitive != null) owner_msg.Parse_(false).Add(GfsCore_.Arg_primitive, owner_primitive);
Object rv = owner_invk.Invk(ctx, 0, owner_msg.Key(), owner_msg);
if (rv == GfoInvkAble_.Rv_cancel) return rv;
else if (rv == GfoInvkAble_.Rv_unhandled) {
if (ctx.Fail_if_unhandled())
throw Err_.new_wo_type("Object does not support key", "key", owner_msg.Key(), "ownerType", Type_adp_.FullNameOf_obj(owner_invk));
else {
Gfo_usr_dlg usr_dlg = ctx.Usr_dlg();
if (usr_dlg != null) usr_dlg.Warn_many(GRP_KEY, "unhandled_key", "Object does not support key: key=~{0} ownerType=~{1}", owner_msg.Key(), Type_adp_.FullNameOf_obj(owner_invk));
return GfoInvkAble_.Null;
}
}
if (owner_msg.Subs_count() == 0) { // msg is leaf
GfsRegyItm regyItm = GfsRegyItm.as_(rv);
if (regyItm == null) return rv; // rv is primitive or other non-regy Object
if (regyItm.IsCmd()) // rv is cmd; invk cmd
return regyItm.InvkAble().Invk(ctx, 0, owner_msg.Key(), owner_msg);
else // rv is host
return regyItm.InvkAble();
}
else { // intermediate; cast to invk and call Exec
GfoInvkAble invk = GfoInvkAble_.as_(rv);
Object primitive = null;
if (invk == null) { // rv is primitive; find appropriate mgr
Class<?> type = rv.getClass();
if (type == String.class) invk = String_.Gfs;
else if (Int_.TypeMatch(type)) invk = Int_.Gfs;
else if (Type_adp_.Eq(type, Bool_.Cls_ref_type)) invk = Bool_.Gfs;
else throw Err_.new_wo_type("unknown primitive", "type", Type_adp_.NameOf_type(type), "obj", Object_.Xto_str_strict_or_null_mark(rv));
primitive = rv;
}
Object exec_rv = null;
int len = owner_msg.Subs_count();
for (int i = 0; i < len; i++) // iterate over subs; needed for a{b;c;d;}
exec_rv = Exec(ctx, invk, owner_msg.Subs_getAt(i), primitive, depth + 1);
return exec_rv;
}
}
static final String GRP_KEY = "gplx.gfs_core";
}
// class GfsRegyMgr : GfoInvkAble {
// public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
// if (ctx.Match(k, Invk_Add)) {
// String libKey = m.ReadStr("libKey"), regKey = m.ReadStr("regKey");
// if (ctx.Deny()) return this;
// GfsRegyItm itm = regy.Get_by(libKey);
// if (regy.Has(regKey)) {ctx.Write_warn("'{0}' already exists", regKey); return this;}
// regy.Add(regKey, itm.InvkAble(), itm.Type_cmd());
// ctx.Write_note("added '{0}' as '{1}'", regKey, libKey);
// }
// else if (ctx.Match(k, Invk_Del)) {
// String regKey = m.ReadStr("regKey");
// if (ctx.Deny()) return this;
// if (!regy.Has(regKey)) {ctx.Write_warn("{0} does not exist", regKey); return this;}
// regy.Del(regKey);
// ctx.Write_note("removed '{0}'", regKey);
// }
// else if (ctx.Match(k, Invk_Load)) {
// Io_url url = (Io_url)m.ReadObj("url", Io_url_.Parser);
// if (ctx.Deny()) return this;
// String loadText = Io_mgr.Instance.LoadFilStr(url);
// GfoMsg loadMsg = core.MsgParser().ParseToMsg(loadText);
// return core.Exec(ctx, loadMsg);
// }
// else return GfoInvkAble_.Rv_unhandled;
// return this;
// } public static final String Invk_Add = "Add", Invk_Del = "Del", Invk_Load = "Load";
// GfsCore core; GfsRegy regy;
// public static GfsRegyMgr new_(GfsCore core, GfsRegy regy) {
// GfsRegyMgr rv = new GfsRegyMgr();
// rv.core = core; rv.regy = regy;
// return rv;
// } GfsRegyMgr() {}
// }

View File

@@ -0,0 +1,113 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
import org.junit.*;
public class GfsCore_tst {
@Before public void setup() {
core = GfsCore.new_();
core.AddObj(String_.Gfs, "String_");
core.AddObj(Int_.Gfs, "Int_");
} GfsCore core;
@Test public void Basic() { // String_.Len('abc') >> 3
tst_Msg
( msg_("String_").Subs_
( msg_("Len").Add("v", "abc"))
, 3);
}
@Test public void PrimitiveConversion() { // String_.Len('abc').Add(-3) >> 0
tst_Msg
( msg_("String_").Subs_
( msg_("Len").Add("v", "abc").Subs_
( msg_("Add").Add("operand", -3))
)
, 0);
}
// @Test public void Fail_notFound() { // String_.DoesNotExists
// tst_Err
// ( msg_("help").Add("", "String_.DoesNotExist")
// , GfsHelp.Err_Unhandled("String_", "DoesNotExist"));
// }
@Test public void Cmd() { // cmd
core.AddCmd(new GfsTest_cmd(), "testCmd");
tst_Msg
( msg_("testCmd").Add("s", "pass")
, "pass");
}
@Test public void EmptyMsg() {
tst_Msg
( msg_("")
, GfoInvkAble_.Rv_unhandled);
}
// @Test public void Fail_argMissing() { // String_.Len()
// tst_String__Len_Err(msg_("Len"), GfsCtx.Err_KeyNotFound("v", "<<EMPTY>>"));
// }
// @Test public void Fail_argWrongKey() { // String_.Len(badKey='abc')
// tst_String__Len_Err(msg_("Len").Add("badKey", "abc"), GfsCtx.Err_KeyNotFound("v", "badKey;"));
// }
// @Test public void Fail_argExtraKey() { // String_.Len(v='abc' extraKey=1)
// tst_String__Len_Err(msg_("Len").Add("v", "abc").Add("extraKey", 1), GfsCtx.Err_KeyNotFound("v", "badKey;"));
// }
@Test public void Add_obj_deep() { // String_.Len(badKey='abc')
GfsCore_tst_nest obj1 = GfsCore_tst_nest.new_("1", "val1");
GfsCore_tst_nest obj1_1 = GfsCore_tst_nest.new_("1_1", "val2");
core.AddObj(obj1, "1");
core.AddDeep(obj1_1, "1", "1_1");
GfoMsg root = GfoMsg_.root_("1", "1_1", GfsCore_tst_nest.Prop2);
Object actl = core.ExecOne(GfsCtx.Instance, root);
Tfds.Eq("val2", actl);
}
void tst_String__Len_Err(GfoMsg m, Err expd) {
tst_Err(msg_("String_").Subs_(m), expd);
}
void tst_Err(GfoMsg msg, Err expd) {
GfoMsg root = msg;
GfsCtx ctx = GfsCtx.new_();
try {
core.ExecOne(ctx, root);
Tfds.Fail_expdError();
}
catch (Exception e) {
Tfds.Eq_err(expd, e);
}
}
GfoMsg msg_(String k) {return GfoMsg_.new_cast_(k);}
void tst_Msg(GfoMsg msg, Object expd) {
GfsCtx ctx = GfsCtx.new_();
Object actl = core.ExecOne(ctx, msg);
Tfds.Eq(expd, actl);
}
}
class GfsCore_tst_nest implements GfoInvkAble, GfoInvkCmdMgrOwner {
public GfoInvkCmdMgr InvkMgr() {return invkMgr;} GfoInvkCmdMgr invkMgr = GfoInvkCmdMgr.new_();
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Prop1)) {return prop1;}
else if (ctx.Match(k, Prop2)) {return prop2;}
else if (ctx.Match(k, prop1)) {return this;}
else return invkMgr.Invk(ctx, ikey, k, m, this);
} public static final String Prop1 = "Prop1", Prop2 = "Prop2";
String prop1, prop2;
public static GfsCore_tst_nest new_(String prop1, String prop2) {
GfsCore_tst_nest rv = new GfsCore_tst_nest();
rv.prop1 = prop1; rv.prop2 = prop2;
return rv;
} GfsCore_tst_nest() {}
}
class GfsTest_cmd implements GfoInvkAble {
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return m.ReadStr("s");}
}

View File

@@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.langs.gfs; import gplx.*; import gplx.langs.*;
public interface GfsLibIni {
void Ini(GfsCore core);
}

View File

@@ -0,0 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.langs.gfs; import gplx.*; import gplx.langs.*;
import gplx.core.gfo_regys.*;
public class GfsLibIni_core implements GfsLibIni {
public void Ini(GfsCore core) {
core.AddCmd(GfsCoreHelp.new_(core), "help");
core.AddObj(String_.Gfs, "String_");
core.AddObj(Int_.Gfs, "Int_");
core.AddObj(DateAdp_.Gfs, "Date_");
core.AddObj(RandomAdp_.Gfs, "RandomAdp_");
core.AddObj(GfoTemplateFactory.Instance, "factory");
core.AddObj(GfoRegy.Instance, "GfoRegy_");
core.AddObj(GfsCore.Instance, "GfsCore_");
core.AddObj(gplx.core.ios.IoUrlInfoRegy.Instance, "IoUrlInfoRegy_");
core.AddObj(gplx.core.ios.IoUrlTypeRegy.Instance, "IoUrlTypeRegy_");
GfoRegy.Instance.Parsers().Add("Io_url", Io_url_.Parser);
}
public static final GfsLibIni_core Instance = new GfsLibIni_core(); GfsLibIni_core() {}
}

View File

@@ -0,0 +1,54 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
class GfsRegy implements GfoInvkAble {
public int Count() {return hash.Count();}
public void Clear() {hash.Clear(); typeHash.Clear();}
public boolean Has(String k) {return hash.Has(k);}
public GfsRegyItm Get_at(int i) {return (GfsRegyItm)hash.Get_at(i);}
public GfsRegyItm Get_by(String key) {return (GfsRegyItm)hash.Get_by(key);}
public GfsRegyItm FetchByType(GfoInvkAble invk) {return (GfsRegyItm)typeHash.Get_by(Type_adp_.FullNameOf_obj(invk));}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
Object rv = (GfsRegyItm)hash.Get_by(k); if (rv == null) throw Err_.new_missing_key(k);
return rv;
}
public void AddObj(GfoInvkAble invk, String key) {Add(key, invk, false);}
public void AddCmd(GfoInvkAble invk, String key) {Add(key, invk, true);}
public void Add(String key, GfoInvkAble invk, boolean typeCmd) {
if (hash.Has(key)) return;
GfsRegyItm regyItm = new GfsRegyItm().Key_(key).InvkAble_(invk).IsCmd_(typeCmd).TypeKey_(Type_adp_.FullNameOf_obj(invk));
hash.Add(key, regyItm);
typeHash.Add_if_dupe_use_1st(regyItm.TypeKey(), regyItm); // NOTE: changed to allow same Object to be added under different aliases (app, xowa) DATE:2014-06-09;
}
public void Del(String k) {
GfsRegyItm itm =(GfsRegyItm)hash.Get_by(k);
if (itm != null) typeHash.Del(itm.TypeKey());
hash.Del(k);
}
Hash_adp typeHash = Hash_adp_.new_();
Ordered_hash hash = Ordered_hash_.New();
public static GfsRegy new_() {return new GfsRegy();} GfsRegy() {}
}
class GfsRegyItm implements GfoInvkAble {
public String Key() {return key;} public GfsRegyItm Key_(String v) {key = v; return this;} private String key;
public String TypeKey() {return typeKey;} public GfsRegyItm TypeKey_(String v) {typeKey = v; return this;} private String typeKey;
public boolean IsCmd() {return isCmd;} public GfsRegyItm IsCmd_(boolean v) {isCmd = v; return this;} private boolean isCmd;
public GfoInvkAble InvkAble() {return invkAble;} public GfsRegyItm InvkAble_(GfoInvkAble v) {invkAble = v; return this;} GfoInvkAble invkAble;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {return invkAble.Invk(ctx, ikey, k, m);}
public static GfsRegyItm as_(Object obj) {return obj instanceof GfsRegyItm ? (GfsRegyItm)obj : null;}
}

View File

@@ -0,0 +1,28 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
public class GfsTypeNames {
public static final String
String = "string"
, Int = "int"
, Bool = "bool"
, Float = "float"
, YesNo = "yn"
, Date = "date"
;
}

View File

@@ -0,0 +1,42 @@
/*
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.langs.gfs; import gplx.*; import gplx.langs.*;
import org.junit.*;
public class Gfs_Date_tst {
@Before public void setup() {
fx = new GfsCoreFxt();
fx.AddObj(DateAdp_.Gfs, "Date_");
Tfds.Now_enabled_y_();
} GfsCoreFxt fx;
@Test public void Now() {
fx.tst_MsgStr(fx.msg_(String_.Ary("Date_", "Now")), DateAdp_.parse_gplx("2001-01-01 00:00:00.000"));
}
@Test public void Add_day() {
fx.tst_MsgStr(fx.msg_(String_.Ary("Date_", "Now", "Add_day"), KeyVal_.new_("days", 1)), DateAdp_.parse_gplx("2001-01-02 00:00:00.000"));
}
}
class GfsCoreFxt {
public GfsCore Core() {return core;} GfsCore core = GfsCore.new_();
public GfoMsg msg_(String[] ary, KeyVal... kvAry) {return GfoMsg_.root_leafArgs_(ary, kvAry);}
public void AddObj(GfoInvkAble invk, String s) {core.AddObj(invk, s);}
public void tst_MsgStr(GfoMsg msg, Object expd) {
GfsCtx ctx = GfsCtx.new_();
Object actl = core.ExecOne(ctx, msg);
Tfds.Eq(Object_.Xto_str_strict_or_null_mark(expd), Object_.Xto_str_strict_or_null_mark(actl));
}
}