/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012-2017 gnosygnu@gmail.com XOWA is licensed under the terms of the General Public License (GPL) Version 3, or alternatively under the terms of the Apache License Version 2.0. You may use XOWA according to either of these licenses as is most appropriate for your project on a case-by-case basis. The terms of each license can be found in the source code repository: GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx; import gplx.core.strings.*; import gplx.langs.gfs.*; public class Int_ { public static final String Cls_val_name = "int"; public static final Class Cls_ref_type = Integer.class; public static final int Min_value = Integer.MIN_VALUE , Max_value = Integer.MAX_VALUE , Max_value__31 = 2147483647 , Neg1 = -1 , Null = Int_.Min_value , Base1 = 1 // for super 1 lists / arrays; EX: PHP; [a, b, c]; [1] => a , Offset_1 = 1 // common symbol for + 1 after current pos; EX: String_.Mid(lhs + Offset_1, rhs) ; 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 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 Parse(String raw) {try {return Integer.parseInt(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, int.class, raw);}} 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 By_double(double v) {return (int)v;} public static int By_hex_bry(byte[] src) {return By_hex_bry(src, 0, src.length);} public static int By_hex_bry(byte[] src, int bgn, int end) { int rv = 0; int factor = 1; for (int i = end - 1; i >= bgn; i--) { int val = By_hex_byte(src[i]); rv += (val * factor); factor *= 16; } return rv; } public static int By_hex_byte(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 byte[] To_bry(int v) {return Bry_.new_a7(To_str(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 String To_str_pad_bgn_space(int val, int reqd_len) {return To_str_pad(val, reqd_len, Bool_.Y, Byte_ascii.Space);} // EX: 1, 3 returns " 1" public static String To_str_pad_bgn_zero (int val, int reqd_len) {return To_str_pad(val, reqd_len, Bool_.Y, Byte_ascii.Num_0);} // EX: 1, 3 returns "001" private static String To_str_pad(int val, int reqd_len, boolean bgn, byte pad_chr) { // get val_len and pad_len; exit early, if no padding needed int val_len = DigitCount(val); int pad_len = reqd_len - val_len; if (pad_len < 0) return Int_.To_str(val); // padding needed Bry_bfr bfr = Bry_bfr_.New(); // handle negative numbers; EX: -1 -> "-001", not "00-1" if (val < 0) { bfr.Add_byte(Byte_ascii.Dash); val *= -1; --val_len; } // build outpt if (!bgn) bfr.Add_int_fixed(val, val_len); bfr.Add_byte_repeat(pad_chr, pad_len); if (bgn) bfr.Add_int_fixed(val, val_len); return bfr.To_str(); } 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 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 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 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 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 boolean Bounds_chk(int bgn, int end, int len) {return bgn > -1 && end < len;} public static int BoundEnd(int v, int end) {return v >= end ? end - 1 : v;} public static int EnsureLessThan(int v, int max) {return v >= max ? max : 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 Min_many(int... ary) { int len = ary.length; if (len == 0) throw Err_.new_wo_type("Min_many requires at least 1 value"); boolean init = true; int min = Int_.Min_value; for (int i = 0; i < len; ++i) { int val = ary[i]; if (init) { min = val; init = false; } else { if (val < min) min = val; } } return min; } public static int Subtract_long(long lhs, long rhs) {return (int)(lhs - rhs);} 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[] Log10Ary = new int[] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, Int_.Max_value}; public static int Log10AryLen = 11; 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 DigitCount(int v) { int log10 = Log10(v); return v > -1 ? log10 + 1 : log10 * -1 + 2; } }