Warning : session_start(): open(/var/lib/php/sessions/sess_gnrfgsbf1jv7mtl2ghje94df4j, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.function.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import java.time.Duration;
import java.lang.invoke.VarHandle;
import java.lang.invoke.MethodHandles;
// Builds a HuffmanTree from a byte histogram
import java.awt.geom.*;
import static x30_pkg.x30_util.DynamicObject;
import java.text.*;
import java.text.NumberFormat;
import java.util.TimeZone;
class main {
static class HuffmanTreeMaker {
// output
final public HuffmanTree getTree(){ return tree(); }
public HuffmanTree tree() { return tree; }
HuffmanTree tree = new HuffmanTree();
// internal
TreeSet pool = new TreeSet(); // combinable trees sorted by incidence (symbol frequency)
int indexCounter; // counter to keep order deterministic
class Head implements Comparable {
int index = indexCounter++;
final public Head setNode(HuffmanTree.Node node){ return node(node); }
public Head node(HuffmanTree.Node node) { this.node = node; return this; } final public HuffmanTree.Node getNode(){ return node(); }
public HuffmanTree.Node node() { return node; }
HuffmanTree.Node node;
final public Head setFreq(double freq){ return freq(freq); }
public Head freq(double freq) { this.freq = freq; return this; } final public double getFreq(){ return freq(); }
public double freq() { return freq; }
double freq; // using floating point to keep things futureproof
// sort by frequency first, then by index (order of creation)
public int compareTo(Head h) {
if (this == h) return 0;
var c = cmp(freq, h.freq);
if (c != 0) return c;
return cmp(index, h.index);
}
public String toString() { return freq + "x " + node; }
}
// histogram[0] = incidence for byte 00
// histogram[1] = incidence for byte 01
// etc. up to 255 (or less)
HuffmanTreeMaker importByteHistogram(int[] histogram) {
int n = l(histogram);
for (int i = 0; i < n; i++) {
double freq = histogram[i];
if (freq != 0)
pool.add(new Head().freq(freq).node(tree.new Leaf(i)));
}
return this;
}
public void run() { try {
while (l(pool) > 1) { ping();
var it = iterator(pool);
var a = it.next();
it.remove();
var b = it.next();
it.remove();
//print("Merging frequencies: " + commaCombine(a.freq, b.freq));
var newHead = new Head()
.freq(a.freq+b.freq)
.node(tree.new Branch().zero(b.node).one(a.node));
//print("Merging: " + commaCombine(a, b) + " to " + newHead);
pool.add(newHead);
}
} catch (Exception __e) { throw rethrow(__e); } }
HuffmanTree get() {
run();
if (nempty(pool))
tree.root(popFirst(pool).node());
return tree;
}
}
static Frequency freq(double freq) {
return toFrequency(freq);
}
static int cmp(Number a, Number b) {
return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue());
}
static int cmp(double a, double b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(int a, int b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(long a, long b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(Object a, Object b) {
if (a == null) return b == null ? 0 : -1;
if (b == null) return 1;
return ((Comparable) a).compareTo(b);
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(IMultiMap mm) { return mm == null ? 0 : mm.size(); }
static int l(AppendableChain a) { return a == null ? 0 : a.size; }
static int l(IntSize o) { return o == null ? 0 : o.size(); }
// legacy mode
//sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// ignore pingSource if not PingV3
static boolean ping(PingSource pingSource) { return ping(); }
// always returns true
static boolean ping() {
//ifdef useNewPing
newPing();
//endifdef
if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */);
//ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) { // don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized(ping_actions) {
if (!ping_actions.isEmpty()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) { throw rethrow(__e); } }
static Iterator iterator(Iterable c) {
return c == null ? emptyIterator() : c.iterator();
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static Class run(String progID, String... args) {
Class main = hotwire(progID);
callMain(main, args);
return main;
}
static boolean nempty(Collection c) {
return !empty(c);
}
static boolean nempty(CharSequence s) {
return !empty(s);
}
static boolean nempty(Object[] o) { return !empty(o); }
static boolean nempty(byte[] o) { return !empty(o); }
static boolean nempty(int[] o) { return !empty(o); }
static boolean nempty(BitSet bs) { return !empty(bs); }
static boolean nempty(Map m) {
return !empty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean nempty(IMultiMap mm) { return mm != null && mm.size() != 0; }
static boolean nempty(Object o) { return !empty(o); }
static boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; }
static A popFirst(List l) {
if (empty(l)) return null;
A a = first(l);
l.remove(0);
return a;
}
static A popFirst(Collection l) {
if (empty(l)) return null;
A a = first(l);
l.remove(a);
return a;
}
static Pair popFirst(Map map) {
if (map == null) return null;
var it = map.entrySet().iterator();
if (!it.hasNext()) return null;
var p = mapEntryToPair(it.next());
it.remove();
return p;
}
static List popFirst(int n, List l) {
List part = cloneSubList(l, 0, n);
removeSubList(l, 0, n);
return part;
}
static AppendableChain popFirst(AppendableChain a) {
return a == null ? null : a.popFirst();
}
static Frequency toFrequency(double freq) {
return new Frequency(freq);
}
static int iteratorCount_int_close(Iterator i) { try {
int n = 0;
if (i != null) while (i.hasNext()) { i.next(); ++n; }
if (i instanceof AutoCloseable) ((AutoCloseable) i).close();
return n;
} catch (Exception __e) { throw rethrow(__e); } }
static Map newWeakHashMap() {
return _registerWeakMap(synchroMap(new WeakHashMap()));
}
static void newPing() {
var tl = newPing_actionTL();
Runnable action = tl == null ? null : tl.get();
{ if (action != null) action.run(); }
}
// TODO: test if android complains about this
static boolean isAWTThread() {
if (isAndroid()) return false;
if (isHeadless()) return false;
return isAWTThread_awt();
}
static boolean isAWTThread_awt() {
return SwingUtilities.isEventDispatchThread();
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
if (o instanceof ThreadLocal) // TODO: remove this
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static void failIfUnlicensed() {
assertTrue("license off", licensed());
}
static Thread currentThread() {
return Thread.currentThread();
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
// a little kludge for stuff like eq(symbol, "$X")
static boolean eq(Symbol a, String b) {
return eq(str(a), b);
}
static RuntimeException fail() { throw new RuntimeException("fail"); }
static RuntimeException fail(Throwable e) { throw asRuntimeException(e); }
static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); }
static RuntimeException fail(Object... objects) { throw new Fail(objects); }
static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static Iterator emptyIterator() {
return Collections.emptyIterator();
}
static void _handleError(Error e) {
//call(javax(), '_handleError, e);
}
// custom mainClass only works with hotwire_here
static Class> hotwire(String src) { return hotwire(src, __1 -> mainClassNameForClassLoader(__1)); }
static Class> hotwire(String src, IF1 calculateMainClass) {
assertFalse(_inCore());
Class j = getJavaX();
if (isAndroid()) {
synchronized(j) { // hopefully this goes well...
List libraries = new ArrayList();
File srcDir = (File) call(j, "transpileMain", src, libraries);
if (srcDir == null)
throw fail("transpileMain returned null (src=" + quote(src) + ")");
Object androidContext = get(j, "androidContext");
return (Class) call(j, "loadx2android", srcDir, src);
}
} else {
Class c = (Class) (call(j, "hotwire", src));
hotwire_copyOver(c);
return c;
}
}
static A callMain(A c, String... args) {
callOpt(c, "main", new Object[] {args});
return c;
}
static void callMain() {
callMain(mc());
}
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); }
static boolean empty(CharSequence s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(BitSet bs) { return bs == null || bs.isEmpty(); }
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
if (o instanceof byte[]) return empty((byte[]) o);
if (o == null) return true;
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) { return i == null || !i.hasNext(); }
static boolean empty(double[] a) { return a == null || a.length == 0; }
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static boolean empty(byte[] a) { return a == null || a.length == 0; }
static boolean empty(short[] a) { return a == null || a.length == 0; }
static boolean empty(IMultiMap mm) { return mm == null || mm.size() == 0; }
static boolean empty(File f) { return getFileSize(f) == 0; }
static boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); }
static boolean empty(Chain c) { return c == null; }
static boolean empty(AppendableChain c) { return c == null; }
static Object first(Object list) {
return first((Iterable) list);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static Pair first(Map map) {
return mapEntryToPair(first(entrySet(map)));
}
static Pair first(MultiMap mm) {
if (mm == null) return null;
var e = first(mm.data.entrySet());
if (e == null) return null;
return pair(e.getKey(), first(e.getValue()));
}
static A first(IterableIterator i) {
return first((Iterator ) i);
}
static A first(Iterator i) {
return i == null || !i.hasNext() ? null : i.next();
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static Character first(CharSequence s) { return empty(s) ? null : s.charAt(0); }
static A first(Pair p) {
return p == null ? null : p.a;
}
static Byte first(byte[] l) {
return empty(l) ? null : l[0];
}
static byte first(ByteBuffer buf) {
return buf.get(0);
}
static A first(A[] l, IF1 pred) {
return firstThat(l, pred);
}
static A first(Iterable l, IF1 pred) {
return firstThat(l, pred);
}
static A first(IF1 pred, Iterable l) {
return firstThat(pred, l);
}
static A first(AppendableChain a) {
return a == null ? null : a.element;
}
static Pair mapEntryToPair(Map.Entry e) {
return e == null ? null : pair(e.getKey(), e.getValue());
}
static List cloneSubList(List l, int startIndex, int endIndex) {
return newSubList(l, startIndex, endIndex);
}
static List cloneSubList(List l, int startIndex) {
return newSubList(l, startIndex);
}
static void removeSubList(List l, int from, int to) {
if (l != null) subList(l, from, to).clear();
}
static void removeSubList(List l, int from) {
if (l != null) subList(l, from).clear();
}
static List _registerWeakMap_preList;
static A _registerWeakMap(A map) {
if (javax() == null) {
// We're in class init
if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList();
_registerWeakMap_preList.add(map);
return map;
}
try {
call(javax(), "_registerWeakMap", map);
} catch (Throwable e) {
printException(e);
print("Upgrade JavaX!!");
}
return map;
}
static void _onLoad_registerWeakMap() {
assertNotNull(javax());
if (_registerWeakMap_preList == null) return;
for (Object o : _registerWeakMap_preList)
_registerWeakMap(o);
_registerWeakMap_preList = null;
}
static Map synchroMap() {
return synchroHashMap();
}
static Map synchroMap(Map map) {
return Collections.synchronizedMap(map);
}
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL;
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL() {
if (newPing_actionTL == null)
newPing_actionTL = vm_generalMap_getOrCreate("newPing_actionTL",
() -> {
Runnable value = (Runnable) (callF_gen(vm_generalMap_get("newPing_valueForNewThread")));
var tl = new x30_pkg.x30_util.BetterThreadLocal();
tl.set(value);
return tl;
});
return newPing_actionTL;
}
static int isAndroid_flag;
static boolean isAndroid() {
if (isAndroid_flag == 0)
isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1;
return isAndroid_flag > 0;
}
static Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (isAndroid()) return isHeadless_cache = true;
if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true;
// Also check if AWT actually works.
// If DISPLAY variable is set but no X server up, this will notice.
try {
SwingUtilities.isEventDispatchThread();
return isHeadless_cache = false;
} catch (Throwable e) { return isHeadless_cache = true; }
}
static String getClassName(Object o) {
return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName();
}
static void assertTrue(Object o) {
if (!(eq(o, true) /*|| isTrue(pcallF(o))*/))
throw fail(str(o));
}
static boolean assertTrue(String msg, boolean b) {
if (!b)
throw fail(msg);
return b;
}
static boolean assertTrue(boolean b) {
if (!b)
throw fail("oops");
return b;
}
static volatile boolean licensed_yes = true;
static boolean licensed() {
if (!licensed_yes) return false;
ping_okInCleanUp();
return true;
}
static void licensed_off() {
licensed_yes = false;
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
static String str(char[] c, int offset, int count) {
return new String(c, offset, count);
}
static RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static String mainClassNameForClassLoader(ClassLoader cl) {
return or((String) callOpt(cl, "mainClassName"), "main");
}
static void assertFalse(Object o) {
if (!(eq(o, false) /*|| isFalse(pcallF(o))*/))
throw fail(str(o));
}
static boolean assertFalse(boolean b) {
if (b) throw fail("oops");
return b;
}
static boolean assertFalse(String msg, boolean b) {
if (b) throw fail(msg);
return b;
}
static boolean _inCore() {
return false;
}
static Class __javax;
static Class getJavaX() { try {
return __javax;
} catch (Exception __e) { throw rethrow(__e); } }
static void __setJavaX(Class j) {
__javax = j;
_onJavaXSet();
}
static Object call(Object o) {
return callF(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
//ret call_cached(o, method, args);
return call_withVarargs(o, method, args);
}
static String quote(Object o) {
if (o == null) return "null";
return quote(str(o));
}
static String quote(String s) {
if (s == null) return "null";
StringBuilder out = new StringBuilder((int) (l(s)*1.5+2));
quote_impl(s, out);
return out.toString();
}
static void quote_impl(String s, StringBuilder out) {
out.append('"');
int l = s.length();
for (int i = 0; i < l; i++) {
char c = s.charAt(i);
if (c == '\\' || c == '"')
out.append('\\').append(c);
else if (c == '\r')
out.append("\\r");
else if (c == '\n')
out.append("\\n");
else if (c == '\t')
out.append("\\t");
else if (c == '\0')
out.append("\\0");
else
out.append(c);
}
out.append('"');
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static B get(Map map, A key) {
ret map != null ? map.get(key) : null;
}*/
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o == null) return null;
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
makeAccessible(f);
return f.get(o);
}
if (o instanceof DynamicObject)
return getOptDynOnly(((DynamicObject) o), field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
if (o == null) return null;
Field f = get_findField(o.getClass(), field);
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
makeAccessible(f);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
return get(o, field);
}
static boolean get(BitSet bs, int idx) {
return bs != null && bs.get(idx);
}
static List hotwire_copyOver_after = synchroList();
static void hotwire_copyOver(Class c) {
// TODO: make a mechanism for making such "inheritable" fields
for (String field : ll("print_log", "print_silent", "androidContext", "_userHome"))
setOptIfNotNull(c, field, getOpt(mc(), field));
setOptIfNotNull(c, "mainBot" , getMainBot());
setOpt(c, "creator_class" , new WeakReference(mc()));
pcallFAll(hotwire_copyOver_after, c);
}
static Object callOpt(Object o) {
return callF(o);
}
static Object callOpt(Object o, String method, Object... args) {
return callOpt_withVarargs(o, method, args);
}
static Class mc() {
return main.class;
}
static String getType(Object o) {
return getClassName(o);
}
static long getFileSize(String path) {
return path == null ? 0 : new File(path).length();
}
static long getFileSize(File f) {
return f == null ? 0 : f.length();
}
static Set> entrySet(Map map) {
return _entrySet(map);
}
static Pair pair(A a, B b) {
return new Pair(a, b);
}
static Pair pair(A a) {
return new Pair(a, a);
}
static A firstThat(Iterable l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(A[] l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(IF1 pred, Iterable l) {
return firstThat(l, pred);
}
static A firstThat(IF1 pred, A[] l) {
return firstThat(l, pred);
}
static List newSubList(List l, int startIndex, int endIndex) {
return cloneList(subList(l, startIndex, endIndex));
}
static List newSubList(List l, int startIndex) {
return cloneList(subList(l, startIndex));
}
static List subList(List l, int startIndex) {
return subList(l, startIndex, l(l));
}
static List subList(int startIndex, List l) {
return subList(l, startIndex);
}
static List subList(int startIndex, int endIndex, List l) {
return subList(l, startIndex, endIndex);
}
static List subList(List l, int startIndex, int endIndex) {
if (l == null) return null;
int n = l(l);
startIndex = Math.max(0, startIndex);
endIndex = Math.min(n, endIndex);
if (startIndex > endIndex) return ll();
if (startIndex == 0 && endIndex == n) return l;
return l.subList(startIndex, endIndex);
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static boolean printAlsoToSystemOut = true;
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1
static volatile Object print_allThreads;
static volatile Object print_preprocess;
static void print() {
print("");
}
static A print(String s, A o) {
print(combinePrintParameters(s, o));
return o;
}
// slightly overblown signature to return original object...
static A print(A o) {
ping_okInCleanUp();
if (print_silent) return o;
String s = o + "\n";
print_noNewLine(s);
return o;
}
static void print_noNewLine(String s) {
try {
Object f = getThreadLocal(print_byThread_dontCreate());
if (f == null) f = print_allThreads;
if (f != null)
// We do need the general callF machinery here as print_byThread is sometimes shared between modules
if (isFalse(
f instanceof F1 ? ((F1) f).get(s) :
callF(f, s))) return;
} catch (Throwable e) {
System.out.println(getStackTrace(e));
}
print_raw(s);
}
static void print_raw(String s) {
if (print_preprocess != null) s = (String) callF(print_preprocess, s);
s = fixNewLines(s);
Appendable loc = local_log;
Appendable buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
if (printAlsoToSystemOut)
System.out.print(s);
vmBus_send("printed", mc(), s);
}
static void print_autoRotate() {
}
static Class javax() {
return getJavaX();
}
static List synchroList() {
return synchroList(new ArrayList ());
}
static List synchroList(List l) {
return Collections.synchronizedList(l);
}
static A printException(A e) {
printStackTrace(e);
return e;
}
static A assertNotNull(A a) {
assertTrue(a != null);
return a;
}
static A assertNotNull(String msg, A a) {
assertTrue(msg, a != null);
return a;
}
static Map synchroHashMap() {
return synchronizedMap(new HashMap());
}
static A vm_generalMap_getOrCreate(Object key, F0 create) {
return vm_generalMap_getOrCreate(key, f0ToIF0(create));
}
static A vm_generalMap_getOrCreate(Object key, IF0 create) {
Map generalMap = vm_generalMap();
if (generalMap == null) return null; // must be x30 init
synchronized(generalMap) { // should switch to locks here
A a = (A) (vm_generalMap_get(key));
if (a == null)
vm_generalMap_put(key, a = create == null ? null : create.get());
return a;
}
}
static A callF_gen(F0 f) {
return f == null ? null : f.get();
}
static B callF_gen(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF_gen(IF0 f) {
return f == null ? null : f.get();
}
static B callF_gen(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF_gen(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF_gen(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF_gen(VF1 f, A a) {
{ if (f != null) f.get(a); }
}
static void callF_gen(A a, IVF1 f) {
{ if (f != null) f.get(a); }
}
static void callF_gen(IVF1 f, A a) {
{ if (f != null) f.get(a); }
}
static Object callF_gen(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF_gen(Object f, Object... args) {
return callF(f, args);
}
static Object vm_generalMap_get(Object key) {
return vm_generalMap().get(key);
}
static void ping_okInCleanUp() {
if (ping_pauseAll || ping_anyActions)
ping_impl(true);
}
static A or(A a, A b) {
return a != null ? a : b;
}
static void _onJavaXSet() {}
static Map> callF_cache = newDangerousWeakHashMap();
static A callF(F0 f) {
return f == null ? null : f.get();
}
static B callF(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF(IF0 f) {
return f == null ? null : f.get();
}
static B callF(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF(VF1 f, A a) {
if (f != null) f.get(a);
}
static void callF(A a, IVF1 f) {
if (f != null) f.get(a);
}
static void callF(IVF1 f, A a) {
if (f != null) f.get(a);
}
static Object callF(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF(Object f, Object... args) {
return safeCallF(f, args);
}
static Object safeCallF(Object f, Object... args) {
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
}
if (f == null) return null;
Class c = f.getClass();
ArrayList methods;
synchronized(callF_cache) {
methods = callF_cache.get(c);
if (methods == null)
methods = callF_makeCache(c);
}
int n = l(methods);
if (n == 0) {
if (f instanceof String)
throw fail("Legacy call: " + f);
throw fail("No get method in " + getClassName(c));
}
if (n == 1) return invokeMethod(methods.get(0), f, args);
for (int i = 0; i < n; i++) {
Method m = methods.get(i);
if (call_checkArgs(m, args, false))
return invokeMethod(m, f, args);
}
throw fail("No matching get method in " + getClassName(c));
}
// used internally
static ArrayList callF_makeCache(Class c) {
ArrayList l = new ArrayList();
Class _c = c;
do {
for (Method m : _c.getDeclaredMethods())
if (m.getName().equals("get")) {
makeAccessible(m);
l.add(m);
}
if (!l.isEmpty()) break;
_c = _c.getSuperclass();
} while (_c != null);
callF_cache.put(c, l);
return l;
}
static Object call_withVarargs(Object o, String methodName, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findStaticMethod(methodName, args);
if (me != null)
return invokeMethod(me, null, args);
// try varargs
List methods = cache.cache.get(methodName);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
{ if (!(isStaticMethod(m))) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, null, newArgs);
}
throw fail("Method " + c.getName() + "." + methodName + "(" + joinWithComma(classNames(args)) + ") not found");
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(methodName, args);
if (me != null)
return invokeMethod(me, o, args);
// try varargs
List methods = cache.cache.get(methodName);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, o, newArgs);
}
throw fail("Method " + c.getName() + "." + methodName + "(" + joinWithComma(classNames(args)) + ") not found");
}
} catch (Exception __e) { throw rethrow(__e); } }
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field makeAccessible(Field f) {
try {
f.setAccessible(true);
} catch (Throwable e) {
// Note: The error reporting only works with Java VM option --illegal-access=deny
vmBus_send("makeAccessible_error", e, f);
}
return f;
}
static Method makeAccessible(Method m) {
try {
m.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, m);
}
return m;
}
static Constructor makeAccessible(Constructor c) {
try {
c.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, c);
}
return c;
}
static Object getOptDynOnly(DynamicObject o, String field) {
if (o == null || o.fieldValues == null) return null;
return o.fieldValues.get(field);
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null) for (A x : a) l.add(x);
return l;
}
static void setOptIfNotNull(Object o, String field, Object value) {
if (value != null) setOpt(o, field, value);
}
static Object getOpt(Object o, String field) {
return getOpt_cached(o, field);
}
static Object getOpt(String field, Object o) {
return getOpt_cached(o, field);
}
static Object getOpt_raw(Object o, String field) { try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
// access of static fields is not yet optimized
static Object getOpt(Class c, String field) { try {
if (c == null) return null;
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
makeAccessible(f);
return f.get(null);
} catch (Exception __e) { throw rethrow(__e); } }
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Object mainBot;
static Object getMainBot() {
return mainBot;
}
static Field setOpt_findField(Class c, String field) {
HashMap map;
synchronized(getOpt_cache) {
map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
}
return map.get(field);
}
static void setOpt(Object o, String field, Object value) { try {
if (o == null) return;
Class c = o.getClass();
HashMap map;
if (getOpt_cache == null)
map = getOpt_makeCache(c); // in class init
else synchronized(getOpt_cache) {
map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
}
if (map == getOpt_special) {
if (o instanceof Class) {
setOpt((Class) o, field, value);
return;
}
// It's probably a subclass of Map. Use raw method. TODO: huh?
setOpt_raw(o, field, value);
return;
}
Field f = map.get(field);
if (f != null)
{ smartSet(f, o, value); return; } // possible improvement: skip setAccessible
if (o instanceof DynamicObject)
{ setDyn(((DynamicObject) o), field, value); return; }
if (o instanceof IMeta)
setDyn(((IMeta) o), field, value);
} catch (Exception __e) { throw rethrow(__e); } }
static void setOpt(Class c, String field, Object value) {
if (c == null) return;
try {
Field f = setOpt_findStaticField(c, field); // TODO: optimize
if (f != null)
smartSet(f, null, value);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field setOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) {
makeAccessible(f);
return f;
}
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static void pcallFAll(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) pcallF(f, args);
}
static void pcallFAll(Iterator it, Object... args) {
while (it.hasNext()) pcallF(it.next(), args);
}
static Object callOpt_withVarargs(Object o, String method, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(method, args);
if (me == null) {
// TODO: varargs
return null;
}
if ((me.getModifiers() & Modifier.STATIC) == 0)
return null;
return invokeMethod(me, null, args);
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(method, args);
if (me != null)
return invokeMethod(me, o, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, o, newArgs);
}
return null;
}
} catch (Exception __e) { throw rethrow(__e); } }
static Set> _entrySet(Map map) {
return map == null ? Collections.EMPTY_SET : map.entrySet();
}
static String unnullForIteration(String s) {
return s == null ? "" : s;
}
static Collection unnullForIteration(Collection l) {
return l == null ? immutableEmptyList() : l;
}
static List unnullForIteration(List l) { return l == null ? immutableEmptyList() : l; }
static byte[] unnullForIteration(byte[] l) { return l == null ? emptyByteArray() : l; }
static int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; }
static short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; }
static Map unnullForIteration(Map l) {
return l == null ? immutableEmptyMap() : l;
}
static Iterable unnullForIteration(Iterable i) {
return i == null ? immutableEmptyList() : i;
}
static A[] unnullForIteration(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnullForIteration(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnullForIteration(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnullForIteration(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnullForIteration(Pair p) {
return p != null ? p : new Pair(null, null);
}
static long unnullForIteration(Long l) { return l == null ? 0L : l; }
static ArrayList cloneList(Iterable l) {
return l instanceof Collection ? cloneList((Collection) l) : asList(l);
}
static ArrayList cloneList(Collection l) {
if (l == null) return new ArrayList();
synchronized(collectionMutex(l)) {
return new ArrayList (l);
}
}
static AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) {
return print_byThread().get() == null ? tempInterceptPrint(f) : null;
}
//static final Map> getOpt_cache = newDangerousWeakHashMap(f getOpt_special_init);
static class getOpt_Map extends WeakHashMap {
getOpt_Map() {
if (getOpt_special == null) getOpt_special = new HashMap();
clear();
}
public void clear() {
super.clear();
//print("getOpt clear");
put(Class.class, getOpt_special);
put(String.class, getOpt_special);
}
}
static final Map> getOpt_cache =
_registerDangerousWeakMap(synchroMap(new getOpt_Map()));
static HashMap getOpt_special; // just a marker
/*static void getOpt_special_init(Map map) {
map.put(Class.class, getOpt_special);
map.put(S.class, getOpt_special);
}*/
static Map getOpt_getFieldMap(Object o) {
Class c = _getClass(o);
HashMap map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
return map;
}
static Object getOpt_cached(Object o, String field) { try {
if (o == null) return null;
Map map = getOpt_getFieldMap(o);
if (map == getOpt_special) {
if (o instanceof Class)
return getOpt((Class) o, field);
/*if (o instanceof S)
ret getOpt(getBot((S) o), field);*/
if (o instanceof Map)
return ((Map) o).get(field);
}
Field f = map.get(field);
if (f != null) return f.get(o);
if (o instanceof DynamicObject)
return syncMapGet2(((DynamicObject) o).fieldValues, field);
return null;
} catch (Exception __e) { throw rethrow(__e); } }
// used internally - we are in synchronized block
static HashMap getOpt_makeCache(Class c) {
HashMap map;
if (isSubtypeOf(c, Map.class))
map = getOpt_special;
else {
map = new HashMap();
if (!reflection_classesNotToScan().contains(c.getName())) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields()) {
makeAccessible(f);
String name = f.getName();
if (!map.containsKey(name))
map.put(name, f);
}
_c = _c.getSuperclass();
} while (_c != null);
}
}
if (getOpt_cache != null) getOpt_cache.put(c, map);
return map;
}
static String combinePrintParameters(String s, Object o) {
return (endsWithLetterOrDigit(s) ? s + ": " : s) + o;
}
// this syntax should be removed...
static Object getThreadLocal(Object o, String name) {
ThreadLocal t = (ThreadLocal) (getOpt(o, name));
return t != null ? t.get() : null;
}
static A getThreadLocal(ThreadLocal tl) {
return tl == null ? null : tl.get();
}
static A getThreadLocal(ThreadLocal tl, A defaultValue) {
return or(getThreadLocal(tl), defaultValue);
}
static ThreadLocal print_byThread_dontCreate() {
return print_byThread;
}
static boolean isFalse(Object o) {
return eq(false, o);
}
static String getStackTrace(Throwable throwable) {
lastException(throwable);
return getStackTrace_noRecord(throwable);
}
static String getStackTrace_noRecord(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return hideCredentials(writer.toString());
}
static String getStackTrace() {
return getStackTrace_noRecord(new Throwable());
}
static String getStackTrace(String msg) {
return getStackTrace_noRecord(new Throwable(msg));
}
static String fixNewLines(String s) {
int i = indexOf(s, '\r');
if (i < 0) return s;
int l = s.length();
StringBuilder out = new StringBuilder(l);
out.append(s, 0, i);
for (; i < l; i++) {
char c = s.charAt(i);
if (c != '\r')
out.append(c);
else {
out.append('\n');
if (i+1 < l && s.charAt(i+1) == '\n') ++i;
}
}
return out.toString();
}
static void print_append(Appendable buf, String s, int max) { try {
synchronized(buf) {
buf.append(s);
if (buf instanceof StringBuffer)
rotateStringBuffer(((StringBuffer) buf), max);
else if (buf instanceof StringBuilder)
rotateStringBuilder(((StringBuilder) buf), max);
}
} catch (Exception __e) { throw rethrow(__e); } }
static void vmBus_send(String msg, Object... args) {
Object arg = vmBus_wrapArgs(args);
pcallFAll_minimalExceptionHandling(vm_busListeners_live(), msg, arg);
pcallFAll_minimalExceptionHandling(vm_busListenersByMessage_live().get(msg), msg, arg);
}
static void vmBus_send(String msg) {
vmBus_send(msg, (Object) null);
}
static A printStackTrace(A e) {
// we go to system.out now - system.err is nonsense
if (e != null) print(getStackTrace(e));
return e;
}
static void printStackTrace() {
printStackTrace(new Throwable());
}
static void printStackTrace(String msg) {
printStackTrace(new Throwable(msg));
}
static void printStackTrace(String msg, Throwable e) {
printStackTrace(new Throwable(msg, e));
}
static Map synchronizedMap() {
return synchroMap();
}
static Map synchronizedMap(Map map) {
return synchroMap(map);
}
static IF0 f0ToIF0(F0 f) {
return f == null ? null : () -> f.get();
}
static Map vm_generalMap_map;
static Map vm_generalMap() {
if (vm_generalMap_map == null)
vm_generalMap_map = (Map) get(javax(), "generalMap");
return vm_generalMap_map;
}
static Object vm_generalMap_put(Object key, Object value) {
return mapPutOrRemove(vm_generalMap(), key, value);
}
static Map newDangerousWeakHashMap() {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()));
}
// initFunction: voidfunc(Map) - is called initially, and after clearing the map
static Map newDangerousWeakHashMap(Object initFunction) {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction);
}
static Object invokeMethod(Method m, Object o, Object... args) { try {
try {
return m.invoke(o, args);
} catch (InvocationTargetException e) {
throw rethrow(getExceptionCause(e));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args)));
}
} catch (Exception __e) { throw rethrow(__e); } }
static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != l(args)) {
if (debug)
print("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++) {
Object arg = args[i];
if (!(arg == null ? !types[i].isPrimitive()
: isInstanceX(types[i], arg))) {
if (debug)
print("Bad parameter " + i + ": " + arg + " vs " + types[i]);
return false;
}
}
return true;
}
static final Map callOpt_cache = newDangerousWeakHashMap();
static Object callOpt_cached(Object o, String methodName, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
// TODO: (super-rare) case where method exists static and non-static
// with different args
Method me = cache.findMethod(methodName, args);
if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null;
return invokeMethod(me, null, args);
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(methodName, args);
if (me == null) return null;
return invokeMethod(me, o, args);
}
} catch (Exception __e) { throw rethrow(__e); } }
// no longer synchronizes! (see #1102990)
static _MethodCache callOpt_getCache(Class c) {
_MethodCache cache = callOpt_cache.get(c);
if (cache == null)
callOpt_cache.put(c, cache = new _MethodCache(c));
return cache;
}
static boolean isStaticMethod(Method m) {
return methodIsStatic(m);
}
static Object[] massageArgsForVarArgsCall(Executable m, Object[] args) {
Class>[] types = m.getParameterTypes();
int n = types.length-1, nArgs = l(args);
if (nArgs < n) return null;
for (int i = 0; i < n; i++)
if (!argumentCompatibleWithType(args[i], types[i]))
return null;
Class varArgType = types[n].getComponentType();
for (int i = n; i < nArgs; i++)
if (!argumentCompatibleWithType(args[i], varArgType))
return null;
Object[] newArgs = new Object[n+1];
arraycopy(args, 0, newArgs, 0, n);
// TODO: optimize
int nVarArgs = nArgs-n;
Object varArgs = Array.newInstance(varArgType, nVarArgs);
for (int i = 0; i < nVarArgs; i++)
Array.set(varArgs, i, args[n+i]);
newArgs[n] = varArgs;
return newArgs;
}
static String joinWithComma(Collection c) {
return join(", ", c);
}
static String joinWithComma(Object... c) {
return join(", ", c);
}
static String joinWithComma(String... c) {
return join(", ", c);
}
static String joinWithComma(Pair p) {
return p == null ? "" : joinWithComma(str(p.a), str(p.b));
}
static List classNames(Collection l) {
return getClassNames(l);
}
static List classNames(Object[] l) {
return getClassNames(asList(l));
}
// TODO: optimize (use getOpt_cache)
static void setOpt_raw(Object o, String field, Object value) { try {
if (o == null) return;
if (o instanceof Class) setOpt_raw((Class) o, field, value);
else {
Field f = setOpt_raw_findField(o.getClass(), field);
if (f != null) {
makeAccessible(f);
smartSet(f, o, value);
}
}
} catch (Exception __e) { throw rethrow(__e); } }
static void setOpt_raw(Class c, String field, Object value) { try {
if (c == null) return;
Field f = setOpt_raw_findStaticField(c, field);
if (f != null) {
makeAccessible(f);
smartSet(f, null, value);
}
} catch (Exception __e) { throw rethrow(__e); } }
static Field setOpt_raw_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field setOpt_raw_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static void smartSet(Field f, Object o, Object value) throws Exception {
try {
f.set(o, value);
} catch (Exception e) {
Class type = f.getType();
// take care of common case (long to int)
if (type == int.class && value instanceof Long)
{ f.set(o, ((Long) value).intValue()); return; }
if (type == boolean.class && value instanceof String)
{ f.set(o, isTrueOrYes(((String) value))); return; }
if (type == LinkedHashMap.class && value instanceof Map)
{ f.set(o, asLinkedHashMap((Map) value)); return; }
throw e;
}
}
static A setDyn(A o, String key, Object value) {
setDynObjectValue(o, key, value);
return o;
}
static void setDyn(IMeta o, String key, Object value) {
metaMapPut(o, key, value);
}
static Object pcallF(Object f, Object... args) {
return pcallFunction(f, args);
}
static A pcallF(F0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static B pcallF(F1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static void pcallF(VF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { printStackTrace(__e); }
}
static Object pcallF(Runnable r) {
try { { if (r != null) r.run(); } } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static A pcallF(IF0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static B pcallF(IF1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static List immutableEmptyList() {
return Collections.emptyList();
}
static byte[] emptyByteArray_a = new byte[0];
static byte[] emptyByteArray() { return emptyByteArray_a; }
static int[] emptyIntArray_a = new int[0];
static int[] emptyIntArray() { return emptyIntArray_a; }
static char[] emptyCharArray = new char[0];
static char[] emptyCharArray() { return emptyCharArray; }
static double[] emptyDoubleArray = new double[0];
static double[] emptyDoubleArray() { return emptyDoubleArray; }
static short[] emptyShortArray = new short[0];
static short[] emptyShortArray() { return emptyShortArray; }
static Map immutableEmptyMap() {
return Collections.emptyMap();
}
static Object[] emptyObjectArray_a = new Object[0];
static Object[] emptyObjectArray() { return emptyObjectArray_a; }
static Symbol emptySymbol_value;
static Symbol emptySymbol() {
if (emptySymbol_value == null) emptySymbol_value = symbol("");
return emptySymbol_value;
}
// unclear semantics as to whether return null on null
static ArrayList asList(A[] a) {
return a == null ? new ArrayList () : new ArrayList (Arrays.asList(a));
}
static ArrayList asList(int[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(long[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (long i : a) l.add(i);
return l;
}
static ArrayList asList(float[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (float i : a) l.add(i);
return l;
}
static ArrayList asList(double[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (double i : a) l.add(i);
return l;
}
static ArrayList asList(short[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (short i : a) l.add(i);
return l;
}
static ArrayList asList(Iterator it) {
ArrayList l = new ArrayList();
if (it != null)
while (it.hasNext())
l.add(it.next());
return l;
}
// disambiguation
static ArrayList asList(IterableIterator s) {
return asList((Iterator) s);
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Producer p) {
ArrayList l = new ArrayList();
A a;
if (p != null) while ((a = p.next()) != null)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static ArrayList asList(ReverseChain c) {
return c == null ? emptyList() : c.toList();
}
static List asList(Pair p) {
return p == null ? null : ll(p.a, p.b);
}
// TODO: JDK 17!! ?? No! Yes? Yes!!
static Object collectionMutex(List l) {
return l;
}
static Object collectionMutex(Object o) {
if (o instanceof List) return o;
// TODO: actually use our own maps so we can get the mutex properly
String c = className(o);
return o;
}
static ThreadLocal print_byThread() {
synchronized(print_byThread_lock) {
if (print_byThread == null)
print_byThread = new ThreadLocal();
}
return print_byThread;
}
// f can return false to suppress regular printing
// call print_raw within f to actually print something
static AutoCloseable tempInterceptPrint(F1 f) {
return tempSetThreadLocal(print_byThread(), f);
}
static void clear(Collection c) {
if (c != null) c.clear();
}
static void clear(Map map) {
if (map != null) map.clear();
}
static void put(Map map, A a, B b) {
if (map != null) map.put(a, b);
}
static void put(List l, int i, A a) {
if (l != null && i >= 0 && i < l(l)) l.set(i, a);
}
static List _registerDangerousWeakMap_preList;
static A _registerDangerousWeakMap(A map) {
return _registerDangerousWeakMap(map, null);
}
static A _registerDangerousWeakMap(A map, Object init) {
callF(init, map);
if (init instanceof String) {
final String f = (String) init;
init = new VF1() { public void get(Map map) { try { callMC(f, map) ; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "callMC(f, map)"; }};
}
if (javax() == null) {
// We're in class init
if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList();
_registerDangerousWeakMap_preList.add(pair(map, init));
return map;
}
call(javax(), "_registerDangerousWeakMap", map, init);
return map;
}
static void _onLoad_registerDangerousWeakMap() {
assertNotNull(javax());
if (_registerDangerousWeakMap_preList == null) return;
for (Pair p : _registerDangerousWeakMap_preList)
_registerDangerousWeakMap(p.a, p.b);
_registerDangerousWeakMap_preList = null;
}
static Class> _getClass(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static Class _getClass(Object o) {
return o == null ? null
: o instanceof Class ? (Class) o : o.getClass();
}
static Class _getClass(Object realm, String name) {
try {
return classLoaderForObject(realm).loadClass(classNameToVM(name));
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static B syncMapGet2(Map map, A a) {
if (map == null) return null;
synchronized(collectionMutex(map)) {
return map.get(a);
}
}
static B syncMapGet2(A a, Map map) {
return syncMapGet2(map, a);
}
static boolean isSubtypeOf(Class a, Class b) {
return a != null && b != null && b.isAssignableFrom(a); // << always hated that method, let's replace it!
}
static Set reflection_classesNotToScan_value = litset(
"jdk.internal.loader.URLClassPath"
);
static Set reflection_classesNotToScan() {
return reflection_classesNotToScan_value;
}
static boolean endsWithLetterOrDigit(String s) {
return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length()-1));
}
// PersistableThrowable doesn't hold GC-disturbing class references in backtrace
static volatile PersistableThrowable lastException_lastException;
static PersistableThrowable lastException() {
return lastException_lastException;
}
static void lastException(Throwable e) {
lastException_lastException = persistableThrowable(e);
}
static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); }
static String hideCredentials(String url) {
try {
if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url;
} catch (Throwable e) {
print("HideCredentials", e);
}
return url.replaceAll("([&?])(_pass|key|cookie)=[^&\\s\"]*", "$1$2=");
}
static String hideCredentials(Object o) {
return hideCredentials(str(o));
}
static int indexOf(List l, A a, int startIndex) {
if (l == null) return -1;
int n = l(l);
for (int i = startIndex; i < n; i++)
if (eq(l.get(i), a))
return i;
return -1;
}
static int indexOf(List l, int startIndex, A a) {
return indexOf(l, a, startIndex);
}
static int indexOf(List l, A a) {
if (l == null) return -1;
return l.indexOf(a);
}
static int indexOf(String a, String b) {
return a == null || b == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, String b, int i) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, char b) {
return a == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, int i, char b) {
return indexOf(a, b, i);
}
static int indexOf(String a, char b, int i) {
return a == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, int i, String b) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(A[] x, A a) {
int n = l(x);
for (int i = 0; i < n; i++)
if (eq(x[i], a))
return i;
return -1;
}
static int indexOf(Iterable l, A a) {
if (l == null) return -1;
int i = 0;
for (A x : l) {
if (eq(x, a))
return i;
i++;
}
return -1;
}
static void rotateStringBuffer(StringBuffer buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static void rotateStringBuilder(StringBuilder buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static Object vmBus_wrapArgs(Object... args) {
return empty(args) ? null
: l(args) == 1 ? args[0]
: args;
}
static void pcallFAll_minimalExceptionHandling(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) { ping(); pcallF_minimalExceptionHandling(f, args); }
}
static void pcallFAll_minimalExceptionHandling(Iterator it, Object... args) {
while (it.hasNext()) { ping(); pcallF_minimalExceptionHandling(it.next(), args); }
}
static Set vm_busListeners_live_cache;
static Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache;}
static Set vm_busListeners_live_load() {
return vm_generalIdentityHashSet("busListeners");
}
static Map vm_busListenersByMessage_live_cache;
static Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache;}
static Map vm_busListenersByMessage_live_load() {
return vm_generalHashMap("busListenersByMessage");
}
static B mapPutOrRemove(Map map, A key, B value) {
if (map != null && key != null)
if (value != null) return map.put(key, value);
else return map.remove(key);
return null;
}
static Throwable getExceptionCause(Throwable e) {
Throwable c = e.getCause();
return c != null ? c : e;
}
static String joinWithSpace(Iterable c) {
return join(" ", c);
}
static String joinWithSpace(Object... c) {
return join(" ", c);
}
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static boolean methodIsStatic(Method m) {
return (m.getModifiers() & Modifier.STATIC) != 0;
}
static boolean argumentCompatibleWithType(Object arg, Class type) {
return arg == null ? !type.isPrimitive() : isInstanceX(type, arg);
}
static void arraycopy(Object[] a, Object[] b) {
if (a != null && b != null)
arraycopy(a, 0, b, 0, Math.min(a.length, b.length));
}
static void arraycopy(Object src, int srcPos, int destPos, int n) { arraycopy(src, srcPos, src, destPos, n); }
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) {
if (n != 0)
System.arraycopy(src, srcPos, dest, destPos, n);
}
public static String join(String glue, Iterable strings) {
if (strings == null) return "";
if (strings instanceof Collection) {
if (((Collection) strings).size() == 1) return str(first((Collection) strings));
}
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String... strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(String glue, Object... strings) {
return join(glue, Arrays.asList(strings));
}
static String join(Iterable strings) {
return join("", strings);
}
static String join(Iterable strings, String glue) {
return join(glue, strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String join(String glue, Pair p) {
return p == null ? "" : str(p.a) + glue + str(p.b);
}
static List getClassNames(Collection l) {
List out = new ArrayList();
if (l != null) for (Object o : l)
out.add(o == null ? null : getClassName(o));
return out;
}
static boolean isTrueOrYes(Object o) {
return isTrueOpt(o) || o instanceof String && (eqicOneOf(((String) o), "1", "t", "true") || isYes(((String) o)));
}
static LinkedHashMap asLinkedHashMap(Map map) {
if (map instanceof LinkedHashMap) return (LinkedHashMap) map;
LinkedHashMap m = new LinkedHashMap();
if (map != null) synchronized(collectionMutex(map)) {
m.putAll(map);
}
return m;
}
static void setDynObjectValue(DynamicObject o, String field, Object value) {
dynamicObject_setRawFieldValue(o, field, value);
}
static void metaMapPut(IMeta o, Object key, Object value) {
{ if (o != null) o.metaPut(key, value); }
}
static void metaMapPut(Object o, Object key, Object value) {
var meta = initIMeta(o);
{ if (meta != null) meta.metaPut(key, value); }
}
static Object pcallFunction(Object f, Object... args) {
try { return callFunction(f, args); } catch (Throwable __e) { printStackTrace(__e); }
return null;
}
static WeakHasherMap symbol_map = new WeakHasherMap(new Hasher() {
public int hashCode(Symbol symbol) { return symbol.text.hashCode(); }
public boolean equals(Symbol a, Symbol b) {
if (a == null) return b == null;
return b != null && eq(a.text, b.text);
}
});
static Symbol symbol(String s) {
if (s == null) return null;
synchronized(symbol_map) {
// TODO: avoid object creation by passing the string to findKey
Symbol symbol = new Symbol(s, true);
Symbol existingSymbol = symbol_map.findKey(symbol);
if (existingSymbol == null)
symbol_map.put(existingSymbol = symbol, true);
return existingSymbol;
}
}
static Symbol symbol(CharSequence s) {
if (s == null) return null;
if (s instanceof Symbol) return (Symbol) s;
if (s instanceof String) return symbol((String) s);
return symbol(str(s));
}
static Symbol symbol(Object o) {
return symbol((CharSequence) o);
}
static ArrayList emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static ArrayList emptyList(int capacity) {
return new ArrayList(max(0, capacity));
}
// Try to match capacity
static ArrayList emptyList(Iterable l) {
return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList();
}
static ArrayList emptyList(Object[] l) {
return emptyList(l(l));
}
// get correct type at once
static ArrayList emptyList(Class c) {
return new ArrayList();
}
static String className(Object o) {
return getClassName(o);
}
static AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) {
if (tl == null) return null;
final A prev = setThreadLocal(tl, a);
return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); }};
}
static HashMap> callMC_cache = new HashMap();
static String callMC_key;
static Method callMC_value;
// varargs assignment fixer for a single string array argument
static Object callMC(String method, String[] arg) {
return callMC(method, new Object[] {arg});
}
static Object callMC(String method, Object... args) { try {
Method me;
if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround
synchronized(callMC_cache) {
me = method == callMC_key ? callMC_value : null;
}
if (me != null) try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
List m;
synchronized(callMC_cache) {
m = callMC_cache.get(method);
}
if (m == null) {
if (callMC_cache.isEmpty()) {
callMC_makeCache();
m = callMC_cache.get(method);
}
if (m == null) throw fail("Method named " + method + " not found in main");
}
int n = m.size();
if (n == 1) {
me = m.get(0);
synchronized(callMC_cache) {
callMC_key = method;
callMC_value = me;
}
try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
}
for (int i = 0; i < n; i++) {
me = m.get(i);
if (call_checkArgs(me, args, false))
return invokeMethod(me, null, args);
}
throw fail("No method called " + method + " with arguments (" + joinWithComma(getClasses(args)) + ") found in main");
} catch (Exception __e) { throw rethrow(__e); } }
static void callMC_makeCache() {
synchronized(callMC_cache) {
callMC_cache.clear();
Class _c = (Class) mc(), c = _c;
while (c != null) {
for (Method m : c.getDeclaredMethods())
if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) {
makeAccessible(m);
multiMapPut(callMC_cache, m.getName(), m);
}
c = c.getSuperclass();
}
}
}
static ClassLoader classLoaderForObject(Object o) {
if (o instanceof ClassLoader) return ((ClassLoader) o);
if (o == null) return null;
return _getClass(o).getClassLoader();
}
// Note: This is actually broken. Inner classes must stay with a $ separator
static String classNameToVM(String name) {
return name.replace(".", "$");
}
static HashSet litset(A... items) {
return lithashset(items);
}
static PersistableThrowable persistableThrowable(Throwable e) {
return e == null ? null : new PersistableThrowable(e);
}
static boolean startsWithOneOf(String s, String... l) {
for (String x : l) if (startsWith(s, x)) return true; return false;
}
static boolean startsWithOneOf(String s, Matches m, String... l) {
for (String x : l) if (startsWith(s, x, m)) return true; return false;
}
static boolean isAGIBlueDomain(String domain) {
return domainIsUnder(domain, theAGIBlueDomain());
}
static String hostNameFromURL(String url) { try {
return empty(url) ? null : new URL(url).getHost();
} catch (Exception __e) { throw rethrow(__e); } }
static Object pcallF_minimalExceptionHandling(Object f, Object... args) {
try {
return callFunction(f, args);
} catch (Throwable e) {
System.out.println(getStackTrace(e));
_storeException(e);
}
return null;
}
static Set vm_generalIdentityHashSet(Object name) {
synchronized(vm_generalMap()) {
Set set = (Set) (vm_generalMap_get(name));
if (set == null)
vm_generalMap_put(name, set = syncIdentityHashSet());
return set;
}
}
static Map vm_generalHashMap(Object name) {
synchronized(vm_generalMap()) {
Map m = (Map) (vm_generalMap_get(name));
if (m == null)
vm_generalMap_put(name, m = syncHashMap());
return m;
}
}
static boolean isTrueOpt(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
return false;
}
static boolean isTrueOpt(String field, Object o) {
return isTrueOpt(getOpt(field, o));
}
static boolean eqicOneOf(String s, String... l) {
for (String x : l) if (eqic(s, x)) return true; return false;
}
static List isYes_yesses = litlist("y", "yes", "yeah", "y", "yup", "yo", "corect", "sure", "ok", "afirmative"); // << collapsed words, so "corect" means "correct"
static boolean isYes(String s) {
return isYes_yesses.contains(collapseWord(toLowerCase(firstWord2(s))));
}
static void dynamicObject_setRawFieldValue(DynamicObject o, Object key, Object value) {
if (o == null) return;
// double sync, but should be OK here because of locking order o > o.fieldValues
synchronized(o) {
o.fieldValues = syncMapPut2_createLinkedHashMap((LinkedHashMap) o.fieldValues, key, value);
}
}
static IMeta initIMeta(Object o) {
if (o == null) return null;
if (o instanceof IMeta) return ((IMeta) o);
if (o instanceof JComponent) return initMetaOfJComponent((JComponent) o);
// This is not really used. Try to use BufferedImageWithMeta instead
if (o instanceof BufferedImage) return optCast(IMeta.class, ((BufferedImage) o).getProperty("meta"));
return null;
}
static Object callFunction(Object f, Object... args) {
return callF(f, args);
}
static int max(int a, int b) { return Math.max(a, b); }
static int max(int a, int b, int c) { return max(max(a, b), c); }
static long max(int a, long b) { return Math.max((long) a, b); }
static long max(long a, long b) { return Math.max(a, b); }
static double max(int a, double b) { return Math.max((double) a, b); }
static float max(float a, float b) { return Math.max(a, b); }
static double max(double a, double b) { return Math.max(a, b); }
static > A max (Iterable l) {
A max = null;
var it = iterator(l);
if (it.hasNext()) {
max = it.next();
while (it.hasNext()) {
A a = it.next();
if (cmp(a, max) > 0)
max = a;
}
}
return max;
}
/*Nah.
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
ret x;
}*/
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static float max(float[] c) {
if (c.length == 0) return Float.MAX_VALUE;
float x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static short max(short[] c) {
short x = -0x8000;
for (short d : c) if (d > x) x = d;
return x;
}
static int max(int[] c) {
int x = Integer.MIN_VALUE;
for (int d : c) if (d > x) x = d;
return x;
}
static > A max(A a, A b) {
return cmp(a, b) >= 0 ? a : b;
}
static A setThreadLocal(ThreadLocal tl, A value) {
if (tl == null) return null;
A old = tl.get();
tl.set(value);
return old;
}
static List getClasses(Object[] array) {
List l = emptyList(l(array));
for (Object o : array) l.add(_getClass(o));
return l;
}
static void multiMapPut(Map > map, A a, B b) {
List l = map.get(a);
if (l == null)
map.put(a, l = new ArrayList());
l.add(b);
}
static void multiMapPut(MultiMap mm, A key, B value) {
if (mm != null && key != null && value != null) mm.put(key, value);
}
static HashSet lithashset(A... items) {
HashSet set = new HashSet();
for (A a : items) set.add(a);
return set;
}
static boolean startsWith(String a, String b) {
return a != null && a.startsWith(unnull(b));
}
static boolean startsWith(String a, char c) {
return nemptyString(a) && a.charAt(0) == c;
}
static boolean startsWith(String a, String b, Matches m) {
if (!startsWith(a, b)) return false;
if (m != null) m.m = new String[] {substring(a, strL(b))};
return true;
}
static boolean startsWith(List a, List b) {
if (a == null || listL(b) > listL(a)) return false;
for (int i = 0; i < listL(b); i++)
if (neq(a.get(i), b.get(i)))
return false;
return true;
}
static boolean domainIsUnder(String domain, String mainDomain) {
return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain);
}
static String theAGIBlueDomain() {
return "agi.blue";
}
static Throwable _storeException_value;
static void _storeException(Throwable e) {
_storeException_value = e;
}
static Set syncIdentityHashSet() {
return (Set) synchronizedSet(identityHashSet());
}
static Map syncHashMap() {
return synchroHashMap();
}
static boolean eqic(String a, String b) {
if ((a == null) != (b == null)) return false;
if (a == null) return true;
return a.equalsIgnoreCase(b);
}
static boolean eqic(Symbol a, Symbol b) {
return eq(a, b);
}
static boolean eqic(Symbol a, String b) {
return eqic(asString(a), b);
}
static boolean eqic(char a, char b) {
if (a == b) return true;
char u1 = Character.toUpperCase(a);
char u2 = Character.toUpperCase(b);
if (u1 == u2) return true;
return Character.toLowerCase(u1) == Character.toLowerCase(u2);
}
static ArrayList litlist(A... a) {
ArrayList l = new ArrayList(a.length);
for (A x : a) l.add(x);
return l;
}
static String collapseWord(String s) {
if (s == null) return "";
StringBuilder buf = new StringBuilder();
for (int i = 0; i < l(s); i++)
if (i == 0 || !charactersEqualIC(s.charAt(i), s.charAt(i-1)))
buf.append(s.charAt(i));
return buf.toString();
}
static List toLowerCase(List strings) {
List x = new ArrayList();
for (String s : strings)
x.add(s.toLowerCase());
return x;
}
static String[] toLowerCase(String[] strings) {
String[] x = new String[l(strings)];
for (int i = 0; i < l(strings); i++)
x[i] = strings[i].toLowerCase();
return x;
}
static String toLowerCase(String s) {
return s == null ? "" : s.toLowerCase();
}
static String firstWord2(String s) {
s = xltrim(s);
if (empty(s)) return "";
if (isLetterOrDigit(first(s)))
return takeCharsWhile(__22 -> isLetterOrDigit(__22), s);
else return "" + first(s);
}
static LinkedHashMap syncMapPut2_createLinkedHashMap(LinkedHashMap map, A key, B value) {
if (key != null)
if (value != null) {
if (map == null) map = new LinkedHashMap();
synchronized(collectionMutex(map)) { map.put(key, value); }
} else if (map != null) synchronized(collectionMutex(map)) { map.remove(key); }
return map;
}
static IMeta initMetaOfJComponent(JComponent c) {
if (c == null) return null;
IMeta meta = (IMeta) (c.getClientProperty(IMeta.class));
if (meta == null)
c.putClientProperty(IMeta.class, meta = new Meta());
return meta;
}
static A optCast(Class c, Object o) {
return isInstance(c, o) ? (A) o : null;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static Collection unnull(Collection l) {
return l == null ? emptyList() : l;
}
static List unnull(List l) { return l == null ? emptyList() : l; }
static int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; }
static Map unnull(Map l) {
return l == null ? emptyMap() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static A[] unnull(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnull(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnull(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnull(Pair p) {
return p != null ? p : new Pair(null, null);
}
static int unnull(Integer i) { return i == null ? 0 : i; }
static long unnull(Long l) { return l == null ? 0L : l; }
static double unnull(Double l) { return l == null ? 0.0 : l; }
static boolean nemptyString(String s) {
return s != null && s.length() > 0;
}
static String substring(String s, int x) {
return substring(s, x, strL(s));
}
static String substring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
int n = s.length();
if (y < x) y = x;
if (y > n) y = n;
if (x >= y) return "";
return s.substring(x, y);
}
// convenience method for quickly dropping a prefix
static String substring(String s, CharSequence l) {
return substring(s, lCharSequence(l));
}
static int strL(String s) {
return s == null ? 0 : s.length();
}
static int listL(Collection l) {
return l == null ? 0 : l.size();
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static boolean ewic(String a, String b) {
return endsWithIgnoreCase(a, b);
}
static boolean ewic(String a, String b, Matches m) {
return endsWithIgnoreCase(a, b, m);
}
static Set synchronizedSet() {
return synchroHashSet();
}
static Set synchronizedSet(Set set) {
return Collections.synchronizedSet(set);
}
static Set identityHashSet() {
return Collections.newSetFromMap(new IdentityHashMap());
}
static String asString(Object o) {
return o == null ? null : o.toString();
}
static boolean charactersEqualIC(char c1, char c2) {
if (c1 == c2) return true;
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) return true;
return Character.toLowerCase(u1) == Character.toLowerCase(u2);
}
static String xltrim(String s) {
int i = 0, n = l(s);
while (i < n && contains(" \t\r\n", s.charAt(i)))
++i;
return substr(s, i);
}
static boolean isLetterOrDigit(char c) {
return Character.isLetterOrDigit(c);
}
// pred: char -> bool
static String takeCharsWhile(String s, Object pred) {
int i = 0;
while (i < l(s) && isTrue(callF(pred, s.charAt(i)))) ++i;
return substring(s, 0, i);
}
static String takeCharsWhile(IF1 f, String s) {
return takeCharsWhile(s, f);
}
static boolean isInstance(Class type, Object arg) {
return type.isInstance(arg);
}
static Map emptyMap() {
return new HashMap();
}
static int lCharSequence(CharSequence s) {
return s == null ? 0 : s.length();
}
static boolean endsWithIgnoreCase(String a, String b) {
int la = l(a), lb = l(b);
return la >= lb && regionMatchesIC(a, la-lb, b, 0, lb);
}
static boolean endsWithIgnoreCase(String a, String b, Matches m) {
if (!endsWithIgnoreCase(a, b)) return false;
if (m != null)
m.m = new String[] { substring(a, 0, l(a)-l(b)) };
return true;
}
static Set synchroHashSet() {
return synchronizedSet(new HashSet ());
}
static boolean contains(Collection c, Object o) {
return c != null && c.contains(o);
}
static boolean contains(Iterable it, Object a) {
if (it != null)
for (Object o : it)
if (eq(a, o))
return true;
return false;
}
static boolean contains(Object[] x, Object o) {
if (x != null)
for (Object a : x)
if (eq(a, o))
return true;
return false;
}
static boolean contains(String s, char c) {
return s != null && s.indexOf(c) >= 0;
}
static boolean contains(String s, String b) {
return s != null && s.indexOf(b) >= 0;
}
static boolean contains(BitSet bs, int i) {
return bs != null && bs.get(i);
}
static boolean contains(Producer p, A a) {
if (p != null && a != null) while (true) {
A x = p.next();
if (x == null) break;
if (eq(x, a)) return true;
}
return false;
}
static boolean contains(Rect r, Pt p) { return rectContains(r, p); }
static String substr(String s, int x) {
return substring(s, x);
}
static String substr(String s, int x, int y) {
return substring(s, x, y);
}
static boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) {
return a != null && a.regionMatches(true, offsetA, b, offsetB, len);
}
static boolean rectContains(int x1, int y1, int w, int h, Pt p) {
return p.x >= x1 && p.y >= y1 && p.x < x1+w && p.y < y1+h;
}
static boolean rectContains(Rect a, Rect b) {
return b.x >= a.x && b.y >= a.y && b.x2() <= a.x2() && b.y2() <= a.y2();
}
static boolean rectContains(Rect a, Rectangle b) {
return rectContains(a, toRect(b));
}
static boolean rectContains(Rect a, int x, int y) {
return a != null && a.contains(x, y);
}
static boolean rectContains(Rect a, Pt p) {
return a != null && p != null && a.contains(p);
}
static Rect toRect(Rectangle r) {
return r == null ? null : new Rect(r);
}
static Rect toRect(RectangularShape r) {
return r == null ? null : toRect(r.getBounds());
}
static Rect toRect(Rect r) { return r; }
static int iround(double d) {
return (int) Math.round(d);
}
static int iround(Number n) {
return iround(toDouble(n));
}
static double toDouble(Object o) {
if (o instanceof Number)
return ((Number) o).doubleValue();
if (o instanceof BigInteger)
return ((BigInteger) o).doubleValue();
if (o instanceof String)
return parseDouble((String) o);
if (o == null) return 0.0;
throw fail(o);
}
static double parseDouble(String s) {
return empty(s) ? 0.0 : Double.parseDouble(s);
}
static abstract class VF1 implements IVF1 {
public abstract void get(A a);
}
// immutable, has strong refs
// Do not run in a synchronized block - it goes wrong in the presence
// of elaborate classloaders (like in Gazelle BEA)
// see #1102990 and #1102991
final static class _MethodCache {
final Class c;
final HashMap> cache = new HashMap();
_MethodCache(Class c) {
this.c = c; _init(); }
void _init() {
Class _c = c;
java.lang.Module myModule = getClass().getModule();
boolean anyHiddenClasses = false;
while (_c != null) {
boolean exported = classIsExportedTo(_c, myModule);
if (!exported)
anyHiddenClasses = true;
else
for (Method m : _c.getDeclaredMethods())
if ((anyHiddenClasses || !isAbstract(m))
&& !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
_c = _c.getSuperclass();
}
// add default methods - this might lead to a duplication
// because the overridden method is also added, but it's not
// a problem except for minimal performance loss.
// If any classes in the hierarchy were inaccessible, we add
// all interface methods (see test_callForbiddenMethodByReflection for a test)
for (Class intf : allInterfacesImplementedBy(c))
for (Method m : intf.getDeclaredMethods())
if ((anyHiddenClasses || m.isDefault()) && !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
}
// Returns only matching methods
Method findMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
Method findStaticMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (isStaticMethod(me) && call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
//Cl allMethods() { ret allValues(cache); }
}
// Meta - a "minimal" approach to adding meta-level to Java objects
static class Meta implements IMeta {
// Meta - a "minimal" approach to adding meta-level to Java objects
// (implementing the interface IMeta)
// We allocate one extra field for each Java object to make it
// reasoning-compatible (reasoning-compatible = extensible with
// fields of any name at runtime).
//
// We couldn't go for 0 extra fields (meta values must be linked
// directly from the object) and there are no half fields in
// Java... so there you go.
//
// Also, if you don't use any meta data, you are probably not
// reasoning about anything. The point of reasoning in JavaX is
// to attach information to objects directly used in the program.
// Possible information contained in the meta field:
// Origin, destination, security level, sender, cost center,
// purpose, list of reifications, ...
// So here it is. THE FIELD YOU HAVE BEEN WAITING FOR!
// [We also have IMeta to retrofit foreign classes (rare but
// probably useful).]
//////////////////////
// The "meta" field //
//////////////////////
// Generic meta value of any kind, but the typical case is it's a
// Map with extra field values for the object etc.
// "meta" is volatile to avoid synchronization; but you can also synchronize on
// _tempMetaMutex() which is usually the object itself. Collections
// and maps are exempt from using the collections's monitor as the meta
// mutex because their monitor tends to be held for long operations
// (e.g. cloneList). For those we use a substantially more complex
// algorithm using a weakMap. Probably overkill. I may reconsider.
volatile Object meta;
// The meta field is not transient, thus by default it will be
// persisted like anything else unless you customize your object
// to suppress or modulate this.
// ...and the interface methods
public void _setMeta(Object meta) { this.meta = meta; }
public Object _getMeta() { return meta; }
// MOST functions are implemented in IMeta (default implementations)
// Scaffolding convenience functions
final boolean scaffolding(){ return scaffoldingEnabled(); }
boolean scaffoldingEnabled() { return main.scaffoldingEnabled(this); }
boolean scaffoldingEnabled(Object o) { return main.scaffoldingEnabled(o); }
}
static class Matches {
String[] m;
Matches() {}
Matches(String... m) {
this.m = m;}
String get(int i) { return i < m.length ? m[i] : null; }
String unq(int i) { return unquote(get(i)); }
String tlc(int i) { return unq(i).toLowerCase(); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
int psi(int i) { return Integer.parseInt(unq(i)); }
public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; }
public int hashCode() { return _hashCode(toList(m)); }
public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); }
}
// for the version with MasterSymbol (used WAY back in "Smart Bot"!) see #1010608
static class Symbol implements CharSequence {
String text;
Symbol() {}
Symbol(String text, boolean dummy) {
this.text = text;} // weird signature to prevent accidental calling
public int hashCode() { return _hashCode(text); }
public String toString() { return text; }
public boolean equals(Object o) {
return this == o;
}
// implementation of CharSequence methods
public int length() { return text.length(); }
public char charAt(int index) { return text.charAt(index); }
public CharSequence subSequence(int start, int end) {
return text.substring(start, end);
}
}
static interface IMeta {
// see class "Meta" for the bla bla
public void _setMeta(Object meta);
public Object _getMeta();
default public IAutoCloseableF0 _tempMetaMutex() {
return new IAutoCloseableF0() {
public Object get() { return IMeta.this; }
public void close() {}
};
}
// actually query another object
default public Object getMeta(Object obj, Object key){ return metaGet(obj, key); }
default public Object metaGet(Object obj, Object key) {
// call global function
return metaMapGet(obj, key);
}
default public Object metaGet(String key, Object obj) {
// call global function
return metaMapGet(obj, key);
}
default public Object getMeta(Object key){ return metaGet(key); }
default public Object metaGet(Object key) {
if (key == null) return null;
Object meta = _getMeta();
if (meta instanceof Map) return ((Map) meta).get(key);
return null;
}
default public void metaSet(IMeta obj, Object key, Object value){ metaPut(obj, key, value); }
default public void metaPut(IMeta obj, Object key, Object value) {
// call global function
metaMapPut(obj, key, value);
}
default public void metaSet(Object key, Object value){ metaPut(key, value); }
default public void metaPut(Object key, Object value) {
if (key == null) return;
Map map = convertObjectMetaToMap(this);
syncMapPutOrRemove(map, key, value);
}
}
// In the newest pinging system (with flag PingV3), a ping source
// is the object that "allows" some code to run.
// When that code calls ping(), the ping source's action (if defined)
// is triggered.
// This allows randomly interrupting code execution, for example.
static class PingSource {
// returns true if it slept
final public PingSource setAction(IF0 action){ return action(action); }
public PingSource action(IF0 action) { this.action = action; return this; } final public IF0 getAction(){ return action(); }
public IF0 action() { return action; }
volatile IF0 action;
// optional description of this ping source
String text;
// optional thread pool that this ping source likes to run in
ThreadPool threadPool;
PingSource() {}
PingSource(ThreadPool threadPool) {
this.threadPool = threadPool;}
PingSource(ThreadPool threadPool, String text) {
this.text = text;
this.threadPool = threadPool;}
PingSource(IF0 action) {
this.action = action;}
// returns true if it slept
final boolean get() {
var a = action;
return a != null && a.get();
}
final void ping() {
var a = action;
if (a != null) a.get();
}
void cancel() {
action = new Cancelled();
}
class Cancelled implements IF0 {
public Boolean get() { throw new PingSourceCancelledException(PingSource.this); }
}
class Encapsulated implements Runnable , IFieldsToList{
Runnable r;
Encapsulated() {}
Encapsulated(Runnable r) {
this.r = r;}public Object[] _fieldsToList() { return new Object[] {r}; }
public void run() { try {
//System.out.println("Encapsulated running: " + r);
try {
pingSource_tl().set(PingSource.this);
//System.out.println("Ping source set");
ping();
r.run();
//System.out.println("Done running");
} finally {
//System.out.println("Finally");
pingSource_tl().set(null);
}
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return PingSource.this + ": " + r; }
}
void dO(Runnable r) {
if (r == null) return;
threadPool.acquireThreadOrQueue(new Encapsulated(r));
}
public String toString() { String t = text; return nempty(t) ? t : super.toString(); }
ISleeper_v2 sleeper() { return threadPool.sleeper(); }
}
// records its full size (total value count) in a field now
static class MultiMap implements IMultiMap {
Map > data = new HashMap >();
int fullSize;
MultiMap() {}
MultiMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); }
MultiMap(MultiMap map) { putAll(map); }
MultiMap(Map > data) {
this.data = data;}
void put(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
list.add(value);
++fullSize;
}}
void add(A key, B value) { put(key, value); }
void addAll(A key, Collection values) { putAll(key, values); }
void addAllIfNotThere(A key, Collection values) { synchronized(data) {
for (B value : values)
setPut(key, value);
}}
void setPut(A key, B value) { synchronized(data) {
if (!containsPair(key, value))
put(key, value);
}}
boolean containsPair(A key, B value) { synchronized(data) {
return get(key).contains(value);
}}
void putAll(Collection keys, B value) { synchronized(data) {
for (A key : unnullForIteration(keys))
put(key, value);
}}
void putAll(A key, Collection values) { synchronized(data) {
if (nempty(values)) getActual(key).addAll(values);
}}
void putAll(Iterable> pairs) { synchronized(data) {
for (Pair p : unnullForIteration(pairs))
put(p.a, p.b);
}}
void removeAll(A key, Collection values) { synchronized(data) {
for (B value : values)
remove(key, value);
}}
public List get(A key) { synchronized(data) {
List list = data.get(key);
return list == null ? Collections. emptyList() : list;
}}
List getOpt(A key) { synchronized(data) {
return data.get(key);
}}
List getAndClear(A key) { synchronized(data) {
List l = cloneList(data.get(key));
remove(key);
return l;
}}
// returns actual mutable live list
// creates the list if not there
List getActual(A key) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
return list;
}}
void clean(A key) { synchronized(data) {
List list = data.get(key);
if (list != null && list.isEmpty()) {
fullSize -= l(list);
data.remove(key);
}
}}
final public Set keys(){ return keySet(); }
public Set keySet() { synchronized(data) {
return data.keySet();
}}
void remove(A key) { synchronized(data) {
fullSize -= l(this.getOpt(key));
data.remove(key);
}}
final void remove(Pair p){ removePair(p); }
void removePair(Pair p) {
if (p != null) remove(p.a, p.b);
}
void remove(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list != null) {
if (list.remove(value))
fullSize--;
if (list.isEmpty())
data.remove(key);
}
}}
void clear() { synchronized(data) {
data.clear();
}}
boolean containsKey(A key) { synchronized(data) {
return data.containsKey(key);
}}
B getFirst(A key) { synchronized(data) {
List list = get(key);
return list.isEmpty() ? null : list.get(0);
}}
void addAll(MultiMap map) { putAll(map); }
void putAll(MultiMap map) { synchronized(data) {
for (A key : map.keySet())
putAll(key, map.get(key));
}}
void putAll(Map map) { synchronized(data) {
if (map != null) for (Map.Entry e : map.entrySet())
put(e.getKey(), e.getValue());
}}
final public int keyCount(){ return keysSize(); }
public int keysSize() { synchronized(data) { return l(data); }}
final public int fullSize(){ return size(); }
public int size() { synchronized(data) {
return fullSize;
}}
// expensive operation
List reverseGet(B b) { synchronized(data) {
List l = new ArrayList();
for (A key : data.keySet())
if (data.get(key).contains(b))
l.add(key);
return l;
}}
Map > asMap() { synchronized(data) {
return cloneMap(data);
}}
boolean isEmpty() { synchronized(data) { return data.isEmpty(); }}
// override in subclasses
List _makeEmptyList() {
return new ArrayList();
}
// returns live lists
Collection> allLists() {
synchronized(data) {
return new ArrayList(data.values());
}
}
Collection> values() { return allLists(); }
List allValues() {
return concatLists(data.values());
}
Object mutex() { return data; }
public String toString() { return "mm" + str(data); }
}
// AppendableChain has one "smart" head element (with size counter
// and pointer to the chain's last element), all the other nodes are
// maximally simple (MinimalChain).
// This allows O(1) front insertion, front removal and back insertion
// (not removal at the back though) which is fine for what I need this
// for (event queues).
//
// Stefan Reich, Oct 21
static class AppendableChain extends MinimalChain implements Iterable {
MinimalChain last; // pointer to last element in chain (which may be us)
int size; // total length of chain
AppendableChain() {} // only used internally
AppendableChain(A element) {
this.element = element; size = 1; last = this; }
// intermediate constructor called by itemPlusChain()
AppendableChain(A element, AppendableChain next) {
this.next = next;
this.element = element;
if (next == null) return;
MinimalChain b = new MinimalChain();
b.element = next.element;
b.next = next.next;
this.next = b;
last = next.last;
size = next.size+1;
}
public String toString() { return str(toList()); }
// append at the end
boolean add(A a) {
MinimalChain newLast = new MinimalChain(a);
last.next = newLast;
last = newLast;
++size;
return true;
}
// drop first element
AppendableChain popFirst() {
if (next == null) return null;
element = next.element;
if (last == next) last = this;
next = next.next;
--size;
return this;
}
ArrayList toList() {
ArrayList l = emptyList(size);
MinimalChain c = this;
while (c != null) {
l.add(c.element);
c = c.next;
}
return l;
}
//public Iterator iterator() { ret toList().iterator(); }
class ACIt extends IterableIterator < A > {
MinimalChain c = AppendableChain.this;
public boolean hasNext() {
return c != null;
}
public A next() {
var a = c.element;
c = c.next;
return a;
}
}
public IterableIterator iterator() {
return new ACIt();
}
}
/*
* @(#)WeakHashMap.java 1.5 98/09/30
*
* Copyright 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
// From https://github.com/mernst/plume-lib/blob/df0bfafc3c16848d88f4ea0ef3c8bf3367ae085e/java/src/plume/WeakHasherMap.java
static final class WeakHasherMap extends AbstractMap implements Map {
private Hasher hasher = null;
/*@Pure*/
private boolean keyEquals(Object k1, Object k2) {
return (hasher==null ? k1.equals(k2)
: hasher.equals(k1, k2));
}
/*@Pure*/
private int keyHashCode(Object k1) {
return (hasher==null ? k1.hashCode()
: hasher.hashCode(k1));
}
// The WeakKey class can't be static because it depends on the hasher.
// That in turn means that its methods can't be static.
// However, I need to be able to call the methods such as create() that
// were static in the original version of this code.
// This finesses that.
private /*@Nullable*/ WeakKey WeakKeyCreate(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private /*@Nullable*/ WeakKey WeakKeyCreate(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
// Cannot be a static class: uses keyHashCode() and keyEquals()
private final class WeakKey extends WeakReference {
private int hash; /* Hashcode of key, stored here since the key
may be tossed by the GC */
private WeakKey(K k) {
super(k);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private WeakKey(K k, ReferenceQueue super K> q) {
super(k, q);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
/* A WeakKey is equal to another WeakKey iff they both refer to objects
that are, in turn, equal according to their own equals methods */
/*@Pure*/
@Override
public boolean equals(/*@Nullable*/ Object o) {
if (o == null) return false; // never happens
if (this == o) return true;
// This test is illegal because WeakKey is a generic type,
// so use the getClass hack below instead.
// if (!(o instanceof WeakKey)) return false;
if (!(o.getClass().equals(WeakKey.class))) return false;
Object t = this.get();
@SuppressWarnings("unchecked")
Object u = ((WeakKey)o).get();
if ((t == null) || (u == null)) return false;
if (t == u) return true;
return keyEquals(t, u);
}
/*@Pure*/
@Override
public int hashCode() {
return hash;
}
}
/* Hash table mapping WeakKeys to values */
private HashMap hash;
/* Reference queue for cleared WeakKeys */
private ReferenceQueue super K> queue = new ReferenceQueue();
/* Remove all invalidated entries from the map, that is, remove all entries
whose keys have been discarded. This method should be invoked once by
each public mutator in this class. We don't invoke this method in
public accessors because that can lead to surprising
ConcurrentModificationExceptions. */
@SuppressWarnings("unchecked")
private void processQueue() {
WeakKey wk;
while ((wk = (WeakKey)queue.poll()) != null) { // unchecked cast
hash.remove(wk);
}
}
/* -- Constructors -- */
/**
* Constructs a new, empty WeakHashMap
with the given
* initial capacity and the given load factor.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @param loadFactor the load factor of the WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero, or if the load factor is
* nonpositive
*/
public WeakHasherMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}
/**
* Constructs a new, empty WeakHashMap
with the given
* initial capacity and the default load factor, which is
* 0.75
.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero
*/
public WeakHasherMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
}
/**
* Constructs a new, empty WeakHashMap
with the default
* capacity and the default load factor, which is 0.75
.
*/
public WeakHasherMap() {
hash = new HashMap();
}
/**
* Constructs a new, empty WeakHashMap
with the default
* capacity and the default load factor, which is 0.75
.
* The WeakHashMap
uses the specified hasher for hashing
* keys and comparing them for equality.
* @param h the Hasher to use when hashing values for this map
*/
public WeakHasherMap(Hasher h) {
hash = new HashMap();
hasher = h;
}
/* -- Simple queries -- */
/**
* Returns the number of key-value mappings in this map.
* Note: In contrast to most implementations of the
* Map
interface, the time required by this operation is
* linear in the size of the map.
*/
/*@Pure*/
@Override
public int size() {
return entrySet().size();
}
/**
* Returns true
if this map contains no key-value mappings.
*/
/*@Pure*/
@Override
public boolean isEmpty() {
return entrySet().isEmpty();
}
/**
* Returns true
if this map contains a mapping for the
* specified key.
*
* @param key the key whose presence in this map is to be tested
*/
/*@Pure*/
@Override
public boolean containsKey(Object key) {
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.containsKey(WeakKeyCreate(kkey));
}
/* -- Lookup and modification operations -- */
/**
* Returns the value to which this map maps the specified key
.
* If this map does not contain a value for this key, then return
* null
.
*
* @param key the key whose associated value, if any, is to be returned
*/
/*@Pure*/
@Override
public /*@Nullable*/ V get(Object key) { // type of argument is Object, not K
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.get(WeakKeyCreate(kkey));
}
/**
* Updates this map so that the given key
maps to the given
* value
. If the map previously contained a mapping for
* key
then that mapping is replaced and the previous value is
* returned.
*
* @param key the key that is to be mapped to the given
* value
* @param value the value to which the given key
is to be
* mapped
*
* @return the previous value to which this key was mapped, or
* null
if if there was no mapping for the key
*/
@Override
public V put(K key, V value) {
processQueue();
return hash.put(WeakKeyCreate(key, queue), value);
}
/**
* Removes the mapping for the given key
from this map, if
* present.
*
* @param key the key whose mapping is to be removed
*
* @return the value to which this key was mapped, or null
if
* there was no mapping for the key
*/
@Override
public V remove(Object key) { // type of argument is Object, not K
processQueue();
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.remove(WeakKeyCreate(kkey));
}
/**
* Removes all mappings from this map.
*/
@Override
public void clear() {
processQueue();
hash.clear();
}
/* -- Views -- */
/* Internal class for entries */
// This can't be static, again because of dependence on hasher.
@SuppressWarnings("TypeParameterShadowing")
private final class Entry implements Map.Entry {
private Map.Entry ent;
private K key; /* Strong reference to key, so that the GC
will leave it alone as long as this Entry
exists */
Entry(Map.Entry ent, K key) {
this.ent = ent;
this.key = key;
}
/*@Pure*/
@Override
public K getKey() {
return key;
}
/*@Pure*/
@Override
public V getValue() {
return ent.getValue();
}
@Override
public V setValue(V value) {
return ent.setValue(value);
}
/*@Pure*/
private boolean keyvalEquals(K o1, K o2) {
return (o1 == null) ? (o2 == null) : keyEquals(o1, o2);
}
/*@Pure*/
private boolean valEquals(V o1, V o2) {
return (o1 == null) ? (o2 == null) : o1.equals(o2);
}
/*@Pure*/
@SuppressWarnings("NonOverridingEquals")
public boolean equals(Map.Entry e /* Object o*/) {
// if (! (o instanceof Map.Entry)) return false;
// Map.Entry e = (Map.Entry)o;
return (keyvalEquals(key, e.getKey())
&& valEquals(getValue(), e.getValue()));
}
/*@Pure*/
@Override
public int hashCode() {
V v;
return (((key == null) ? 0 : keyHashCode(key))
^ (((v = getValue()) == null) ? 0 : v.hashCode()));
}
}
/* Internal class for entry sets */
private final class EntrySet extends AbstractSet> {
Set> hashEntrySet = hash.entrySet();
@Override
public Iterator> iterator() {
return new Iterator>() {
Iterator> hashIterator = hashEntrySet.iterator();
Map.Entry next = null;
@Override
public boolean hasNext() {
while (hashIterator.hasNext()) {
Map.Entry ent = hashIterator.next();
WeakKey wk = ent.getKey();
K k = null;
if ((wk != null) && ((k = wk.get()) == null)) {
/* Weak key has been cleared by GC */
continue;
}
next = new Entry(ent, k);
return true;
}
return false;
}
@Override
public Map.Entry next() {
if ((next == null) && !hasNext())
throw new NoSuchElementException();
Map.Entry e = next;
next = null;
return e;
}
@Override
public void remove() {
hashIterator.remove();
}
};
}
/*@Pure*/
@Override
public boolean isEmpty() {
return !(iterator().hasNext());
}
/*@Pure*/
@Override
public int size() {
int j = 0;
for (Iterator> i = iterator(); i.hasNext(); i.next()) j++;
return j;
}
@Override
public boolean remove(Object o) {
processQueue();
if (!(o instanceof Map.Entry,?>)) return false;
@SuppressWarnings("unchecked")
Map.Entry e = (Map.Entry)o; // unchecked cast
Object ev = e.getValue();
WeakKey wk = WeakKeyCreate(e.getKey());
Object hv = hash.get(wk);
if ((hv == null)
? ((ev == null) && hash.containsKey(wk)) : hv.equals(ev)) {
hash.remove(wk);
return true;
}
return false;
}
/*@Pure*/
@Override
public int hashCode() {
int h = 0;
for (Iterator> i = hashEntrySet.iterator(); i.hasNext(); ) {
Map.Entry ent = i.next();
WeakKey wk = ent.getKey();
Object v;
if (wk == null) continue;
h += (wk.hashCode()
^ (((v = ent.getValue()) == null) ? 0 : v.hashCode()));
}
return h;
}
}
private /*@Nullable*/ Set> entrySet = null;
/**
* Returns a Set
view of the mappings in this map.
*/
/*@SideEffectFree*/
@Override
public Set> entrySet() {
if (entrySet == null) entrySet = new EntrySet();
return entrySet;
}
// find matching key
K findKey(Object key) {
processQueue();
K kkey = (K) key;
// TODO: use replacement for HashMap to avoid reflection
WeakKey wkey = WeakKeyCreate(kkey);
WeakKey found = hashMap_findKey(hash, wkey);
return found == null ? null : found.get();
}
}
static class Pair implements Comparable> {
final public Pair setA(A a){ return a(a); }
public Pair a(A a) { this.a = a; return this; } final public A getA(){ return a(); }
public A a() { return a; }
A a;
final public Pair setB(B b){ return b(b); }
public Pair b(B b) { this.b = b; return this; } final public B getB(){ return b(); }
public B b() { return b; }
B b;
Pair() {}
Pair(A a, B b) {
this.b = b;
this.a = a;}
public int hashCode() {
return hashCodeFor(a) + 2*hashCodeFor(b);
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Pair)) return false;
Pair t = (Pair) o;
return eq(a, t.a) && eq(b, t.b);
}
public String toString() {
return "<" + a + ", " + b + ">";
}
public int compareTo(Pair p) {
if (p == null) return 1;
int i = ((Comparable ) a).compareTo(p.a);
if (i != 0) return i;
return ((Comparable) b).compareTo(p.b);
}
}
static class Fail extends RuntimeException implements IFieldsToList{
Object[] objects;
Fail() {}
Fail(Object... objects) {
this.objects = objects;}public Object[] _fieldsToList() { return new Object[] {objects}; }
Fail(Throwable cause, Object... objects) {
super(cause);
this.objects = objects;
}
public String toString() { return joinNemptiesWithColon("Fail", getMessage()); }
public String getMessage() { return commaCombine(getCause(), objects); }
}
static class Rect implements WidthAndHeight , IFieldsToList{
static final String _fieldOrder = "x y w h";
int x;
int y;
int w;
int h;
Rect() {}
Rect(int x, int y, int w, int h) {
this.h = h;
this.w = w;
this.y = y;
this.x = x;}
public boolean equals(Object o) {
if (!(o instanceof Rect)) return false;
Rect __1 = (Rect) o;
return x == __1.x && y == __1.y && w == __1.w && h == __1.h;
}
public int hashCode() {
int h = 2543108;
h = boostHashCombine(h, _hashCode(x));
h = boostHashCombine(h, _hashCode(y));
h = boostHashCombine(h, _hashCode(w));
h = boostHashCombine(h, _hashCode(h));
return h;
}
public Object[] _fieldsToList() { return new Object[] {x, y, w, h}; }
Rect(Rectangle r) {
x = r.x;
y = r.y;
w = r.width;
h = r.height;
}
Rect(Pt p, int w, int h) {
this.h = h;
this.w = w; x = p.x; y = p.y; }
Rect(Rect r) { x = r.x; y = r.y; w = r.w; h = r.h; }
final Rectangle getRectangle() {
return new Rectangle(x, y, w, h);
}
public String toString() {
return x + "," + y + " / " + w + "," + h;
}
final int x1() { return x; }
final int y1() { return y; }
final int x2() { return x + w; }
final int y2() { return y + h; }
final boolean contains(Pt p) {
return contains(p.x, p.y);
}
final boolean contains(int _x, int _y) {
return _x >= x && _y >= y && _x < x+w && _y < y+h;
}
final boolean contains(Rectangle r) {
return rectContains(this, r);
}
final boolean empty() { return w <= 0 || h <= 0; }
final public int getWidth() { return w; }
final public int getHeight() { return h; }
final public int area() { return w*h; }
WidthAndHeight widthAndHeight() { return main.widthAndHeight(w, h); }
}
static class Pt implements Comparable, IDoublePt {
int x, y;
Pt() {}
Pt(Point p) {
x = p.x;
y = p.y;
}
Pt(int x, int y) {
this.y = y;
this.x = x;}
Point getPoint() {
return new Point(x, y);
}
public boolean equals(Object o) {
return o instanceof Pt && x == ((Pt) o).x && y == ((Pt) o).y;
}
public int hashCode() {
return boostHashCombine(x, y);
}
// compare in scan order
public int compareTo(Pt p) {
if (y != p.y) return cmp(y, p.y);
return cmp(x, p.x);
}
public String toString() {
return x + ", " + y;
}
double length() { return sqrt(x*x+y*y); }
public Pt minus(Pt p) { return ptMinus(this, p); }
public double x_double() { return x; }
public double y_double() { return y; }
}
static class HuffmanTree implements BitIO {
final public HuffmanTree setRoot(Node root){ return root(root); }
public HuffmanTree root(Node root) { this.root = root; return this; } final public Node getRoot(){ return root(); }
public Node root() { return root; }
Node root;
Leaf[] characterMap = new Leaf[256];
final public HuffmanTree setDebug(boolean debug){ return debug(debug); }
public HuffmanTree debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug(){ return debug(); }
public boolean debug() { return debug; }
boolean debug = false;
/*
algebraic Node {
constructor Branch {
settable Node zero;
settable Node one;
}
constructor Leaf {
settable byte literal;
}
}
*/
abstract class Node implements BitIO {
final public Node setParent(Branch parent){ return parent(parent); }
public Node parent(Branch parent) { this.parent = parent; return this; } final public Branch getParent(){ return parent(); }
public Branch parent() { return parent; }
Branch parent;
void buildSymbol(BitBuffer head, Node child) {
{ if (parent != null) parent.buildSymbol(head, this); }
}
abstract Leaf readSymbol(BitHead head);
}
class Branch extends Node {
final public Node getZero(){ return zero(); }
public Node zero() { return zero; }
Node zero;
final public Node getOne(){ return one(); }
public Node one() { return one; }
Node one;
Branch zero(Node zero) {
this.zero = zero;
zero.parent = this;
return this;
}
Branch one(Node one) {
this.one = one;
one.parent = this;
return this;
}
public void readWrite(BitHead head) {
head.exchangeBit(1);
head.exchange(zero, () -> zero(readNode(head)));
head.exchange(one, () -> one(readNode(head)));
}
void buildSymbol(BitBuffer head, Node child) {
head.add(child == one);
super.buildSymbol(head, child);
}
Leaf readSymbol(BitHead head) {
boolean bit = head.readBit();
if (debug) print("Read bit " + bit);
return (bit ? one : zero).readSymbol(head);
}
}
class Leaf extends Node {
final public byte getLiteral(){ return literal(); }
public byte literal() { return literal; }
byte literal;
Leaf() {}
Leaf(int literal) { literal((byte) literal); }
byte get() { return literal; }
Leaf literal(byte b) {
literal = b;
fillCharacterMap();
return this;
}
public void readWrite(BitHead head) {
head.exchangeBit(0);
head.exchangeByte(literal, __3 -> literal(__3));
if (debug) print(this);
}
void fillCharacterMap() {
characterMap[ubyteToInt(literal)] = this;
}
Leaf readSymbol(BitHead head) {
if (debug) print("Reached symbol " + this);
return this;
}
public String toString() {
return "Literal " + byteToHex(literal);
}
}
void makeRootIfEmpty() {
if (root == null) root = new Leaf(0);
}
Node readNode(BitHead head) {
boolean type = head.peekBit();
Node node = type ? new Branch() : new Leaf();
if (debug) print(type ? "Branch" : "Leaf");
node.readWrite(head);
return node;
}
public void readWrite(BitHead head) {
if (head.writeMode()) {
makeRootIfEmpty();
root.readWrite(head);
}
if (head.readMode())
root = readNode(head);
}
public String toString() {
makeRootIfEmpty();
List out = new ArrayList();
StringBuilder symbol = new StringBuilder();
final class _C_1 { void toString_collect(Node node) {
if (node instanceof Leaf) {
out.add(symbol + ": " + /*ubyteToHex*/quote(codePoint(ubyteToInt(((Leaf) node).get()))));
} else {
symbol.append("0");
toString_collect(((Branch) node).zero());
removeLast(symbol);
symbol.append("1");
toString_collect(((Branch) node).one());
removeLast(symbol);
}
} } final _C_1 __2 = new _C_1();
__2.toString_collect(root);
return lines(out);
}
final void writeSymbol(int sym, BitHead head){ writeCharacter(sym, head); }
void writeCharacter(int sym, BitHead head) {
sym &= 0xFF;
Leaf node = characterMap[sym];
if (node == null)
throw fail("Symbol cannot be encoded: " + sym);
BitBuffer buffer = new BitBuffer();
node.buildSymbol(buffer, null);
// when there is only one symbol
if (buffer.isEmpty())
buffer.add(0);
for (int i = l(buffer)-1; i >= 0; i--)
head.writeBit(buffer.get(i));
}
int readSymbol(BitHead head) {
if (head.isEOF()) return -1;
if (root instanceof Leaf)
head.advanceBit(); // don't even care
return ubyteToInt(root.readSymbol(head).get());
}
}
static abstract class F0 {
abstract A get();
}
static abstract class F1 {
abstract B get(A a);
}
// you still need to implement hasNext() and next()
static abstract class IterableIterator implements Iterator , Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
public static interface IF0 {
A get();
}
static interface Hasher {
int hashCode(A a);
boolean equals(A a, A b);
}
static interface IF1 {
B get(A a);
}
static class PersistableThrowable extends DynamicObject {
String className;
String msg;
String stacktrace;
PersistableThrowable() {}
PersistableThrowable(Throwable e) {
if (e == null)
className = "Crazy Null Error";
else {
className = getClassName(e).replace('/', '.');
msg = e.getMessage();
stacktrace = getStackTrace_noRecord(e);
}
}
public String toString() {
return nempty(msg) ? className + ": " + msg : className;
}
RuntimeException asRuntimeException() {
return new Fail(this);
}
}
static class Frequency implements Comparable , IFieldsToList{
double frequency;
Frequency() {}
public boolean equals(Object o) {
if (!(o instanceof Frequency)) return false;
Frequency __1 = (Frequency) o;
return frequency == __1.frequency;
}
public int hashCode() {
int h = 1933944124;
h = boostHashCombine(h, _hashCode(frequency));
return h;
}
public Object[] _fieldsToList() { return new Object[] {frequency}; }
final public double getInterval(){ return interval(); }
public double interval() { return interval; }
double interval;
final double get(){ return frequency(); }
double frequency() { return frequency; }
// !customConstructor
Frequency(double frequency) {
this.frequency = frequency; interval = doubleRatio(1, frequency); }
public String toString() { return format3(); }
String format3() { return format(3); }
String format1() { return format(1); }
String format(int digits) { return str(new Rendering(digits)); }
class Rendering implements IFieldsToList{
int digits;
Rendering() {}
Rendering(int digits) {
this.digits = digits;}public Object[] _fieldsToList() { return new Object[] {digits}; }
double value = frequency;
String unit = "Hz";
transient IF0 formatValue;
String formatValue() { return formatValue != null ? formatValue.get() : formatValue_base(); }
final String formatValue_fallback(IF0 _f) { return _f != null ? _f.get() : formatValue_base(); }
String formatValue_base() { return formatDouble(value, digits); }
public void run() { try {
while (abs(value) >= 1000) {
value /= 1000;
unit = "k" + unit;
}
unit = replacePrefixes(unit,
"kkkk", "T",
"kkk", "G",
"kk", "M");
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { run(); return spaceCombine(formatValue(), unit); }
}
public int compareTo(Frequency f) {
return cmp(frequency, f.frequency);
}
}
static interface IVF1 {
void get(A a);
}
interface BitIO {
void readWrite(BitHead head);
default byte[] saveAsByteArray(){ return saveToByteArray(); }
default byte[] toByteArray(){ return saveToByteArray(); }
default byte[] saveToByteArray() { return saveToByteArray(new BitHead()); }
default byte[] saveAsByteArray(BitHead head){ return saveToByteArray(head); }
default byte[] toByteArray(BitHead head){ return saveToByteArray(head); }
default byte[] saveToByteArray(BitHead head) {
var baos = byteArrayOutputStream();
head.outputStream(baos);
readWrite(head);
head.finish();
return baos.toByteArray();
}
default String toHexString() {
return main.toHexString(toByteArray());
}
default File saveToFile(File file) {
OutputStream out = bufferedFileOutputStream(file); try {
var head = new BitHead(out);
readWrite(head);
head.finish();
return file;
} finally { _close(out); }}
default BitIO fromByteArray(byte[] data){ return load(data); }
default BitIO load(byte[] data) {
readWrite(new BitHead(new ByteArrayInputStream(data)));
return this;
}
default BitIO load(File file) {
InputStream in = bufferedInputStream(file); try {
readWrite(new BitHead(in));
return this;
} finally { _close(in); }}
}
static class BitHead extends ByteHead {
final public int getAlign(){ return align(); }
public int align() { return align; }
int align = 8;
final public int getCurrentByte(){ return currentByte(); }
public int currentByte() { return currentByte; }
int currentByte;
final public BitHead setDebug(boolean debug){ return debug(debug); }
public BitHead debug(boolean debug) { this.debug = debug; return this; } final public boolean getDebug(){ return debug(); }
public boolean debug() { return debug; }
boolean debug = false;
BitHead() {}
BitHead(InputStream inputStream) { super(inputStream); }
BitHead(OutputStream outputStream) { super(outputStream); }
boolean writeArraysSlowly() { return false; }
// choose fast or slow version depending on alignment
void write(byte[] data) {
if (align == 0 && !writeArraysSlowly())
super.write(data);
else
for (var b : data) write(b);
}
void writeByte(int i) {
i &= 0xFF;
if (debug) print("writeByte: align=" + align + ", byteCounter=" + byteCounter + ", value=" + i);
if (align == 0)
super.writeByte(i);
else {
currentByte |= i << align;
super.writeByte(currentByte);
currentByte = i >> (8-align);
}
}
void writePartialByte(int i, int bits) {
for (int bit = 0; bit < bits; bit++) {
writeBit(i);
i >>>= 1;
}
}
void writeBit(int i) {
writeBit((i & 1) != 0);
}
void writeBit(boolean b) {
align &= 7;
if (b) currentByte |= 1 << align;
if (align == 7) {
super.writeByte(currentByte);
currentByte = align = 0;
} else
++align;
}
int readPartialByte(int bits) {
int value = 0;
for (int bit = 0; bit < bits; bit++)
if (readBit()) value |= 1 << bit;
return isEOF() ? -1 : value;
}
int readByte() {
if (debug) print("readByte: align=" + align + ", byteCounter=" + byteCounter);
int value;
if (align == 0) {
value = currentByte;
align = 8;
} else if (align == 8)
value = super.readByte();
else {
value = currentByte >> align;
int align = this.align;
bufferNextByte();
if (isEOF()) return -1;
this.align = align;
value |= (currentByte << (8-align)) & 0xFF;
}
if (debug) print("value: " + value);
return value;
}
boolean readBit() {
boolean bitSet = peekBit();
advanceBit();
return bitSet;
}
boolean peekBit() {
if (currentByte < 0)
throw fail("eof");
if (align == 8)
bufferNextByte();
return (currentByte & (1 << align)) != 0;
}
void bufferNextByte() {
currentByte = super.readByte();
align = 0;
}
void advanceBit() {
if (currentByte < 0) return;
if (align == 8)
bufferNextByte();
++align;
}
boolean byteAligned() {
return (align & 7) == 0;
}
final void flushBits(){ completeByte(); }
final void finishByte(){ completeByte(); }
final void finish(){ completeByte(); }
void completeByte() { completeByte(false); }
final void flushBits(boolean padWithOnes){ completeByte(padWithOnes); }
final void finishByte(boolean padWithOnes){ completeByte(padWithOnes); }
final void finish(boolean padWithOnes){ completeByte(padWithOnes); }
void completeByte(boolean padWithOnes) {
if (debug) print("Finishing byte " + byteCounter + " (align " + align + ")");
if (byteAligned()) return;
if (writeMode()) {
if (padWithOnes) currentByte |= 0xFF << align;
super.writeByte(currentByte);
}
currentByte = 0;
align = readMode() ? 8 : 0;
}
// TODO: switch to more compact version saving 5 bits on average
final void trailingBitCount(){ writeTrailingBitCount(); }
void writeTrailingBitCount() { writeTrailingBitCount(false); }
final void trailingBitCount(boolean padWithOnes){ writeTrailingBitCount(padWithOnes); }
void writeTrailingBitCount(boolean padWithOnes) {
if (!writeMode()) return;
int bitCount = modRange_incl(align(), 1, 8);
completeByte(padWithOnes);
writeByte(bitCount);
}
void exchange(BitIO writable) {
if (writable != null) writable.readWrite(this);
}
void exchangeBit(IF0 getter, IVF1 setter) {
if (writeMode())
writeBit(getter.get());
if (readMode())
setter.get(readBit());
}
void exchangeBit(int i) { exchangeBit(odd(i)); }
void exchangeBit(boolean i) {
exchangeBit(() -> i, j -> assertEquals(i, j));
}
void exchange(BitIO getter, Runnable setter) {
if (writeMode())
getter.readWrite(this);
if (readMode())
setter.run();
}
boolean isEOF() { return currentByte < 0; }
}
static class PingSourceCancelledException extends RuntimeException implements IFieldsToList{
PingSource pingSource;
PingSourceCancelledException() {}
PingSourceCancelledException(PingSource pingSource) {
this.pingSource = pingSource;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + pingSource + ")"; }public Object[] _fieldsToList() { return new Object[] {pingSource}; }
}
static interface IFieldsToList {
Object[] _fieldsToList();
}
static interface ISleeper_v2 {
Sleeping doLater(Timestamp targetTime, Runnable r);
public default Sleeping doAfter(double seconds, Runnable r) {
return doLater(tsNow().plusSeconds(seconds), r);
}
}
static class MinimalChain implements Iterable {
A element;
MinimalChain next;
MinimalChain() {}
MinimalChain(A element) {
this.element = element;}
MinimalChain(A element, MinimalChain next) {
this.next = next;
this.element = element;}
public String toString() { return str(toList()); }
ArrayList toList() {
ArrayList l = new ArrayList();
MinimalChain c = this;
while (c != null) {
l.add(c.element);
c = c.next;
}
return l;
}
void setElement(A a) { element = a; }
void setNext(MinimalChain next) { this.next = next; }
// TODO: optimize
public Iterator iterator() { return toList().iterator(); }
A get() { return element; }
}
// The idea is to leave max as the actual number of cores the system
// has (numberOfCores()), and in case of being fully booked, raise an
// alert (customerMustWaitAlert) which can be handled by a strategy
// object (different reactions are possible).
// If nothing is done in such an event, clients are processed serially
// (no guarantees of order), split up among the available threads.
/* SYNChronisation order:
1. PooledThread
2. ThreadPool */
static class ThreadPool implements AutoCloseable {
int max = numberOfCores();
List all = new ArrayList();
Set used = new HashSet();
Set free = new HashSet();
boolean verbose, retired;
// our own ping surce so we can start threads & keep them running
class InternalPingSource extends PingSource {}
InternalPingSource internalPingSource = new InternalPingSource();
MultiSleeper sleeper = new MultiSleeper();
ThreadPool() {}
ThreadPool(int max) {
this.max = max;}
synchronized int maxSize() { return max; }
synchronized int total() { return l(used)+l(free); }
transient Set onCustomerMustWaitAlert;
public ThreadPool onCustomerMustWaitAlert(Runnable r) { onCustomerMustWaitAlert = createOrAddToSyncLinkedHashSet(onCustomerMustWaitAlert, r); return this; }
public ThreadPool removeCustomerMustWaitAlertListener(Runnable r) { main.remove(onCustomerMustWaitAlert, r); return this; }
public void customerMustWaitAlert() { if (onCustomerMustWaitAlert != null) for (var listener : onCustomerMustWaitAlert) pcallF_typed(listener); }
void fireCustomerMustWaitAlert() {
vmBus_send("customerMustWaitAlert", this, currentThread());
customerMustWaitAlert();
}
// DOESN'T WAIT. adds action to a thread's queue if nothing is
// available immediately.
PooledThread acquireThreadOrQueue(Runnable action) {
if (action == null) return null;
PooledThread t;
synchronized(this) {
if (_hasFreeAfterCreating()) {
t = _firstFreeThread();
markUsed(t);
} else
t = _anyThread();
}
t.addWork(action); // will move it from free to used
return t;
}
// run in synchronized block
boolean _hasFreeAfterCreating() {
checkNotRetired();
if (nempty(free)) return true;
if (total() < max) {
PooledThread t = newThread();
all.add(t);
free.add(t);
return true;
}
return false;
}
// WAITS until thread is available
PooledThread acquireThreadOrWait(Runnable action) { try {
if (action == null) return null;
PooledThread t;
while (true) {
synchronized(this) {
if (_hasFreeAfterCreating()) {
t = _firstFreeThread();
break;
} else
_waitWaitWait();
}
}
t.addWork(action);
return t;
} catch (Exception __e) { throw rethrow(__e); } }
PooledThread _firstFreeThread() {
return first(free);
}
PooledThread _anyThread() {
return random(used);
}
class PooledThread extends Thread {
PooledThread(String name) { super(name); }
AppendableChain q;
synchronized Runnable _grabWorkOrSleep() { try {
Runnable r = first(q);
if (r == null) {
markFree(this);
if (verbose) print("Thread sleeps");
synchronized(this) { wait(); }
if (verbose) print("Thread woke up");
return null;
}
q = popFirst(q);
return r;
} catch (Exception __e) { throw rethrow(__e); } }
public void run() { try {
pingSource_tl().set(internalPingSource);
while (!retired()) { ping();
Runnable r = _grabWorkOrSleep();
if (verbose) print(this + " work: " + r);
if (r != null)
try {
if (verbose) print(this + " running: " + r);
r.run();
pingSource_tl().set(internalPingSource);
if (verbose) print(this + " done");
} catch (Throwable e) {
pingSource_tl().set(internalPingSource);
if (verbose) print(this + " error");
printStackTrace(e);
} finally {
pingSource_tl().set(internalPingSource);
if (verbose) print("ThreadPool finally");
}
}
} catch (Exception __e) { throw rethrow(__e); } }
synchronized boolean isEmpty() { return empty(q); }
// append to q (do later)
void addWork(Runnable r) {
if (verbose) print("Added work to " + this + ": " + r);
synchronized(this) {
q = chainPlus(q, r);
notifyAll();
}
}
}
PooledThread newThread() {
PooledThread t = new PooledThread("Thread Pool Inhabitant " + n2(total()+1));
t.start();
return t;
}
synchronized void markFree(PooledThread t) {
used.remove(t);
free.add(t);
notifyAll();
}
synchronized void markUsed(PooledThread t) {
free.remove(t);
used.add(t);
}
synchronized public String toString() {
return retired()
? "Retired ThreadPool"
: "ThreadPool " + roundBracket(commaCombine(
n2(used) + " used out of " + n2(total()),
max <= total() ? null : "could grow to " + n2(max)));
}
synchronized boolean retired() { return retired; }
synchronized void retire() {
if (verbose) print("ThreadPool Retiring");
retired = true;
for (var thread : free) syncNotifyAll(thread); // wake it up so it exits
}
void checkNotRetired() {
if (retired()) throw fail("retired");
}
// We could do a soft-close here (stop the idle threads, let running threads finish, then end those too, stop accepting new orders)
// or a hard close (interrupt all threads, stop accepting new orders)
synchronized public void close() { try {
retire();
} catch (Exception __e) { throw rethrow(__e); } }
// run in synchronized block
void _waitWaitWait() { try {
do {
fireCustomerMustWaitAlert();
wait();
checkNotRetired();
} while (empty(free));
} catch (Exception __e) { throw rethrow(__e); } }
void dO(String text, Runnable r) {
if (r == null) return;
new PingSource(this, text).dO(r);
}
ISleeper_v2 sleeper() { return sleeper; }
}
static interface IAutoCloseableF0 extends IF0 , AutoCloseable {}
interface IMultiMap {
public Set keySet();
public Collection get(A a);
public int size();
public int keyCount();
}
interface IDoublePt {
public double x_double();
public double y_double();
}
static interface WidthAndHeight {
default int w(){ return getWidth(); }
default int width(){ return getWidth(); }
int getWidth();
default int h(){ return getHeight(); }
default int height(){ return getHeight(); }
int getHeight();
public default Rect bounds() { return rect(0, 0, getWidth(), getHeight()); }
default int area() { return toInt(areaAsLong()); }
default long areaAsLong() { return longMul(w(), h()); }
}
// little-endian
static class BitBuffer implements IntSize {
ByteBuffer byteBuffer = new ByteBuffer(); // TODO (optimization): use a growing circular buffer
int currentByte, currentBit;
void add(int b) {
add(odd(b));
}
void add(boolean b) {
if (b) currentByte |= 1 << currentBit;
if (currentBit == 7) {
byteBuffer.add((byte) currentByte);
currentByte = 0;
currentBit = 0;
} else
++currentBit;
}
boolean get(int iBit) {
int iByte = iBit >> 3;
int theByte = iByte == byteBuffer.size()
? currentByte
: byteBuffer.get(iByte);
return (theByte & (1 << (iBit & 7))) != 0;
}
boolean hasFullByte() {
return !byteBuffer.isEmpty();
}
byte popFullByte() {
return byteBuffer.popFirst();
}
public int size() {
return byteBuffer.size()*8 + currentBit;
}
boolean isEmpty() { return size() == 0; }
// TODO: optimize void writeBits(int data, int nBits)
}
abstract static class Sleeping implements AutoCloseable , IFieldsToList{
Timestamp targetTime;
Runnable action;
Sleeping() {}
Sleeping(Timestamp targetTime, Runnable action) {
this.action = action;
this.targetTime = targetTime;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + targetTime + ", " + action + ")"; }public Object[] _fieldsToList() { return new Object[] {targetTime, action}; }
long remainingMS() { return targetTime.minus(tsNow()); }
}
interface IntSize {
int size();
}
static class MultiSleeper extends RestartableCountdown implements ISleeper_v2 {
TreeMultiMap entries = new TreeMultiMap();
void check() {
var time = nextWakeUpTime();
var action = firstValue(entries);
setTargetTime(time == null ? 0 : time.sysTime(), new Runnable() { public void run() { try {
List toCall;
synchronized(MultiSleeper.this) {
toCall = entries.get(time);
entries.remove(time);
}
check();
pcallFAll(toCall);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "List toCall;\r\n synchronized(MultiSleeper.this) {\r\n toCa..."; }});
}
synchronized void removeEntry(Timestamp targetTime, Runnable action) {
entries.remove(targetTime, action);
}
// API
synchronized Timestamp nextWakeUpTime() {
return firstKey(entries);
}
public synchronized Sleeping doLater(Timestamp targetTime, Runnable r) {
if (r == null || targetTime == null) return null;
targetTime = max(targetTime, tsNow());
entries.put(targetTime, r);
check();
return new Sleeping(targetTime, r) {
public void close() { try {
removeEntry(targetTime, r);
} catch (Exception __e) { throw rethrow(__e); } }
};
}
}
// We use big-endian as DataOutputStream does
// (TODO: decide on an endianness!)
static class ByteHead /*is DataOutput*/ {
final public ByteHead setReadMode(boolean readMode){ return readMode(readMode); }
public ByteHead readMode(boolean readMode) { this.readMode = readMode; return this; } final public boolean getReadMode(){ return readMode(); }
public boolean readMode() { return readMode; }
boolean readMode = false;
final public ByteHead setWriteMode(boolean writeMode){ return writeMode(writeMode); }
public ByteHead writeMode(boolean writeMode) { this.writeMode = writeMode; return this; } final public boolean getWriteMode(){ return writeMode(); }
public boolean writeMode() { return writeMode; }
boolean writeMode = false;
final public InputStream getInputStream(){ return inputStream(); }
public InputStream inputStream() { return inputStream; }
InputStream inputStream;
final public OutputStream getOutputStream(){ return outputStream(); }
public OutputStream outputStream() { return outputStream; }
OutputStream outputStream;
final public ByteHead setByteCounter(long byteCounter){ return byteCounter(byteCounter); }
public ByteHead byteCounter(long byteCounter) { this.byteCounter = byteCounter; return this; } final public long getByteCounter(){ return byteCounter(); }
public long byteCounter() { return byteCounter; }
long byteCounter;
ByteHead() {}
ByteHead(InputStream inputStream) { inputStream(inputStream); }
ByteHead(OutputStream outputStream) { outputStream(outputStream); }
ByteHead inputStream(InputStream inputStream) { this.inputStream = inputStream; readMode(true); return this; }
ByteHead outputStream(OutputStream outputStream) { this.outputStream = outputStream; writeMode(true); return this; }
void write(byte[] data) { try {
ensureWriteMode();
{ if (outputStream != null) outputStream.write(data); }
byteCounter += data.length;
} catch (Exception __e) { throw rethrow(__e); } }
void writeLong(long l) {
writeInt((int) (l >> 32));
writeInt((int) l);
}
void writeInt(int i) {
write(i >> 24);
write(i >> 16);
write(i >> 8);
write(i);
}
void writeShort(int i) {
write(i >> 8);
write(i);
}
final void write(int i){ writeByte(i); }
void writeByte(int i) { try {
ensureWriteMode();
{ if (outputStream != null) outputStream.write(i); }
byteCounter++;
} catch (Exception __e) { throw rethrow(__e); } }
void writeASCII(char c) {
write(toASCII(c));
}
void writeASCII(String s) {
write(toASCII(s));
}
void exchangeASCII(String s) {
exchangeConstantBytes(toASCII(s));
}
void exchangeConstantBytes(byte[] data) {
for (int i = 0; i < l(data); i++)
exchangeByte(data[i]);
}
long readLong() {
long i = readInt() << 32;
return i | (readInt() & 0xFFFFFFFFL);
}
int readInt() {
int i = read() << 24;
i |= read() << 16;
i |= read() << 8;
return i | read();
}
short readShort() {
int i = read() << 8;
return (short) (i | read());
}
// -1 for EOF
final int read(){ return readByte(); }
int readByte() { try {
ensureReadMode();
++byteCounter;
return inputStream.read();
} catch (Exception __e) { throw rethrow(__e); } }
void ensureReadMode() {
if (!readMode) throw fail("Not in read mode");
}
void ensureWriteMode() {
if (!writeMode) throw fail("Not in write mode");
}
// exchange = read or write depending on mode
void exchangeByte(byte getter, IVF1 setter) {
exchangeByte(() -> getter, setter);
}
void exchangeByte(IF0 getter, IVF1 setter) {
if (writeMode())
writeByte(getter.get());
if (readMode())
setter.get(toUByte(readByte()));
}
void exchangeShort(IF0 getter, IVF1 setter) {
if (writeMode())
writeShort(getter.get());
if (readMode())
setter.get(readShort());
}
void exchangeLong(IVar var) {
exchangeLong(var.getter(), var.setter());
}
void exchangeLong(IF0 getter, IVF1 setter) {
if (writeMode())
writeLong(getter.get());
if (readMode())
setter.get(readLong());
}
void exchangeByte(byte i) {
exchangeByte(() -> i, j -> assertEquals(i, j));
}
void exchangeInt(int i) {
exchangeInt(() -> i, j -> assertEquals(i, j));
}
void exchangeInt(IF0 getter, IVF1 setter) {
if (writeMode())
writeInt(getter.get());
if (readMode())
setter.get(readInt());
}
void exchange(ByteIO writable) {
if (writable != null) writable.readWrite(this);
}
void exchangeAll(Iterable extends ByteIO> writables) {
if (writables != null)
for (var writable : writables)
exchange(writable);
}
// write size in bytes of element first (as int),
// then the element itself.
// upon reading, size is actually ignored.
void exchangeWithSize(ByteIO writable) {
if (writeMode()) {
byte[] data = writable.saveToByteArray();
writeInt(l(data));
write(data);
}
if (readMode()) {
int n = readInt();
writable.readWrite(this);
}
}
void finish() {}
}
static class ByteBuffer implements Iterable {
byte[] data;
int size;
ByteBuffer() {}
ByteBuffer(int size) { if (size != 0) data = new byte[size]; }
ByteBuffer(Iterable l) {
if (l instanceof Collection) allocate(((Collection) l).size());
addAll(l);
}
ByteBuffer(byte[] data) { this.data = data; size = l(data); }
// TODO *(ByteBuffer buf) { ... }
void add(int idx, int i) {
add(0);
arraycopy(data, idx, data, idx+1, size-(idx+1));
data[idx] = (byte) i;
}
void add(int i) { add((byte) i); }
void add(byte i) {
if (size >= lByteArray(data)) {
allocate(Math.max(1, toInt(Math.min(maximumSafeArraySize(), lByteArray(data)*2L))));
if (size >= data.length) throw fail("ByteBuffer too large: " + size);
}
data[size++] = i;
}
void allocate(int n) {
data = resizeByteArray(data, max(n, size()));
}
void addAll(Iterable l) {
if (l != null) for (byte i : l) add(i);
}
final byte[] toByteArray(){ return toArray(); }
byte[] toArray() {
return size == 0 ? null : resizeByteArray(data, size);
}
List toList() {
return byteArrayToList(data, 0, size);
}
List asVirtualList() {
return new RandomAccessAbstractList() {
public int size() { return size; }
public Byte get(int i) { return ByteBuffer.this.get(i); }
public Byte set(int i, Byte val) {
Byte a = get(i);
data[i] = val;
return a;
}
};
}
void reset() { size = 0; }
void clear() { reset(); }
int size() { return size; }
boolean isEmpty() { return size == 0; }
byte get(int idx) {
if (idx >= size) throw fail("Index out of range: " + idx + "/" + size);
return data[idx];
}
void set(int idx, byte value) {
if (idx >= size) throw fail("Index out of range: " + idx + "/" + size);
data[idx] = value;
}
byte popLast() {
if (size == 0) throw fail("empty buffer");
return data[--size];
}
// unefficient
byte popFirst() {
if (size == 0) throw fail("empty buffer");
byte b = data[0];
arraycopy(data, 1, 0, --size);
return b;
}
byte last() { return data[size-1]; }
byte nextToLast() { return data[size-2]; }
public String toString() { return squareBracket(joinWithSpace(toList())); }
public Iterator iterator() {
return new IterableIterator() {
int i = 0;
public boolean hasNext() { return i < size; }
public Byte next() {
//if (!hasNext()) fail("Index out of bounds: " + i);
return data[i++];
}
};
}
/*public ByteIterator byteIterator() {
ret new ByteIterator {
int i = 0;
public bool hasNext() { ret i < size; }
public int next() {
//if (!hasNext()) fail("Index out of bounds: " + i);
ret data[i++];
}
toString { ret "Iterator@" + i + " over " + ByteBuffer.this; }
};
}*/
void trimToSize() {
data = resizeByteArray(data, size);
}
int indexOf(byte b) {
for (int i = 0; i < size; i++)
if (data[i] == b)
return i;
return -1;
}
byte[] subArray(int start, int end) {
return subByteArray(data, start, min(end, size));
}
}
static class Timestamp implements Comparable , IFieldsToList{
long date;
Timestamp(long date) {
this.date = date;}
public boolean equals(Object o) {
if (!(o instanceof Timestamp)) return false;
Timestamp __1 = (Timestamp) o;
return date == __1.date;
}
public int hashCode() {
int h = 2059094262;
h = boostHashCombine(h, _hashCode(date));
return h;
}
public Object[] _fieldsToList() { return new Object[] {date}; }
Timestamp() { date = now(); }
Timestamp(Date date) { if (date != null) this.date = date.getTime(); }
long unixDate() { return date; }
long unixSeconds() { return unixDate()/1000; }
public String toString() { return formatLocalDateWithSeconds(date); }
// Hmm. Should Timestamp(0) be equal to null? Question, questions...
public int compareTo(Timestamp t) {
return t == null ? 1 : cmp(date, t.date);
}
Timestamp plus(Seconds seconds) {
return plus(seconds == null ? null : seconds.getDouble());
}
final Timestamp plusSeconds(double seconds){ return plus(seconds); }
Timestamp plus(double seconds) {
return new Timestamp(date+toMS(seconds));
}
// returns milliseconds
long minus(Timestamp ts) {
return unixDate()-ts.unixDate();
}
long sysTime() {
return clockTimeToSystemTime(date);
}
Duration minusAsDuration(Timestamp ts) {
return Duration.ofMillis(minus(ts));
}
}
interface ByteIO {
void readWrite(ByteHead head);
default byte[] saveAsByteArray(){ return saveToByteArray(); }
default byte[] toByteArray(){ return saveToByteArray(); }
default byte[] saveToByteArray() { return saveToByteArray(new ByteHead()); }
default byte[] saveAsByteArray(ByteHead head){ return saveToByteArray(head); }
default byte[] toByteArray(ByteHead head){ return saveToByteArray(head); }
default byte[] saveToByteArray(ByteHead head) {
var baos = byteArrayOutputStream();
head.outputStream(baos);
readWrite(head);
head.finish();
return baos.toByteArray();
}
default String toHexString() {
return main.toHexString(toByteArray());
}
default File saveToFile(File file) {
OutputStream out = bufferedFileOutputStream(file); try {
var head = new ByteHead(out);
readWrite(head);
head.finish();
return file;
} finally { _close(out); }}
default ByteIO fromByteArray(byte[] data){ return load(data); }
default ByteIO load(byte[] data) {
readWrite(new ByteHead(new ByteArrayInputStream(data)));
return this;
}
default ByteIO load(File file) {
InputStream in = bufferedInputStream(file); try {
readWrite(new ByteHead(in));
return this;
} finally { _close(in); }}
}
static class RestartableCountdown implements AutoCloseable {
java.util.Timer timer;
long targetTime; // in sys time
long /*firings,*/ totalSleepTime; // stats
synchronized void setTargetTime(long targetTime, Runnable action) {
if (targetTime <= 0)
stop();
else if (targetTime != this.targetTime) {
start(targetTime-sysNow(), action);
this.targetTime = targetTime;
}
}
// stops the countdown and restarts it
synchronized void start(long delayMS, Object action) {
stop();
if (delayMS <= 0)
{ startThread(new Runnable() { public void run() { try { callF(action);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callF(action);"; }}); }
else {
totalSleepTime += delayMS;
timer = doLater_daemon(delayMS, action);
targetTime = sysNow()+delayMS;
}
}
void start(double delaySeconds, Object action) {
start(toMS(delaySeconds), action);
}
synchronized void stop() {
cancelTimer(timer);
timer = null;
targetTime = 0;
}
public void close() { stop(); }
}
static class Seconds implements Comparable , IFieldsToList{
double seconds;
Seconds() {}
Seconds(double seconds) {
this.seconds = seconds;}
public boolean equals(Object o) {
if (!(o instanceof Seconds)) return false;
Seconds __1 = (Seconds) o;
return seconds == __1.seconds;
}
public int hashCode() {
int h = -660217249;
h = boostHashCombine(h, _hashCode(seconds));
return h;
}
public Object[] _fieldsToList() { return new Object[] {seconds}; }
final double get(){ return seconds(); }
final double getDouble(){ return seconds(); }
double seconds() { return seconds; }
public String toString() { return formatDouble(seconds, 3) + " s"; }
public int compareTo(Seconds s) {
return cmp(seconds, s.seconds);
}
Seconds div(double x) { return new Seconds(get()/x); }
Seconds minus(Seconds x) { return new Seconds(get()-x.get()); }
}
abstract static class RandomAccessAbstractList extends AbstractList implements RandomAccess {
}
static class TreeMultiMap extends MultiMap {
TreeMultiMap() { super(true); }
TreeMultiMap(MultiMap map) { this(); putAll(map); }
}
static interface IVar extends IF0 {
void set(A a);
A get();
// reified type of value (if available)
default Class getType() { return null; }
default IF0 getter() { return () -> get(); }
default IVF1 setter() { return __1 -> set(__1); }
default boolean has() { return get() != null; }
default void clear() { set(null); }
}
static Class> getClass(String name) {
return _getClass(name);
}
static Class getClass(Object o) {
return _getClass(o);
}
static Class getClass(Object realm, String name) {
return _getClass(realm, name);
}
static boolean classIsExportedTo(Class c, java.lang.Module destModule) {
if (c == null || destModule == null) return false;
java.lang.Module srcModule = c.getModule();
String packageName = c.getPackageName();
return srcModule.isExported(packageName, destModule);
}
static boolean isAbstract(Class c) {
return (c.getModifiers() & Modifier.ABSTRACT) != 0;
}
static boolean isAbstract(Method m) {
return (m.getModifiers() & Modifier.ABSTRACT) != 0;
}
static boolean reflection_isForbiddenMethod(Method m) {
return m.getDeclaringClass() == Object.class
&& eqOneOf(m.getName(), "finalize", "clone", "registerNatives");
}
static Set allInterfacesImplementedBy(Object o) {
return allInterfacesImplementedBy(_getClass(o));
}
static Set allInterfacesImplementedBy(Class c) {
if (c == null) return null;
HashSet set = new HashSet();
allInterfacesImplementedBy_find(c, set);
return set;
}
static void allInterfacesImplementedBy_find(Class c, Set set) {
if (c.isInterface() && !set.add(c)) return;
do {
for (Class intf : c.getInterfaces())
allInterfacesImplementedBy_find(intf, set);
} while ((c = c.getSuperclass()) != null);
}
static Method findMethod(Object o, String method, Object... args) {
return findMethod_cached(o, method, args);
}
static boolean findMethod_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static Method findStaticMethod(Class c, String method, Object... args) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (!m.getName().equals(method))
continue;
if ((m.getModifiers() & Modifier.STATIC) == 0 || !findStaticMethod_checkArgs(m, args))
continue;
return m;
}
c = c.getSuperclass();
}
return null;
}
static boolean findStaticMethod_checkArgs(Method m, Object[] args) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length)
return false;
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i])))
return false;
return true;
}
static String unquote(String s) {
if (s == null) return null;
if (startsWith(s, '[')) {
int i = 1;
while (i < s.length() && s.charAt(i) == '=') ++i;
if (i < s.length() && s.charAt(i) == '[') {
String m = s.substring(1, i);
if (s.endsWith("]" + m + "]"))
return s.substring(i+1, s.length()-i-1);
}
}
return unquoteSingleOrDoubleQuotes(s);
}
static List quoteAll(String[] l) {
return quoteAll(asList(l));
}
static List quoteAll(Collection l) {
List x = new ArrayList();
for (String s : l)
x.add(quote(s));
return x;
}
static int _hashCode(Object a) {
return a == null ? 0 : a.hashCode();
}
static ArrayList toList(A[] a) { return asList(a); }
static ArrayList toList(int[] a) { return asList(a); }
static ArrayList toList(Set s) { return asList(s); }
static ArrayList toList(Iterable s) { return asList(s); }
static boolean arraysEqual(Object[] a, Object[] b) {
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++)
if (neq(a[i], b[i])) return false;
return true;
}
static Object metaGet(IMeta o, Object key) {
return metaMapGet(o, key);
}
static Object metaGet(Object o, Object key) {
return metaMapGet(o, key);
}
static Object metaGet(String key, IMeta o) {
return metaMapGet(o, key);
}
static Object metaGet(String key, Object o) {
return metaMapGet(o, key);
}
static Object metaMapGet(IMeta o, Object key) {
return o == null ? null : o.metaGet(key); // We now let the object itself do it (overridable!)
}
static Object metaMapGet(Object o, Object key) {
return metaMapGet(toIMeta(o), key);
}
static void metaPut(IMeta o, Object key, Object value) {
metaMapPut(o, key, value);
}
static void metaPut(Object o, Object key, Object value) {
metaMapPut(o, key, value);
}
static Map convertObjectMetaToMap(IMeta o) { return convertObjectMetaToMap(o, () -> makeObjectMetaMap()); }
static Map convertObjectMetaToMap(IMeta o, IF0 createEmptyMap) {
if (o == null) return null;
// The following shortcut depends on the assumption that a meta field never reverts
// to null when it was a map
Object meta = o._getMeta();
if (meta instanceof Map) return ((Map) meta);
// non-shortcut path (create meta)
var mutex = tempMetaMutex(o); try {
var actualMutex = mutex.get();
synchronized(actualMutex) {
meta = o._getMeta();
if (meta instanceof Map) return ((Map) meta);
Map map = createEmptyMap.get();
if (meta != null) map.put("previousMeta" , meta);
o._setMeta(map);
return map;
}
} finally { _close(mutex); }}
static void syncMapPutOrRemove(Map map, A key, B value) {
syncMapPut2(map, key, value);
}
static BetterThreadLocal pingSource_tl_var = new BetterThreadLocal() {
@Override
public PingSource initialValue() {
return ping_v3_pingSourceMaker().get();
}
};
static BetterThreadLocal pingSource_tl() {
return pingSource_tl_var;
}
static Map putAll(Map a, Map extends A,? extends B> b) {
if (a != null && b != null) a.putAll(b);
return a;
}
static MultiMap putAll(MultiMap a, Map extends A,? extends B> b) {
if (a != null) a.putAll((Map) b);
return a;
}
static Map putAll(Map a, Object... b) {
if (a != null)
litmap_impl(a, b);
return a;
}
static void remove(List l, int i) {
if (l != null && i >= 0 && i < l(l))
l.remove(i);
}
static void remove(Collection l, A a) {
if (l != null) l.remove(a);
}
static B remove(Map map, Object a) {
return map == null ? null : map.remove(a);
}
static void remove(BitSet bs, int i) {
bs.clear(i);
}
static A getAndClear(IVar v) {
A a = v.get();
v.set(null);
return a;
}
static Set keys(Map map) {
return map == null ? new HashSet() : map.keySet();
}
// convenience shortcut for keys_gen
static Set keys(Object map) {
return keys((Map) map);
}
static Set keys(IMultiMap mm) {
return mm.keySet();
}
static Set keySet(Map map) {
return map == null ? new HashSet() : map.keySet();
}
static Set keySet(Object map) {
return keys((Map) map);
}
static Set keySet(MultiMap mm) {
return mm.keySet();
}
static int keysSize(MultiMap mm) {
return lKeys(mm);
}
static A reverseGet(List l, int idx) {
if (l == null || idx < 0) return null;
int n = l(l);
return idx < n ? l.get(n-1-idx) : null;
}
static Map cloneMap(Map map) {
if (map == null) return new HashMap();
// assume mutex is equal to map
synchronized(map) {
return map instanceof TreeMap ? new TreeMap((TreeMap) map) // copies comparator
: map instanceof LinkedHashMap ? new LinkedHashMap(map)
: new HashMap(map);
}
}
static List cloneMap(Iterable l, IF1 f) {
List x = emptyList(l);
if (l != null) for (A o : cloneList(l))
x.add(f.get(o));
return x;
}
static Collection values(Map map) {
return map == null ? emptyList() : map.values();
}
// convenience shortcut for values_gen
static Collection values(Object map) {
return values((Map) map);
}
static Collection values(MultiMap mm) {
return mm == null ? emptyList() : concatLists(values(mm.data));
}
static > List allValues(Map map) {
List out = new ArrayList();
for (var l : values(map))
addAll(out, l);
return out;
}
static List concatLists(Iterable ... lists) {
List l = new ArrayList();
if (lists != null) for (Iterable list : lists)
addAll(l, list);
return l;
}
static List concatLists(Collection extends Iterable > lists) {
List l = new ArrayList();
if (lists != null) for (Iterable list : lists)
addAll(l, list);
return l;
}
static Method hashMap_findKey_method;
static A hashMap_findKey(HashMap map, Object key) { try {
if (hashMap_findKey_method == null)
hashMap_findKey_method = findMethodNamed(HashMap.class, "getNode");
Map.Entry entry = (Map.Entry) hashMap_findKey_method.invoke(map, hashMap_internalHash(key), key);
// java.util.Map.Entry entry = (java.util.Map.Entry) call(hash, 'getNode, hashMap_internalHash(key), wkey);
return entry == null ? null : entry.getKey();
} catch (Exception __e) { throw rethrow(__e); } }
static String a(String noun) {
if (eq(noun, "")) return "?";
return ("aeiou".indexOf(noun.charAt(0)) >= 0 ? "an " : "a ") + noun;
}
static String a(String contents, Object... params) {
return hfulltag("a", contents, params);
}
static String b(Object contents, Object... params) {
return tag("b", contents, params);
}
static int hashCodeFor(Object a) {
return a == null ? 0 : a.hashCode();
}
static String joinNemptiesWithColon(String... strings) {
return joinNempties(": ", strings);
}
static String joinNemptiesWithColon(Collection strings) {
return joinNempties(": ", strings);
}
static String commaCombine(Object... l) {
return joinNemptiesWithComma(flattenCollectionsAndArrays(ll(l)));
}
static int boostHashCombine(int a, int b) {
return a ^ (b + 0x9e3779b9 + (a << 6) + (a >>> 2));
// OLD (changed) 2022/3/10: ret a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
}
static WidthAndHeight widthAndHeight(BufferedImage image) {
return image == null ? null : widthAndHeight(image.getWidth(), image.getHeight());
}
static WidthAndHeightImpl widthAndHeight(int w, int h) {
return new WidthAndHeightImpl(w, h);
}
static double sqrt(double x) {
return Math.sqrt(x);
}
static Pt ptMinus(Pt a, Pt b) {
if (b == null) return a;
return new Pt(a.x-b.x, a.y-b.y);
}
static Container getParent(final Component c) {
return c == null ? null : swing(new F0() { public Container get() { try { return c.getParent(); } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "return c.getParent();"; }});
}
static int ubyteToInt(byte b) {
return b & 0x0FF;
}
static int ubyteToInt(char c) {
return c & 0x0FF;
}
static String byteToHex(int b) {
return ubyteToHex(b);
}
static String codePoint(int codePoint) {
return codePointToString(codePoint);
}
static void removeLast(List l) {
if (!l.isEmpty())
l.remove(l(l)-1);
}
static void removeLast(List l, int n) {
removeSubList(l, l(l)-n);
}
static void removeLast(int n, List l) {
removeLast(l, n);
}
static void removeLast(StringBuilder buf) {
if (buf == null) return;
int n = buf.length();
if (n > 0) buf.setLength(n-1);
}
static String lines(Iterable lines) { return fromLines(lines); }
static String lines(Object[] lines) { return fromLines(asList(lines)); }
static List lines(String s) { return toLines(s); }
// convenience map call
static String lines(Iterable l, IF1 f) {
return mapToLines(l, f);
}
static UnsupportedOperationException unsupportedOperation() {
throw new UnsupportedOperationException();
}
static double doubleRatio(double x, double y) {
return y == 0 ? 0 : x/y;
}
static double doubleRatio(Seconds x, Seconds y) {
return doubleRatio(x.get(), y.get());
}
static String format3(String pat, Object... args) {
if (args.length == 0) return pat;
List tok = javaTokPlusPeriod(pat);
int argidx = 0;
for (int i = 1; i < tok.size(); i += 2)
if (tok.get(i).equals("*"))
tok.set(i, format3_formatArg(argidx < args.length ? args[argidx++] : "null"));
return join(tok);
}
static String format3_formatArg(Object arg) {
if (arg == null) return "null";
if (arg instanceof String) {
String s = (String) arg;
return isIdentifier(s) || isNonNegativeInteger(s) ? s : quote(s);
}
if (arg instanceof Integer || arg instanceof Long) return String.valueOf(arg);
return quote(structure(arg));
}
static String format(String pat, Object... args) {
return format3(pat, args);
}
static String formatDouble(double d, int digits) {
String format = digits <= 0 ? "0" : "0." + rep(digits, '#');
return decimalFormatEnglish(format, d);
}
static String formatDouble(double d) {
return str(d);
}
static float abs(float f) { return Math.abs(f); }
static int abs(int i) { return Math.abs(i); }
static double abs(double d) { return Math.abs(d); }
static double abs(Complex c) { return c.abs(); }
static String replacePrefixes(String s, String... replacements) {
for (Pair p : listToPairs(replacements))
s = replacePrefix(p.a, p.b, s);
return s;
}
static String spaceCombine(Object... l) {
return joinNemptiesWithSpace(flattenCollections(ll(l)));
}
static ByteArrayOutputStream byteArrayOutputStream() {
return new ByteArrayOutputStream();
}
static String toHexString(byte[] a) {
return bytesToHex(a);
}
static String toHexString(List a) {
return bytesToHex(byteListToArray(a));
}
static byte[] toByteArray(ByteArrayOutputStream baos) {
return baos == null ? null : baos.toByteArray();
}
static byte[] toByteArray(Iterator extends Number> it) {
ByteBuffer buf = new ByteBuffer();
while (it.hasNext())
buf.add((byte) it.next().intValue());
return buf.toByteArray();
}
static byte[] toByteArray(Collection extends Number> it) {
int n = l(it), i = 0;
byte[] a = new byte[n];
for (var x : it)
a[i++] = (byte) x.intValue();
return a;
}
static byte[] toByteArray(Object o) {
if (o == null) return null;
if (o instanceof byte[]) return ((byte[]) o);
if (o instanceof Iterator)
return toByteArray((Iterator) o);
if (o instanceof Collection)
return toByteArray((Collection) ((Collection) o));
// not sure what else to put here
throw fail("toByteArray", o);
}
static BufferedOutputStream bufferedFileOutputStream(File f) { try {
return bufferedOutputStream(newFileOutputStream(f));
} catch (Exception __e) { throw rethrow(__e); } }
static void _close(AutoCloseable c) {
if (c != null) try {
c.close();
} catch (Throwable e) {
// Some classes stupidly throw an exception on double-closing
if (c instanceof javax.imageio.stream.ImageOutputStream)
return;
else throw rethrow(e);
}
}
static Object load(String varName) {
readLocally(varName);
return get(mc(), varName);
}
static Object load(String progID, String varName) {
readLocally(progID, varName);
return get(mc(), varName);
}
static int bufferedInputStream_bufferSize = 65536;
static BufferedInputStream bufferedInputStream(int bufSize, File f) { try {
return bufferedInputStream(bufSize, newFileInputStream(f));
} catch (Exception __e) { throw rethrow(__e); } }
static BufferedInputStream bufferedInputStream(File f) { try {
return bufferedInputStream(newFileInputStream(f));
} catch (Exception __e) { throw rethrow(__e); } }
static BufferedInputStream bufferedInputStream(InputStream in) {
return new BufferedInputStream(in, bufferedInputStream_bufferSize);
}
static BufferedInputStream bufferedInputStream(int bufSize, InputStream in) {
return new BufferedInputStream(in, bufSize);
}
static int modRange_incl(int i, int start, int end) {
return start+mod(i-start, end-start+1);
}
static boolean odd(int i) {
return (i & 1) != 0;
}
static boolean odd(long i) {
return (i & 1) != 0;
}
static boolean odd(BigInteger i) { return odd(toInt(i)); }
static A assertEquals(Object x, A y) {
return assertEquals("", x, y);
}
static A assertEquals(String msg, Object x, A y) {
if (assertVerbose()) return assertEqualsVerbose(msg, x, y);
if (!(x == null ? y == null : x.equals(y)))
throw fail((msg != null ? msg + ": " : "") + y + " != " + x);
return y;
}
static String shortClassName_dropNumberPrefix(Object o) {
return dropNumberPrefix(shortClassName(o));
}
static java.util.Timer doLater(long delay, final Object r) {
ping();
final java.util.Timer timer = new java.util.Timer();
timer.schedule(timerTask(r, timer), delay);
return vmBus_timerStarted(timer);
}
static java.util.Timer doLater(double delaySeconds, final Object r) {
return doLater(toMS(delaySeconds), r);
}
static Timestamp tsNow() {
return new Timestamp();
}
static volatile int numberOfCores_value;
static int numberOfCores() {
if (numberOfCores_value == 0)
numberOfCores_value = Runtime.getRuntime().availableProcessors();
return numberOfCores_value;
}
static Set createOrAddToSyncLinkedHashSet(Set set, A a) {
if (set == null) set = syncLinkedHashSet();
set.add(a);
return set;
}
static A pcallF_typed(F0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static B pcallF_typed(F1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static void pcallF_typed(VF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { printStackTrace(__e); }
}
static void pcallF_typed(IVF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { printStackTrace(__e); }
}
static void pcallF_typed(IVF2 f, A a, B b) {
try {
{ if (f != null) f.get(a, b); }
} catch (Throwable __e) { printStackTrace(__e); }
}
static Object pcallF_typed(Runnable r) {
try { { if (r != null) r.run(); } } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static A pcallF_typed(IF0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
static B pcallF_typed(IF1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { printStackTrace(__e); } return null;
}
// runnable = Runnable or String (method name)
static Thread newThread(Object runnable) {
return new BetterThread(_topLevelErrorHandling(toRunnable(runnable)));
}
static Thread newThread(Object runnable, String name) {
if (name == null) name = defaultThreadName();
return new BetterThread(_topLevelErrorHandling(toRunnable(runnable)), name);
}
static Thread newThread(String name, Object runnable) {
return newThread(runnable, name);
}
static int random(int n) { return random(n, defaultRandomGenerator()); }
static int random(int n, Random r) {
return random(r, n);
}
static int random(Random r, int n) {
return n <= 0 ? 0 : getRandomizer(r).nextInt(n);
}
static double random(double max) {
return random()*max;
}
static double random() {
return defaultRandomGenerator().nextInt(100001)/100000.0;
}
static double random(double min, double max) {
return min+random()*(max-min);
}
// min <= value < max
static int random(int min, int max) {
return min+random(max-min);
}
static int random(int min, int max, Random r) {
return random(r, min, max);
}
static int random(Random r, int min, int max) {
return min+random(r, max-min);
}
static A random(List l) {
return oneOf(l);
}
static A random(Collection c) {
if (c instanceof List) return random((List ) c);
int i = random(l(c));
return collectionGet(c, i);
}
static Pair random(Map map) {
return entryToPair(random(entries(map)));
}
// Yes the nomenclature is a bit illogical
static Chain chainPlus(Chain chain, A a) {
return new Chain (a, chain);
}
static Chain chainPlus(Chain chain, A... l) {
for (A a : unnullForIteration(l))
chain = chainPlus(chain, a);
return chain;
}
static ReverseChain chainPlus(ReverseChain chain, A a) {
return new ReverseChain (chain, a);
}
static ReverseChain chainPlus(ReverseChain chain, A... l) {
for (A a : unnullForIteration(l))
chain = chainPlus(chain, a);
return chain;
}
static AppendableChain chainPlus(AppendableChain chain, A a) {
if (chain == null) return new AppendableChain (a);
chain.add(a);
return chain;
}
static AppendableChain chainPlus(AppendableChain chain, A... l) {
for (A a : unnullForIteration(l))
chain = chainPlus(chain, a);
return chain;
}
static String n2(long l) { return formatWithThousands(l); }
static String n2(AtomicLong l) { return n2(l.get()); }
static String n2(Collection l) { return n2(l(l)); }
static String n2(Map map) { return n2(l(map)); }
static String n2(double l, String singular) {
return empty(singular) ? str(l) : n2(l, singular, singular + "s");
}
static String n2(double l, String singular, String plural) {
if (fraction(l) == 0)
return n2((long) l, singular, plural);
else
return l + " " + plural;
}
static String n2(long l, String singular, String plural) {
return n_fancy2(l, singular, plural);
}
static String n2(long l, String singular) {
return empty(singular) ? n2(l) : n_fancy2(l, singular, singular + "s");
}
static String n2(Collection l, String singular) {
return n2(l(l), singular);
}
static String n2(Collection l, String singular, String plural) {
return n_fancy2(l, singular, plural);
}
static String n2(Map m, String singular, String plural) {
return n_fancy2(m, singular, plural);
}
static String n2(Map m, String singular) {
return n2(l(m), singular);
}
static String n2(long[] a, String singular) { return n2(l(a), singular); }
static String n2(Object[] a, String singular) { return n2(l(a), singular); }
static String n2(Object[] a, String singular, String plural) { return n_fancy2(a, singular, plural); }
static String n2(IMultiMap mm, String singular) { return n2(mm, singular, singular + "s"); }
static String n2(IMultiMap mm, String singular, String plural) {
return n_fancy2(l(mm), singular, plural);
}
static String roundBracket(String s) {
return "(" + s + ")";
}
static String roundBracket(Object s) {
return roundBracket(str(s));
}
static void syncNotifyAll(Object o) {
if (o != null) synchronized(o) { o.notifyAll(); }
}
static int getWidth(Component c) {
return c == null ? 0 : (int) swingCall(c, "getWidth");
}
static int getHeight(Component c) {
return c == null ? 0 : (int) swingCall(c, "getHeight");
}
static Rect rect(int x, int y, int w, int h) {
return new Rect(x, y, w, h);
}
static Rect rect(Pt p, int w, int h) {
return new Rect(p.x, p.y, w, h);
}
static Rect rect(int w, int h) {
return new Rect(0, 0, w, h);
}
static int toInt(Object o) {
if (o == null) return 0;
if (o instanceof Number)
return ((Number) o).intValue();
if (o instanceof String)
return parseInt((String) o);
if (o instanceof Boolean)
return boolToInt((Boolean) o);
throw fail("woot not int: " + getClassName(o));
}
static int toInt(long l) {
if (l != (int) l) throw fail("Too large for int: " + l);
return (int) l;
}
static long longMul(long a, long b) {
return a*b;
}
static void add(BitSet bs, int i) {
bs.set(i);
}
static boolean add(Collection c, A a) {
return c != null && c.add(a);
}
static void add(Container c, Component x) {
addToContainer(c, x);
}
static long add(AtomicLong l, long b) {
return l.addAndGet(b);
}
static B firstValue(Map map) {
return first(values(map));
}
static B firstValue(MultiMap map) {
return map == null ? null : first(firstValue(map.data));
}
static A firstKey(Map map) {
return first(keys(map));
}
static A firstKey(IMultiMap map) {
return map == null ? null : first(map.keySet());
}
static byte[] toASCII(String s) {
return s.getBytes(java.nio.charset.StandardCharsets.US_ASCII);
}
static byte toASCII(char c) {
return toASCII(str(new char[] {c}))[0];
}
static byte toUByte(int i) {
if (!isUByte(i))
throw fail("Not a u-byte: " + i);
return (byte) i;
}
static void addAll(Collection c, Iterable b) {
if (c != null && b != null) for (A a : b) c.add(a);
}
static boolean addAll(Collection c, Collection b) {
return c != null && b != null && c.addAll(b);
}
static boolean addAll(Collection c, B... b) {
return c != null && b != null && c.addAll(Arrays.asList(b));
}
static Map addAll(Map a, Map extends A,? extends B> b) {
if (a != null && b != null) a.putAll(b);
return a;
}
static A addAll(A c, Collection extends Component> components) {
return addComponents(c, components);
}
static A addAll(A c, Component... components) {
return addComponents(c, components);
}
static int lByteArray(byte[] a) {
return a == null ? 0 : a.length;
}
static int maximumSafeArraySize() {
return Integer.MAX_VALUE-8;
}
static byte[] resizeByteArray(byte[] a, int n) {
if (n == l(a)) return a;
byte[] b = new byte[n];
arraycopy(a, 0, b, 0, min(l(a), n));
return b;
}
static Object[] toArray(Collection c) {
return toObjectArray(c);
}
static A[] toArray(Class type, Iterable c) {
return toArray(c, type);
}
static A[] toArray(Class type, Collection c) {
return toArray(c, type);
}
static A[] toArray(Collection c, Class type) {
A[] a = arrayOfType(l(c), type);
if (a.length == 0) return a;
asList(c).toArray(a);
return a;
}
static A[] toArray(Iterable c, Class type) {
var c2 = asList(c);
A[] a = arrayOfType(l(c2), type);
if (a.length == 0) return a;
c2.toArray(a);
return a;
}
// array must have correct length and will be filled
static A[] toArray(A[] array, Collection c) {
if (array == null || c == null) return null;
asList(c).toArray(array);
return array;
}
static ArrayList