1 | !1005027 |
2 | |
3 | // The following comes from: http://tinybrain.de:8080/tb-int/get-transpiled.php?id=1005017&raw=1 |
4 | |
5 | import java.util.*; |
6 | import java.util.zip.*; |
7 | import java.util.List; |
8 | import java.util.regex.*; |
9 | import java.util.concurrent.*; |
10 | import java.util.concurrent.atomic.*; |
11 | import javax.swing.*; |
12 | import javax.swing.event.*; |
13 | import javax.swing.text.*; |
14 | import javax.swing.table.*; |
15 | import java.io.*; |
16 | import java.net.*; |
17 | import java.lang.reflect.*; |
18 | import java.lang.ref.*; |
19 | import java.lang.management.*; |
20 | import java.security.*; |
21 | import java.security.spec.*; |
22 | import java.awt.*; |
23 | import java.awt.event.*; |
24 | import java.awt.image.*; |
25 | import javax.imageio.*; |
26 | import java.math.*; |
27 | public class main { |
28 | |
29 | |
30 | static String defaultCfg = "\nalwaysrun true\nchatmacro0 \"No\"\nchatmacro1 \"I'm ready to kick butt!\"\nchatmacro2 \"I'm OK.\"\nchatmacro3 \"I'm not looking too good!\"\nchatmacro4 \"Help!\"\nchatmacro5 \"You suck!\"\nchatmacro6 \"Next time, scumbag...\"\nchatmacro7 \"Come here!\"\nchatmacro8 \"I'll take care of it.\"\nchatmacro9 \"Yes\"\ndetaillevel 0\nfullscreen true\njoyb_fire 0\njoyb_speed 2\njoyb_strafe 1\njoyb_use 3\nkey_down 115\nkey_fire 157\nkey_left 172\nkey_right 174\nkey_speed 182\nkey_strafe 184\nkey_strafeleft 97\nkey_straferight 100\nkey_up 119\nkey_use 32\nmb_used 2\nmouse_sensitivity 5\nmouseb_fire 0\nmouseb_forward 2\nmouseb_strafe 1\nmusic_volume 8\nscreenblocks 10\nsfx_volume 8\nshow_messages true\nsnd_channels 3\nuse_joystick false\nuse_mouse true\nusegamma 0\n"; |
31 | |
32 | public static void main(String[] args) throws Exception { |
33 | renameConsole("Mocha DOOM!"); |
34 | File iwad = loadLibrary("#1005008"); |
35 | File iwad2 = prepareProgramFile("doom1.wad"); |
36 | copyFile(iwad, iwad2); |
37 | File iwad3 = new File(iwad2.getName()); |
38 | if (!iwad3.exists()) |
39 | throw fail("We are not in the right directory! " + f2s(iwad3.getAbsoluteFile().getParentFile()) + " (should be " + f2s(programDir()) + ")"); |
40 | |
41 | File cfgFile = prepareProgramFile("default.cfg"); |
42 | if (!cfgFile.exists()) |
43 | saveTextFile(cfgFile, defaultCfg.trim()); |
44 | |
45 | String[] argz = {"-iwad", f2s(iwad2)}; |
46 | printStructure(argz); |
47 | callMain(_getClass("i.Main"), argz); |
48 | } |
49 | |
50 | |
51 | public static void copyFile(File src, File dest) { try { |
52 | |
53 | mkdirsForFile(dest); |
54 | FileInputStream inputStream = new FileInputStream(src.getPath()); |
55 | FileOutputStream outputStream = new FileOutputStream(dest.getPath()); |
56 | try { |
57 | copyStream(inputStream, outputStream); |
58 | inputStream.close(); |
59 | } finally { |
60 | outputStream.close(); |
61 | } |
62 | |
63 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
64 | static RuntimeException fail() { |
65 | throw new RuntimeException("fail"); |
66 | } |
67 | |
68 | static RuntimeException fail(Object msg) { |
69 | throw new RuntimeException(String.valueOf(msg)); |
70 | } |
71 | |
72 | static RuntimeException fail(String msg) { |
73 | throw new RuntimeException(unnull(msg)); |
74 | } |
75 | |
76 | // disabled for now to shorten some programs |
77 | /*static RuntimeException fail(S msg, O... args) { |
78 | throw new RuntimeException(format(msg, args)); |
79 | }*/ |
80 | static File loadLibrary(String snippetID) { |
81 | return loadBinarySnippet(snippetID); |
82 | } |
83 | static File prepareProgramFile(String name) { |
84 | return mkdirsForFile(getProgramFile(name)); |
85 | } |
86 | |
87 | static File prepareProgramFile(String progID, String name) { |
88 | return mkdirsForFile(getProgramFile(progID, name)); |
89 | } |
90 | static void callMain(Object c, String... args) { |
91 | callOpt(c, "main", new Object[] {args}); |
92 | } |
93 | static String f2s(File f) { |
94 | return f == null ? null : f.getAbsolutePath(); |
95 | } |
96 | /** writes safely (to temp file, then rename) */ |
97 | public static void saveTextFile(String fileName, String contents) throws IOException { |
98 | File file = new File(fileName); |
99 | File parentFile = file.getParentFile(); |
100 | if (parentFile != null) |
101 | parentFile.mkdirs(); |
102 | String tempFileName = fileName + "_temp"; |
103 | File tempFile = new File(tempFileName); |
104 | if (contents != null) { |
105 | if (tempFile.exists()) try { |
106 | String saveName = tempFileName + ".saved." + now(); |
107 | copyFile(tempFile, new File(saveName)); |
108 | } catch (Throwable e) { printStackTrace(e); } |
109 | FileOutputStream fileOutputStream = new FileOutputStream(tempFile.getPath()); |
110 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); |
111 | PrintWriter printWriter = new PrintWriter(outputStreamWriter); |
112 | printWriter.print(contents); |
113 | printWriter.close(); |
114 | } |
115 | |
116 | if (file.exists() && !file.delete()) |
117 | throw new IOException("Can't delete " + fileName); |
118 | |
119 | if (contents != null) |
120 | if (!tempFile.renameTo(file)) |
121 | throw new IOException("Can't rename " + tempFile + " to " + file); |
122 | } |
123 | |
124 | public static void saveTextFile(File fileName, String contents) { |
125 | try { |
126 | saveTextFile(fileName.getPath(), contents); |
127 | } catch (IOException e) { |
128 | throw new RuntimeException(e); |
129 | } |
130 | } |
131 | |
132 | static void renameConsole(String title) { |
133 | setConsoleTitle(title); |
134 | } |
135 | static File programDir_mine; // set this to relocate program's data |
136 | |
137 | static File programDir() { |
138 | return programDir(getProgramID()); |
139 | } |
140 | |
141 | static File programDir(String snippetID) { |
142 | if (programDir_mine != null && sameSnippetID(snippetID, programID())) |
143 | return programDir_mine; |
144 | return new File(javaxDataDir(), formatSnippetID(snippetID)); |
145 | } |
146 | |
147 | static Class<?> _getClass(String name) { |
148 | try { |
149 | return Class.forName(name); |
150 | } catch (ClassNotFoundException e) { |
151 | return null; |
152 | } |
153 | } |
154 | |
155 | static Class _getClass(Object o) { |
156 | return o instanceof Class ? (Class) o : o.getClass(); |
157 | } |
158 | |
159 | static Class _getClass(Object realm, String name) { try { |
160 | |
161 | return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); |
162 | |
163 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
164 | static void printStructure(String prefix, Object o) { |
165 | print(prefix + structure(o)); |
166 | } |
167 | |
168 | static void printStructure(Object o) { |
169 | print(structure(o)); |
170 | } |
171 | |
172 | |
173 | |
174 | static Class<?> getClass(String name) { |
175 | try { |
176 | return Class.forName(name); |
177 | } catch (ClassNotFoundException e) { |
178 | return null; |
179 | } |
180 | } |
181 | |
182 | static Class getClass(Object o) { |
183 | return o instanceof Class ? (Class) o : o.getClass(); |
184 | } |
185 | |
186 | static Class getClass(Object realm, String name) { try { |
187 | |
188 | try { |
189 | return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); |
190 | } catch (ClassNotFoundException e) { |
191 | return null; |
192 | } |
193 | |
194 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
195 | public static File mkdirsForFile(File file) { |
196 | File dir = file.getParentFile(); |
197 | if (dir != null) // is null if file is in current dir |
198 | dir.mkdirs(); |
199 | return file; |
200 | } |
201 | |
202 | static File javaxDataDir_dir; // can be set to work on different base dir |
203 | |
204 | static File javaxDataDir() { |
205 | return javaxDataDir_dir != null ? javaxDataDir_dir : new File(userHome(), "JavaX-Data"); |
206 | } |
207 | static Object callOpt(Object o) { |
208 | if (o == null) return null; |
209 | return callF(o); |
210 | } |
211 | |
212 | static Object callOpt(Object o, String method, Object... args) { |
213 | try { |
214 | if (o == null) return null; |
215 | if (o instanceof Class) { |
216 | Method m = callOpt_findStaticMethod((Class) o, method, args, false); |
217 | if (m == null) return null; |
218 | m.setAccessible(true); |
219 | return m.invoke(null, args); |
220 | } else { |
221 | Method m = callOpt_findMethod(o, method, args, false); |
222 | if (m == null) return null; |
223 | m.setAccessible(true); |
224 | return m.invoke(o, args); |
225 | } |
226 | } catch (Exception e) { |
227 | throw new RuntimeException(e); |
228 | } |
229 | } |
230 | |
231 | static Method callOpt_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
232 | Class _c = c; |
233 | while (c != null) { |
234 | for (Method m : c.getDeclaredMethods()) { |
235 | if (debug) |
236 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
237 | if (!m.getName().equals(method)) { |
238 | if (debug) System.out.println("Method name mismatch: " + method); |
239 | continue; |
240 | } |
241 | |
242 | if ((m.getModifiers() & Modifier.STATIC) == 0 || !callOpt_checkArgs(m, args, debug)) |
243 | continue; |
244 | |
245 | return m; |
246 | } |
247 | c = c.getSuperclass(); |
248 | } |
249 | return null; |
250 | } |
251 | |
252 | static Method callOpt_findMethod(Object o, String method, Object[] args, boolean debug) { |
253 | Class c = o.getClass(); |
254 | while (c != null) { |
255 | for (Method m : c.getDeclaredMethods()) { |
256 | if (debug) |
257 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
258 | if (m.getName().equals(method) && callOpt_checkArgs(m, args, debug)) |
259 | return m; |
260 | } |
261 | c = c.getSuperclass(); |
262 | } |
263 | return null; |
264 | } |
265 | |
266 | private static boolean callOpt_checkArgs(Method m, Object[] args, boolean debug) { |
267 | Class<?>[] types = m.getParameterTypes(); |
268 | if (types.length != args.length) { |
269 | if (debug) |
270 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
271 | return false; |
272 | } |
273 | for (int i = 0; i < types.length; i++) |
274 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
275 | if (debug) |
276 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
277 | return false; |
278 | } |
279 | return true; |
280 | } |
281 | |
282 | |
283 | static String programID; |
284 | |
285 | static String getProgramID() { |
286 | return nempty(programID) ? formatSnippetID(programID) : "?"; |
287 | } |
288 | |
289 | // TODO: ask JavaX instead |
290 | static String getProgramID(Class c) { |
291 | String id = (String) getOpt(c, "programID"); |
292 | if (nempty(id)) |
293 | return formatSnippetID(id); |
294 | return "?"; |
295 | } |
296 | |
297 | static String getProgramID(Object o) { |
298 | return getProgramID(getMainClass(o)); |
299 | } |
300 | |
301 | static String unnull(String s) { |
302 | return s == null ? "" : s; |
303 | } |
304 | |
305 | static <A> List<A> unnull(List<A> l) { |
306 | return l == null ? emptyList() : l; |
307 | } |
308 | |
309 | static <A> Iterable<A> unnull(Iterable<A> i) { |
310 | return i == null ? emptyList() : i; |
311 | } |
312 | |
313 | static Object[] unnull(Object[] a) { |
314 | return a == null ? new Object[0] : a; |
315 | } |
316 | static void setConsoleTitle(String title) { |
317 | callOpt(consoleFrame_gen(), "setTitle", title); |
318 | } |
319 | static long now_virtualTime; |
320 | static long now() { |
321 | return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); |
322 | } |
323 | |
324 | static String formatSnippetID(String id) { |
325 | return "#" + parseSnippetID(id); |
326 | } |
327 | |
328 | static String formatSnippetID(long id) { |
329 | return "#" + id; |
330 | } |
331 | static String programID() { |
332 | return getProgramID(); |
333 | } |
334 | static File getProgramFile(String progID, String fileName) { |
335 | if (new File(fileName).isAbsolute()) |
336 | return new File(fileName); |
337 | return new File(getProgramDir(progID), fileName); |
338 | } |
339 | |
340 | static File getProgramFile(String fileName) { |
341 | return getProgramFile(getProgramID(), fileName); |
342 | } |
343 | |
344 | static void printStackTrace(Throwable e) { |
345 | // we go to system.out now - system.err is nonsense |
346 | print(getStackTrace(e)); |
347 | } |
348 | |
349 | static void printStackTrace() { |
350 | printStackTrace(new Throwable()); |
351 | } |
352 | static String classNameToVM(String name) { |
353 | return name.replace(".", "$"); |
354 | } |
355 | static String structure(Object o) { |
356 | HashSet refd = new HashSet(); |
357 | return structure_2(structure_1(o, new structure_Data(refd)), refd); |
358 | } |
359 | |
360 | // leave to false, unless unstructure() breaks |
361 | static boolean structure_allowShortening = false; |
362 | |
363 | static int structure_shareStringsLongerThan = 20; |
364 | |
365 | static class structure_Data { |
366 | int stringSizeLimit; |
367 | IdentityHashMap<Object, Integer> seen = new IdentityHashMap<Object, Integer>(); |
368 | HashSet<Integer> refd; |
369 | HashMap<String, Integer> strings = new HashMap<String, Integer>(); |
370 | HashSet<String> concepts = new HashSet<String>(); |
371 | Class conceptClass = findClass("Concept"); |
372 | |
373 | structure_Data(HashSet<Integer> refd) { |
374 | this.refd = refd;} |
375 | } |
376 | |
377 | static String structure_1(Object o, structure_Data d) { |
378 | if (o == null) return "null"; |
379 | |
380 | // these are never back-referenced (for readability) |
381 | |
382 | if (o instanceof BigInteger) |
383 | return "bigint(" + o + ")"; |
384 | |
385 | if (o instanceof Double) |
386 | return "d(" + quote(str(o)) + ")"; |
387 | |
388 | if (o instanceof Float) |
389 | return "fl " + quote(str(o)); |
390 | |
391 | if (o instanceof Long) |
392 | return o + "L"; |
393 | |
394 | if (o instanceof Integer) |
395 | return str(o); |
396 | |
397 | if (o instanceof Boolean) |
398 | return ((Boolean) o).booleanValue() ? "t" : "f"; |
399 | |
400 | if (o instanceof Character) |
401 | return quoteCharacter((Character) o); |
402 | |
403 | if (o instanceof File) |
404 | return "File " + quote(((File) o).getPath()); |
405 | |
406 | // referencable objects follow |
407 | |
408 | Integer ref = d.seen.get(o); |
409 | if (ref != null) { |
410 | d.refd.add(ref); |
411 | return "r" + ref; |
412 | } |
413 | |
414 | if (o instanceof String && (ref = d.strings.get((String) o)) != null) { |
415 | d.refd.add(ref); |
416 | return "r" + ref; |
417 | } |
418 | |
419 | ref = d.seen.size()+1; |
420 | d.seen.put(o, ref); |
421 | String r = "m" + ref + " "; // marker |
422 | |
423 | if (o instanceof String) { |
424 | String s = d.stringSizeLimit != 0 ? shorten((String) o, d.stringSizeLimit) : (String) o; |
425 | if (l(s) >= structure_shareStringsLongerThan) |
426 | d.strings.put(s, ref); |
427 | return r + quote(s); |
428 | } |
429 | |
430 | String name = o.getClass().getName(); |
431 | |
432 | StringBuilder buf = new StringBuilder(); |
433 | |
434 | if (o instanceof HashSet) |
435 | return r + "hashset " + structure_1(new ArrayList((Set) o), d); |
436 | |
437 | if (o instanceof TreeSet) |
438 | return r + "treeset " + structure_1(new ArrayList((Set) o), d); |
439 | |
440 | if (o instanceof Collection) { |
441 | for (Object x : (Collection) o) { |
442 | if (buf.length() != 0) buf.append(", "); |
443 | buf.append(structure_1(x, d)); |
444 | } |
445 | return r + "[" + buf + "]"; |
446 | } |
447 | |
448 | if (o instanceof Map) { |
449 | for (Object e : ((Map) o).entrySet()) { |
450 | if (buf.length() != 0) buf.append(", "); |
451 | buf.append(structure_1(((Map.Entry) e).getKey(), d)); |
452 | buf.append("="); |
453 | buf.append(structure_1(((Map.Entry) e).getValue(), d)); |
454 | } |
455 | return r + (o instanceof HashMap ? "hm" : "") + "{" + buf + "}"; |
456 | } |
457 | |
458 | if (o.getClass().isArray()) { |
459 | if (o instanceof byte[]) |
460 | return "ba " + quote(bytesToHex((byte[]) o)); |
461 | |
462 | int n = Array.getLength(o); |
463 | |
464 | if (o instanceof boolean[]) { |
465 | String hex = boolArrayToHex((boolean[]) o); |
466 | int i = l(hex); |
467 | while (i > 0 && hex.charAt(i-1) == '0' && hex.charAt(i-2) == '0') i -= 2; |
468 | return "boolarray " + n + " " + quote(substring(hex, 0, i)); |
469 | } |
470 | |
471 | String atype = "array", sep = ", "; |
472 | |
473 | if (o instanceof int[]) { |
474 | //ret "intarray " + quote(intArrayToHex((int[]) o)); |
475 | atype = "intarray"; |
476 | sep = " "; |
477 | } |
478 | |
479 | for (int i = 0; i < n; i++) { |
480 | if (buf.length() != 0) buf.append(sep); |
481 | buf.append(structure_1(Array.get(o, i), d)); |
482 | } |
483 | return r + atype + "{" + buf + "}"; |
484 | } |
485 | |
486 | if (o instanceof Class) |
487 | return r + "class(" + quote(((Class) o).getName()) + ")"; |
488 | |
489 | if (o instanceof Throwable) |
490 | return r + "exception(" + quote(((Throwable) o).getMessage()) + ")"; |
491 | |
492 | if (o instanceof BitSet) { |
493 | BitSet bs = (BitSet) o; |
494 | for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) { |
495 | if (buf.length() != 0) buf.append(", "); |
496 | buf.append(i); |
497 | } |
498 | return "bitset{" + buf + "}"; |
499 | } |
500 | |
501 | // Need more cases? This should cover all library classes... |
502 | if (name.startsWith("java.") || name.startsWith("javax.")) |
503 | return r + String.valueOf(o); |
504 | |
505 | String shortName = o.getClass().getName().replaceAll("^main\\$", ""); |
506 | |
507 | if (shortName.equals("Lisp")) { |
508 | buf.append("l(" + structure_1(getOpt(o, "head"), d)); |
509 | List args = (List) ( getOpt(o, "args")); |
510 | if (nempty(args)) |
511 | for (int i = 0; i < l(args); i++) { |
512 | buf.append(", "); |
513 | Object arg = args.get(i); |
514 | |
515 | // sweet shortening |
516 | if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty"))) |
517 | arg = get(arg, "head"); |
518 | |
519 | buf.append(structure_1(arg, d)); |
520 | } |
521 | buf.append(")"); |
522 | return r + str(buf); |
523 | } |
524 | |
525 | int numFields = 0; |
526 | String fieldName = ""; |
527 | if (shortName.equals("DynamicObject")) { |
528 | shortName = (String) get_raw(o, "className"); |
529 | Map<String, Object> fieldValues = (Map) get_raw(o, "fieldValues"); |
530 | |
531 | for (String _fieldName : fieldValues.keySet()) { |
532 | fieldName = _fieldName; |
533 | Object value = fieldValues.get(fieldName); |
534 | if (value != null) { |
535 | if (buf.length() != 0) buf.append(", "); |
536 | buf.append(fieldName + "=" + structure_1(value, d)); |
537 | } |
538 | ++numFields; |
539 | } |
540 | } else { |
541 | // regular class |
542 | |
543 | Class c = o.getClass(); |
544 | |
545 | if (d.conceptClass != null && d.conceptClass.isInstance(o) && !d.concepts.contains(c.getName())) { |
546 | d.concepts.add(c.getName()); |
547 | r += "c "; |
548 | } |
549 | |
550 | while (c != Object.class) { |
551 | List<Field> fields = asList(c.getDeclaredFields()); |
552 | for (int i = 1; i < l(fields); i++) |
553 | if (eq(fields.get(i).getName(), "this$1")) { |
554 | swapElements(fields, 0, i); |
555 | break; |
556 | } |
557 | for (Field field : fields) { |
558 | if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0) |
559 | continue; |
560 | fieldName = field.getName(); |
561 | |
562 | // skip outer object reference |
563 | //if (fieldName.indexOf("$") >= 0) continue; |
564 | |
565 | Object value; |
566 | try { |
567 | field.setAccessible(true); |
568 | value = field.get(o); |
569 | } catch (Exception e) { |
570 | value = "?"; |
571 | } |
572 | |
573 | // put special cases here... |
574 | |
575 | if (value != null) { |
576 | if (buf.length() != 0) buf.append(", "); |
577 | buf.append(fieldName + "=" + structure_1(value, d)); |
578 | } |
579 | ++numFields; |
580 | } |
581 | c = c.getSuperclass(); |
582 | } |
583 | } |
584 | |
585 | String b = buf.toString(); |
586 | |
587 | if (numFields == 1 && structure_allowShortening) |
588 | b = b.replaceAll("^" + fieldName + "=", ""); // drop field name if only one |
589 | String s = shortName; |
590 | if (buf.length() != 0) |
591 | s += "(" + b + ")"; |
592 | return r + s; |
593 | } |
594 | |
595 | // drop unused markers |
596 | static String structure_2(String s, HashSet<Integer> refd) { |
597 | List<String> tok = javaTok(s); |
598 | StringBuilder out = new StringBuilder(); |
599 | for (int i = 1; i < l(tok); i += 2) { |
600 | String t = tok.get(i); |
601 | if (t.startsWith("m") && isInteger(t.substring(1)) |
602 | && !refd.contains(parseInt(t.substring(1)))) |
603 | continue; |
604 | out.append(t).append(tok.get(i+1)); |
605 | } |
606 | return str(out); |
607 | } |
608 | |
609 | static boolean sameSnippetID(String a, String b) { |
610 | return a != null && b != null && parseSnippetID(a) == parseSnippetID(b); |
611 | } |
612 | static volatile StringBuffer local_log = new StringBuffer(); // not redirected |
613 | static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot |
614 | |
615 | // in bytes - will cut to half that |
616 | static volatile int print_log_max = 1024*1024; |
617 | static volatile int local_log_max = 100*1024; |
618 | //static int print_maxLineLength = 0; // 0 = unset |
619 | |
620 | static boolean print_silent; // total mute if set |
621 | |
622 | static void print() { |
623 | print(""); |
624 | } |
625 | |
626 | // slightly overblown signature to return original object... |
627 | static <A> A print(A o) { |
628 | if (print_silent) return o; |
629 | String s = String.valueOf(o) + "\n"; |
630 | // TODO if (print_maxLineLength != 0) |
631 | StringBuffer loc = local_log; |
632 | StringBuffer buf = print_log; |
633 | int loc_max = print_log_max; |
634 | if (buf != loc && buf != null) { |
635 | print_append(buf, s, print_log_max); |
636 | loc_max = local_log_max; |
637 | } |
638 | if (loc != null) |
639 | print_append(loc, s, loc_max); |
640 | System.out.print(s); |
641 | return o; |
642 | } |
643 | |
644 | static void print(long l) { |
645 | print(String.valueOf(l)); |
646 | } |
647 | |
648 | static void print(char c) { |
649 | print(String.valueOf(c)); |
650 | } |
651 | |
652 | static void print_append(StringBuffer buf, String s, int max) { |
653 | synchronized(buf) { |
654 | buf.append(s); |
655 | max /= 2; |
656 | if (buf.length() > max) try { |
657 | int newLength = max/2; |
658 | int ofs = buf.length()-newLength; |
659 | String newString = buf.substring(ofs); |
660 | buf.setLength(0); |
661 | buf.append("[...] ").append(newString); |
662 | } catch (Exception e) { |
663 | buf.setLength(0); |
664 | } |
665 | } |
666 | } |
667 | static void copyStream(InputStream in, OutputStream out) { try { |
668 | |
669 | byte[] buf = new byte[65536]; |
670 | while (true) { |
671 | int n = in.read(buf); |
672 | if (n <= 0) return; |
673 | out.write(buf, 0, n); |
674 | } |
675 | |
676 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
677 | static File loadBinarySnippet(String snippetID) { try { |
678 | |
679 | long id = parseSnippetID(snippetID); |
680 | File f = DiskSnippetCache_getLibrary(id); |
681 | if (f == null) { |
682 | byte[] data = loadDataSnippetImpl(snippetID); |
683 | DiskSnippetCache_putLibrary(id, data); |
684 | f = DiskSnippetCache_getLibrary(id); |
685 | } |
686 | return f; |
687 | |
688 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
689 | |
690 | |
691 | static Object callF(Object f, Object... args) { |
692 | return callFunction(f, args); |
693 | } |
694 | static <A> ArrayList<A> asList(A[] a) { |
695 | return new ArrayList<A>(Arrays.asList(a)); |
696 | } |
697 | |
698 | static ArrayList<Integer> asList(int[] a) { |
699 | ArrayList<Integer> l = new ArrayList(); |
700 | for (int i : a) l.add(i); |
701 | return l; |
702 | } |
703 | |
704 | static <A> ArrayList<A> asList(Iterable<A> s) { |
705 | if (s instanceof ArrayList) return (ArrayList) s; |
706 | ArrayList l = new ArrayList(); |
707 | if (s != null) |
708 | for (A a : s) |
709 | l.add(a); |
710 | return l; |
711 | } |
712 | public static String bytesToHex(byte[] bytes) { |
713 | return bytesToHex(bytes, 0, bytes.length); |
714 | } |
715 | |
716 | public static String bytesToHex(byte[] bytes, int ofs, int len) { |
717 | StringBuilder stringBuilder = new StringBuilder(len*2); |
718 | for (int i = 0; i < len; i++) { |
719 | String s = "0" + Integer.toHexString(bytes[ofs+i]); |
720 | stringBuilder.append(s.substring(s.length()-2, s.length())); |
721 | } |
722 | return stringBuilder.toString(); |
723 | } |
724 | |
725 | static void swapElements(List l, int i, int j) { |
726 | if (i == j) return; |
727 | Object o = l.get(i); |
728 | l.set(i, l.get(j)); |
729 | l.set(j, o); |
730 | } |
731 | static boolean isInteger(String s) { |
732 | return s != null && Pattern.matches("\\-?\\d+", s); |
733 | } |
734 | static String quote(String s) { |
735 | if (s == null) return "null"; |
736 | return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\""; |
737 | } |
738 | |
739 | static String quote(long l) { |
740 | return quote("" + l); |
741 | } |
742 | |
743 | static String quote(char c) { |
744 | return quote("" + c); |
745 | } |
746 | |
747 | static String shorten(String s, int max) { |
748 | if (s == null) return ""; |
749 | return s.length() <= max ? s : s.substring(0, Math.min(s.length(), max)) + "..."; |
750 | } |
751 | static String getStackTrace(Throwable throwable) { |
752 | StringWriter writer = new StringWriter(); |
753 | throwable.printStackTrace(new PrintWriter(writer)); |
754 | return writer.toString(); |
755 | } |
756 | static String quoteCharacter(char c) { |
757 | if (c == '\'') return "'\\''"; |
758 | if (c == '\\') return "'\\\\'"; |
759 | return "'" + c + "'"; |
760 | } |
761 | |
762 | // extended over Class.isInstance() to handle primitive types |
763 | static boolean isInstanceX(Class type, Object arg) { |
764 | if (type == boolean.class) return arg instanceof Boolean; |
765 | if (type == int.class) return arg instanceof Integer; |
766 | if (type == long.class) return arg instanceof Long; |
767 | if (type == float.class) return arg instanceof Float; |
768 | if (type == short.class) return arg instanceof Short; |
769 | if (type == char.class) return arg instanceof Character; |
770 | if (type == byte.class) return arg instanceof Byte; |
771 | if (type == double.class) return arg instanceof Double; |
772 | return type.isInstance(arg); |
773 | } |
774 | // currently finds only inner classes of class "main" |
775 | // returns null on not found |
776 | // this is the simple version that is not case-tolerant |
777 | static Class findClass(String name) { |
778 | if (!isJavaIdentifier(name)) return null; |
779 | try { |
780 | return Class.forName("main$" + name); |
781 | } catch (ClassNotFoundException e) { |
782 | return null; |
783 | } |
784 | } |
785 | static boolean eq(Object a, Object b) { |
786 | if (a == null) return b == null; |
787 | if (a.equals(b)) return true; |
788 | if (a instanceof BigInteger) { |
789 | if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b)); |
790 | if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b)); |
791 | } |
792 | return false; |
793 | } |
794 | static String str(Object o) { |
795 | return String.valueOf(o); |
796 | } |
797 | // get purpose 1: access a list/array (safer version of x.get(y)) |
798 | |
799 | static <A> A get(List<A> l, int idx) { |
800 | return idx >= 0 && idx < l(l) ? l.get(idx) : null; |
801 | } |
802 | |
803 | static <A> A get(A[] l, int idx) { |
804 | return idx >= 0 && idx < l(l) ? l[idx] : null; |
805 | } |
806 | |
807 | // default to false |
808 | static boolean get(boolean[] l, int idx) { |
809 | return idx >= 0 && idx < l(l) ? l[idx] : false; |
810 | } |
811 | |
812 | static Class get_dynamicObject = findClass("DynamicObject"); |
813 | |
814 | // get purpose 2: access a field by reflection or a map |
815 | |
816 | static Object get(Object o, String field) { |
817 | try { |
818 | if (o instanceof Class) return get((Class) o, field); |
819 | |
820 | if (o instanceof Map) |
821 | return ((Map) o).get(field); |
822 | |
823 | Field f = getOpt_findField(o.getClass(), field); |
824 | if (f != null) { |
825 | f.setAccessible(true); |
826 | return f.get(o); |
827 | } |
828 | |
829 | if (get_dynamicObject != null && get_dynamicObject.isInstance(o)) |
830 | return call(get_raw(o, "fieldValues"), "get", field); |
831 | } catch (Exception e) { |
832 | throw asRuntimeException(e); |
833 | } |
834 | throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName()); |
835 | } |
836 | |
837 | static Object get_raw(Object o, String field) { |
838 | try { |
839 | Field f = get_findField(o.getClass(), field); |
840 | f.setAccessible(true); |
841 | return f.get(o); |
842 | } catch (Exception e) { |
843 | throw new RuntimeException(e); |
844 | } |
845 | } |
846 | |
847 | static Object get(Class c, String field) { |
848 | try { |
849 | Field f = get_findStaticField(c, field); |
850 | f.setAccessible(true); |
851 | return f.get(null); |
852 | } catch (Exception e) { |
853 | throw new RuntimeException(e); |
854 | } |
855 | } |
856 | |
857 | static Field get_findStaticField(Class<?> c, String field) { |
858 | Class _c = c; |
859 | do { |
860 | for (Field f : _c.getDeclaredFields()) |
861 | if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) |
862 | return f; |
863 | _c = _c.getSuperclass(); |
864 | } while (_c != null); |
865 | throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); |
866 | } |
867 | |
868 | static Field get_findField(Class<?> c, String field) { |
869 | Class _c = c; |
870 | do { |
871 | for (Field f : _c.getDeclaredFields()) |
872 | if (f.getName().equals(field)) |
873 | return f; |
874 | _c = _c.getSuperclass(); |
875 | } while (_c != null); |
876 | throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); |
877 | } |
878 | static Object consoleFrame_gen() { |
879 | return getOpt(getOpt(getJavaX(), "console"), "frame"); |
880 | } |
881 | // replacement for class JavaTok |
882 | // maybe incomplete, might want to add floating point numbers |
883 | // todo also: extended multi-line strings |
884 | |
885 | static int javaTok_n, javaTok_elements; |
886 | static boolean javaTok_opt; |
887 | |
888 | static List<String> javaTok(String s) { |
889 | return javaTok(s, null); |
890 | } |
891 | |
892 | static List<String> javaTok(String s, List<String> existing) { |
893 | ++javaTok_n; |
894 | int nExisting = javaTok_opt && existing != null ? existing.size() : 0; |
895 | List<String> tok = existing != null ? new ArrayList(nExisting) : new ArrayList(); |
896 | int l = s.length(); |
897 | |
898 | int i = 0, n = 0; |
899 | while (i < l) { |
900 | int j = i; |
901 | char c; String cc; |
902 | |
903 | // scan for whitespace |
904 | while (j < l) { |
905 | c = s.charAt(j); |
906 | cc = s.substring(j, Math.min(j+2, l)); |
907 | if (c == ' ' || c == '\t' || c == '\r' || c == '\n') |
908 | ++j; |
909 | else if (cc.equals("/*")) { |
910 | do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/")); |
911 | j = Math.min(j+2, l); |
912 | } else if (cc.equals("//")) { |
913 | do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0); |
914 | } else |
915 | break; |
916 | } |
917 | |
918 | if (n < nExisting && javaTok_isCopyable(existing.get(n), s, i, j)) |
919 | tok.add(existing.get(n)); |
920 | else |
921 | tok.add(quickSubstring(s, i, j)); |
922 | ++n; |
923 | i = j; |
924 | if (i >= l) break; |
925 | c = s.charAt(i); // cc is not needed in rest of loop body |
926 | cc = s.substring(i, Math.min(i+2, l)); |
927 | |
928 | // scan for non-whitespace |
929 | if (c == '\'' || c == '"') { |
930 | char opener = c; |
931 | ++j; |
932 | while (j < l) { |
933 | if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors |
934 | ++j; |
935 | break; |
936 | } else if (s.charAt(j) == '\\' && j+1 < l) |
937 | j += 2; |
938 | else |
939 | ++j; |
940 | } |
941 | } else if (Character.isJavaIdentifierStart(c)) |
942 | do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't" |
943 | else if (Character.isDigit(c)) { |
944 | do ++j; while (j < l && Character.isDigit(s.charAt(j))); |
945 | if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L |
946 | } else if (cc.equals("[[")) { |
947 | do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]")); |
948 | j = Math.min(j+2, l); |
949 | } else if (cc.equals("[=") && i+2 < l && s.charAt(i+2) == '[') { |
950 | do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]")); |
951 | j = Math.min(j+3, l); |
952 | } else |
953 | ++j; |
954 | |
955 | if (n < nExisting && javaTok_isCopyable(existing.get(n), s, i, j)) |
956 | tok.add(existing.get(n)); |
957 | else |
958 | tok.add(quickSubstring(s, i, j)); |
959 | ++n; |
960 | i = j; |
961 | } |
962 | |
963 | if ((tok.size() % 2) == 0) tok.add(""); |
964 | javaTok_elements += tok.size(); |
965 | return tok; |
966 | } |
967 | |
968 | static List<String> javaTok(List<String> tok) { |
969 | return javaTok(join(tok), tok); |
970 | } |
971 | |
972 | static boolean javaTok_isCopyable(String t, String s, int i, int j) { |
973 | return t.length() == j-i |
974 | && s.regionMatches(i, t, 0, j-i); // << could be left out, but that's brave |
975 | } |
976 | static String substring(String s, int x) { |
977 | return safeSubstring(s, x); |
978 | } |
979 | |
980 | static String substring(String s, int x, int y) { |
981 | return safeSubstring(s, x, y); |
982 | } |
983 | |
984 | // Data files are immutable, use centralized cache |
985 | public static File DiskSnippetCache_getLibrary(long snippetID) throws IOException { |
986 | File file = new File(getGlobalCache(), "data_" + snippetID + ".jar"); |
987 | return file.exists() ? file : null; |
988 | } |
989 | |
990 | public static void DiskSnippetCache_putLibrary(long snippetID, byte[] data) throws IOException { |
991 | saveBinaryFile(new File(getGlobalCache(), "data_" + snippetID).getPath() + ".jar", data); |
992 | } |
993 | |
994 | static byte[] loadDataSnippetImpl(String snippetID) throws IOException { |
995 | byte[] data; |
996 | try { |
997 | URL url = new URL("http://eyeocr.sourceforge.net/filestore/filestore.php?cmd=serve&file=blob_" |
998 | + parseSnippetID(snippetID) + "&contentType=application/binary"); |
999 | System.err.println("Loading library: " + url); |
1000 | try { |
1001 | data = loadBinaryPage(url.openConnection()); |
1002 | } catch (RuntimeException e) { |
1003 | data = null; |
1004 | } |
1005 | |
1006 | if (data == null || data.length == 0) { |
1007 | url = new URL("http://data.tinybrain.de/blobs/" |
1008 | + parseSnippetID(snippetID)); |
1009 | System.err.println("Loading library: " + url); |
1010 | data = loadBinaryPage(url.openConnection()); |
1011 | } |
1012 | System.err.println("Bytes loaded: " + data.length); |
1013 | } catch (FileNotFoundException e) { |
1014 | throw new IOException("Binary snippet #" + snippetID + " not found or not public"); |
1015 | } |
1016 | return data; |
1017 | } |
1018 | static String _userHome; |
1019 | static String userHome() { |
1020 | if (_userHome == null) { |
1021 | if (isAndroid()) |
1022 | _userHome = "/storage/sdcard0/"; |
1023 | else |
1024 | _userHome = System.getProperty("user.home"); |
1025 | //System.out.println("userHome: " + _userHome); |
1026 | } |
1027 | return _userHome; |
1028 | } |
1029 | |
1030 | static File userHome(String path) { |
1031 | return new File(userDir(), path); |
1032 | } |
1033 | static List emptyList() { |
1034 | return new ArrayList(); |
1035 | //ret Collections.emptyList(); |
1036 | } |
1037 | public static long parseSnippetID(String snippetID) { |
1038 | long id = Long.parseLong(shortenSnippetID(snippetID)); |
1039 | if (id == 0) throw fail("0 is not a snippet ID"); |
1040 | return id; |
1041 | } |
1042 | static Class getMainClass() { try { |
1043 | |
1044 | return Class.forName("main"); |
1045 | |
1046 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
1047 | |
1048 | static Class getMainClass(Object o) { try { |
1049 | |
1050 | return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main"); |
1051 | |
1052 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
1053 | static boolean nempty(Collection c) { |
1054 | return !isEmpty(c); |
1055 | } |
1056 | |
1057 | static boolean nempty(CharSequence s) { |
1058 | return !isEmpty(s); |
1059 | } |
1060 | |
1061 | static boolean nempty(Object[] o) { |
1062 | return !isEmpty(o); |
1063 | } |
1064 | |
1065 | static boolean nempty(Map m) { |
1066 | return !isEmpty(m); |
1067 | } |
1068 | |
1069 | static boolean nempty(Iterator i) { |
1070 | return i != null && i.hasNext(); |
1071 | } |
1072 | static int l(Object[] a) { return a == null ? 0 : a.length; } |
1073 | static int l(boolean[] a) { return a == null ? 0 : a.length; } |
1074 | static int l(byte[] a) { return a == null ? 0 : a.length; } |
1075 | static int l(int[] a) { return a == null ? 0 : a.length; } |
1076 | static int l(float[] a) { return a == null ? 0 : a.length; } |
1077 | static int l(char[] a) { return a == null ? 0 : a.length; } |
1078 | static int l(Collection c) { return c == null ? 0 : c.size(); } |
1079 | static int l(Map m) { return m == null ? 0 : m.size(); } |
1080 | static int l(CharSequence s) { return s == null ? 0 : s.length(); } |
1081 | |
1082 | static int l(Object o) { |
1083 | return l((List) o); // incomplete |
1084 | } |
1085 | |
1086 | static File getProgramDir() { |
1087 | return programDir(); |
1088 | } |
1089 | |
1090 | static File getProgramDir(String snippetID) { |
1091 | return programDir(snippetID); |
1092 | } |
1093 | static Object call(Object o) { |
1094 | return callFunction(o); |
1095 | } |
1096 | |
1097 | // varargs assignment fixer for a single string array argument |
1098 | static Object call(Object o, String method, String[] arg) { |
1099 | return call(o, method, new Object[] {arg}); |
1100 | } |
1101 | |
1102 | static Object call(Object o, String method, Object... args) { |
1103 | try { |
1104 | if (o instanceof Class) { |
1105 | Method m = call_findStaticMethod((Class) o, method, args, false); |
1106 | m.setAccessible(true); |
1107 | return m.invoke(null, args); |
1108 | } else { |
1109 | Method m = call_findMethod(o, method, args, false); |
1110 | m.setAccessible(true); |
1111 | return m.invoke(o, args); |
1112 | } |
1113 | } catch (Exception e) { |
1114 | throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); |
1115 | } |
1116 | } |
1117 | |
1118 | static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
1119 | Class _c = c; |
1120 | while (c != null) { |
1121 | for (Method m : c.getDeclaredMethods()) { |
1122 | if (debug) |
1123 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
1124 | if (!m.getName().equals(method)) { |
1125 | if (debug) System.out.println("Method name mismatch: " + method); |
1126 | continue; |
1127 | } |
1128 | |
1129 | if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug)) |
1130 | continue; |
1131 | |
1132 | return m; |
1133 | } |
1134 | c = c.getSuperclass(); |
1135 | } |
1136 | throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName()); |
1137 | } |
1138 | |
1139 | static Method call_findMethod(Object o, String method, Object[] args, boolean debug) { |
1140 | Class c = o.getClass(); |
1141 | while (c != null) { |
1142 | for (Method m : c.getDeclaredMethods()) { |
1143 | if (debug) |
1144 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
1145 | if (m.getName().equals(method) && call_checkArgs(m, args, debug)) |
1146 | return m; |
1147 | } |
1148 | c = c.getSuperclass(); |
1149 | } |
1150 | throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName()); |
1151 | } |
1152 | |
1153 | private static boolean call_checkArgs(Method m, Object[] args, boolean debug) { |
1154 | Class<?>[] types = m.getParameterTypes(); |
1155 | if (types.length != args.length) { |
1156 | if (debug) |
1157 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
1158 | return false; |
1159 | } |
1160 | for (int i = 0; i < types.length; i++) |
1161 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
1162 | if (debug) |
1163 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
1164 | return false; |
1165 | } |
1166 | return true; |
1167 | } |
1168 | |
1169 | |
1170 | static int parseInt(String s) { |
1171 | return empty(s) ? 0 : Integer.parseInt(s); |
1172 | } |
1173 | // hmm, this shouldn't call functions really. That was just |
1174 | // for coroutines. |
1175 | static boolean isTrue(Object o) { |
1176 | if (o instanceof Boolean) |
1177 | return ((Boolean) o).booleanValue(); |
1178 | if (o == null) return false; |
1179 | return ((Boolean) callF(o)).booleanValue(); |
1180 | } |
1181 | |
1182 | static boolean isTrue(Object pred, Object arg) { |
1183 | return booleanValue(callF(pred, arg)); |
1184 | } |
1185 | static Object getOpt(Object o, String field) { |
1186 | if (o instanceof String) o = getBot ((String) o); |
1187 | if (o == null) return null; |
1188 | if (o instanceof Class) return getOpt((Class) o, field); |
1189 | |
1190 | if (o.getClass().getName().equals("main$DynamicObject")) |
1191 | return ((Map) getOpt_raw(o, "fieldValues")).get(field); |
1192 | |
1193 | if (o instanceof Map) return ((Map) o).get(field); |
1194 | |
1195 | return getOpt_raw(o, field); |
1196 | } |
1197 | |
1198 | static Object getOpt_raw(Object o, String field) { |
1199 | try { |
1200 | Field f = getOpt_findField(o.getClass(), field); |
1201 | if (f == null) return null; |
1202 | f.setAccessible(true); |
1203 | return f.get(o); |
1204 | } catch (Exception e) { |
1205 | throw new RuntimeException(e); |
1206 | } |
1207 | } |
1208 | |
1209 | static Object getOpt(Class c, String field) { |
1210 | try { |
1211 | if (c == null) return null; |
1212 | Field f = getOpt_findStaticField(c, field); |
1213 | if (f == null) return null; |
1214 | f.setAccessible(true); |
1215 | return f.get(null); |
1216 | } catch (Exception e) { |
1217 | throw new RuntimeException(e); |
1218 | } |
1219 | } |
1220 | |
1221 | static Field getOpt_findStaticField(Class<?> c, String field) { |
1222 | Class _c = c; |
1223 | do { |
1224 | for (Field f : _c.getDeclaredFields()) |
1225 | if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) |
1226 | return f; |
1227 | _c = _c.getSuperclass(); |
1228 | } while (_c != null); |
1229 | return null; |
1230 | } |
1231 | |
1232 | static Field getOpt_findField(Class<?> c, String field) { |
1233 | Class _c = c; |
1234 | do { |
1235 | for (Field f : _c.getDeclaredFields()) |
1236 | if (f.getName().equals(field)) |
1237 | return f; |
1238 | _c = _c.getSuperclass(); |
1239 | } while (_c != null); |
1240 | return null; |
1241 | } |
1242 | static String boolArrayToHex(boolean[] a) { |
1243 | return bytesToHex(boolArrayToBytes(a)); |
1244 | } |
1245 | |
1246 | |
1247 | static Object callFunction(Object f, Object... args) { |
1248 | if (f == null) return null; |
1249 | if (f instanceof Runnable) { |
1250 | ((Runnable) f).run(); |
1251 | return null; |
1252 | } else if (f instanceof String) |
1253 | return call(mc(), (String) f, args); |
1254 | else |
1255 | return call(f, "get", args); |
1256 | //else throw fail("Can't call a " + getClassName(f)); |
1257 | } |
1258 | static boolean empty(Collection c) { |
1259 | return isEmpty(c); |
1260 | } |
1261 | |
1262 | static boolean empty(String s) { |
1263 | return isEmpty(s); |
1264 | } |
1265 | |
1266 | static boolean empty(Map map) { |
1267 | return map == null || map.isEmpty(); |
1268 | } |
1269 | |
1270 | static boolean empty(Object[] o) { |
1271 | return o == null || o.length == 0; |
1272 | } |
1273 | |
1274 | static boolean empty(Object o) { |
1275 | if (o instanceof Collection) return empty((Collection) o); |
1276 | if (o instanceof String) return empty((String) o); |
1277 | if (o instanceof Map) return empty((Map) o); |
1278 | if (o instanceof Object[]) return empty((Object[]) o); |
1279 | throw fail("unknown type for 'empty': " + getType(o)); |
1280 | } |
1281 | // hopefully covers all cases :) |
1282 | static String safeSubstring(String s, int x, int y) { |
1283 | if (s == null) return null; |
1284 | if (x < 0) x = 0; |
1285 | if (x > s.length()) return ""; |
1286 | if (y < x) y = x; |
1287 | if (y > s.length()) y = s.length(); |
1288 | return s.substring(x, y); |
1289 | } |
1290 | |
1291 | static String safeSubstring(String s, int x) { |
1292 | return safeSubstring(s, x, l(s)); |
1293 | } |
1294 | |
1295 | static RuntimeException asRuntimeException(Throwable t) { |
1296 | return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); |
1297 | } |
1298 | static Object getBot(String botID) { |
1299 | return callOpt(getMainBot(), "getBot", botID); |
1300 | } |
1301 | |
1302 | public static String join(String glue, Iterable<String> strings) { |
1303 | StringBuilder buf = new StringBuilder(); |
1304 | Iterator<String> i = strings.iterator(); |
1305 | if (i.hasNext()) { |
1306 | buf.append(i.next()); |
1307 | while (i.hasNext()) |
1308 | buf.append(glue).append(i.next()); |
1309 | } |
1310 | return buf.toString(); |
1311 | } |
1312 | |
1313 | public static String join(String glue, String[] strings) { |
1314 | return join(glue, Arrays.asList(strings)); |
1315 | } |
1316 | |
1317 | public static String join(Iterable<String> strings) { |
1318 | return join("", strings); |
1319 | } |
1320 | |
1321 | public static String join(String[] strings) { |
1322 | return join("", strings); |
1323 | } |
1324 | |
1325 | static String shortenSnippetID(String snippetID) { |
1326 | if (snippetID.startsWith("#")) |
1327 | snippetID = snippetID.substring(1); |
1328 | String httpBlaBla = "http://tinybrain.de/"; |
1329 | if (snippetID.startsWith(httpBlaBla)) |
1330 | snippetID = snippetID.substring(httpBlaBla.length()); |
1331 | return "" + parseLong(snippetID); |
1332 | } |
1333 | static byte[] boolArrayToBytes(boolean[] a) { |
1334 | byte[] b = new byte[(l(a)+7)/8]; |
1335 | for (int i = 0; i < l(a); i++) |
1336 | if (a[i]) |
1337 | b[i/8] |= 1 << (i & 7); |
1338 | return b; |
1339 | } |
1340 | static boolean booleanValue(Object o) { |
1341 | return eq(true, o); |
1342 | } |
1343 | static String quickSubstring(String s, int i, int j) { |
1344 | if (i == j) return ""; |
1345 | return s.substring(i, j); |
1346 | } |
1347 | static boolean isJavaIdentifier(String s) { |
1348 | if (s.length() == 0 || !Character.isJavaIdentifierStart(s.charAt(0))) |
1349 | return false; |
1350 | for (int i = 1; i < s.length(); i++) |
1351 | if (!Character.isJavaIdentifierPart(s.charAt(i))) |
1352 | return false; |
1353 | return true; |
1354 | } |
1355 | /** writes safely (to temp file, then rename) */ |
1356 | public static void saveBinaryFile(String fileName, byte[] contents) throws IOException { |
1357 | File file = new File(fileName); |
1358 | File parentFile = file.getParentFile(); |
1359 | if (parentFile != null) |
1360 | parentFile.mkdirs(); |
1361 | String tempFileName = fileName + "_temp"; |
1362 | FileOutputStream fileOutputStream = new FileOutputStream(tempFileName); |
1363 | fileOutputStream.write(contents); |
1364 | fileOutputStream.close(); |
1365 | if (file.exists() && !file.delete()) |
1366 | throw new IOException("Can't delete " + fileName); |
1367 | |
1368 | if (!new File(tempFileName).renameTo(file)) |
1369 | throw new IOException("Can't rename " + tempFileName + " to " + fileName); |
1370 | } |
1371 | |
1372 | static void saveBinaryFile(File fileName, byte[] contents) { |
1373 | try { |
1374 | saveBinaryFile(fileName.getPath(), contents); |
1375 | } catch (IOException e) { |
1376 | throw new RuntimeException(e); |
1377 | } |
1378 | } |
1379 | static Class __javax; |
1380 | |
1381 | static Class getJavaX() { |
1382 | return __javax; |
1383 | } |
1384 | static boolean isEmpty(Collection c) { |
1385 | return c == null || c.isEmpty(); |
1386 | } |
1387 | |
1388 | static boolean isEmpty(CharSequence s) { |
1389 | return s == null || s.length() == 0; |
1390 | } |
1391 | |
1392 | static boolean isEmpty(Object[] a) { |
1393 | return a == null || a.length == 0; |
1394 | } |
1395 | |
1396 | static boolean isEmpty(Map map) { |
1397 | return map == null || map.isEmpty(); |
1398 | } |
1399 | static byte[] loadBinaryPage(String url) { try { |
1400 | |
1401 | return loadBinaryPage(new URL(url).openConnection()); |
1402 | |
1403 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
1404 | |
1405 | public static byte[] loadBinaryPage(URLConnection con) { try { |
1406 | |
1407 | //setHeaders(con); |
1408 | ByteArrayOutputStream buf = new ByteArrayOutputStream(); |
1409 | InputStream inputStream = con.getInputStream(); |
1410 | int n = 0; |
1411 | while (true) { |
1412 | int ch = inputStream.read(); |
1413 | if (ch < 0) |
1414 | break; |
1415 | buf.write(ch); |
1416 | if (++n % 100000 == 0) |
1417 | System.err.println(" " + n + " bytes loaded."); |
1418 | } |
1419 | inputStream.close(); |
1420 | return buf.toByteArray(); |
1421 | |
1422 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
1423 | |
1424 | static File getGlobalCache() { |
1425 | File file = new File(userHome(), ".tinybrain/snippet-cache"); |
1426 | file.mkdirs(); |
1427 | return file; |
1428 | } |
1429 | |
1430 | static File userDir() { |
1431 | return new File(userHome()); |
1432 | } |
1433 | |
1434 | static File userDir(String path) { |
1435 | return new File(userHome(), path); |
1436 | } |
1437 | static boolean isAndroid() { return System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0; } |
1438 | |
1439 | |
1440 | static Object mc() { |
1441 | return getMainClass(); |
1442 | } |
1443 | static String getType(Object o) { |
1444 | return getClassName(o); |
1445 | } |
1446 | static Object mainBot; |
1447 | |
1448 | static Object getMainBot() { |
1449 | return mainBot; |
1450 | } |
1451 | static long parseLong(String s) { |
1452 | if (s == null) return 0; |
1453 | return Long.parseLong(dropSuffix("L", s)); |
1454 | } |
1455 | |
1456 | static long parseLong(Object s) { |
1457 | return Long.parseLong((String) s); |
1458 | } |
1459 | |
1460 | |
1461 | static String getClassName(Object o) { |
1462 | return o == null ? "null" : o.getClass().getName(); |
1463 | } |
1464 | static String dropSuffix(String suffix, String s) { |
1465 | return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s; |
1466 | } |
1467 | |
1468 | } |
1469 | |
1470 | !include #1005016 |
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1005029 |
Snippet name: | Mocha Doom Single Source With Translator |
Eternal ID of this version: | #1005029/1 |
Text MD5: | bd15c6305a8bdd33db8af921338fdc4d |
Author: | stefan |
Category: | javax |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-09-28 22:19:39 |
Source code size: | 44966 bytes / 1470 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 595 / 545 |
Referenced in: | [show references] |