+ private static final JSObject.JSFunction openFile = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args.length != 1) return null;
+ String file = Platform.fileDialog(args[0].toString(), false);
+ return file == null ? null : new ByteStream(file);
+ }
+ };
+
+ private static final JSObject.JSFunction saveFile = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args.length != 2) return null;
+ if (!(args[1] instanceof ByteStream)) return null;
+ String file = args[0].toString();
+ if (safeFiles.get(Platform.isCaseSensitive() ? file : file.toLowerCase()) == null) {
+ file = Platform.fileDialog(file, true);
+ if (file == null) return null;
+ safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object());
+ }
+ try {
+ ((ByteStream)args[1]).writeTo(new FileOutputStream(file));
+ return null;
+ } catch (IOException e) {
+ if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file");
+ if (Log.on) Log.log(ByteStream.class, e);
+ throw new JavaScriptException("error while writing a ByteStream to a file");
+ }
+ }
+ };
+
+ private static final JSObject.JSFunction saveFileAs = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args.length != 2) return null;
+ if (!(args[1] instanceof ByteStream)) return null;
+ String file = args[0].toString();
+ file = Platform.fileDialog(file, true);
+ if (file == null) return null;
+ safeFiles.put(Platform.isCaseSensitive() ? file : file.toLowerCase(), new Object());
+ try {
+ ((ByteStream)args[1]).writeTo(new FileOutputStream(file));
+ return null;
+ } catch (IOException e) {
+ if (Log.on) Log.log(ByteStream.class, "IO Exception while writing a ByteStream to a file");
+ if (Log.on) Log.log(ByteStream.class, e);
+ throw new JavaScriptException("error while writing a ByteStream to a file");
+ }
+ }
+ };
+
+ private static final JSObject.JSFunction utfEncode = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args == null || args.length != 1) return null;
+ return new ByteStream(args[0].toString().getBytes());
+ }
+ };
+
+
+ private static final JSObject.JSFunction parseHTML = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args == null || args.length != 1 || args[0] == null) return null;
+ try {
+ if (args[0] instanceof ByteStream) {
+ return HTML.parseReader(new InputStreamReader(((ByteStream)args[0]).getInputStream()));
+ } else {
+ return HTML.parseReader(new StringReader(args[0].toString()));
+ }
+ } catch (IOException e) {
+ if (Log.on) Log.log(HTML.class, "IO Exception while parsing HTML");
+ if (Log.on) Log.log(HTML.class, e);
+ throw new JavaScriptException("error while parsing HTML");
+ }
+ }
+ };
+
+ private static void recurse(String indent, String name, Object o, Context cx) {
+ if (!name.equals("")) name += " : ";
+
+ if (o == null) {
+ Log.log(cx.interpreterSourceFile, indent + name + "<null>");
+
+ } else if (o instanceof NativeArray) {
+ Log.log(cx.interpreterSourceFile, indent + name + "<array>");
+ NativeArray na = (NativeArray)o;
+ for(int i=0; i<na.jsGet_length(); i++)
+ recurse(indent + " ", i + "", na.get(i, null), cx);
+
+ } else if (!(o instanceof NativeDate) && (o instanceof JSObject || o instanceof ScriptableObject)) {
+ Log.log(cx.interpreterSourceFile, indent + name + "<object>");
+ Scriptable s = (Scriptable)o;
+ Object[] keys = s.getIds();
+ for(int i=0; i<keys.length; i++)
+ recurse(indent + " ", keys[i].toString(),
+ keys[i] instanceof Integer ? s.get(((Integer)keys[i]).intValue(), null) : s.get(keys[i].toString(), null), cx);
+
+ } else {
+ Log.log(cx.interpreterSourceFile, indent + name + o);
+
+ }
+ }
+
+ static final JSObject.JSFunction recursivePrintObject = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args == null || args.length != 1) return null;
+ recurse("", "", args[0], cx);
+ return null;
+ }
+ };
+
+ private static final JSObject.JSFunction loadArchive = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (!ThreadMessage.suspendThread()) return null;
+
+ try {
+ if (args == null || args.length < 1 || args[0] == null) return null;
+ URL u = new URL(args[0].toString());
+
+ Function callback = null;
+ if (args.length == 2 && args[1] != null && args[1] instanceof Function) callback = (Function)args[1];
+
+ if (!u.getFile().endsWith(".xwar")) {
+ if (Log.on) Log.log(this, "Error: archive names must end with .xwar: " + u.getFile());
+ throw new JavaScriptException("Error: archive names must end with .xwar: " + u.getFile());
+ }
+
+ if (u.getProtocol().equals("http")) {
+ HTTP http = new HTTP(u.toString());
+ if (Main.originAddr == null) {
+ try {
+ Main.originAddr = InetAddress.getByName(u.getHost());
+ } catch (UnknownHostException e) {
+ if (Log.on) Log.log(this, "couldn't resolve " + u.getHost() + "; proceeding without permissions");
+ Main.originAddr = InetAddress.getByName("0.0.0.0");
+ }
+ } else {
+ Main.originAddr = InetAddress.getByName("0.0.0.0");
+ }
+ HTTP.HTTPInputStream in = http.GET();
+ Resources.loadArchive(in, in.getContentLength(), callback);
+
+ } else if (u.getProtocol().equals("file")) {
+ if (Main.originAddr != null) {
+ if (Log.on) Log.log(this, "scripts downloaded from the network may not load xwars from the local filesystem");
+ throw new JavaScriptException("scripts downloaded from the network may not load xwars from the local filesystem");
+ }
+ Resources.loadArchive(new FileInputStream(u.getFile()), (int)new File(u.getFile()).length(), callback);
+
+ } else {
+ if (Log.on) Log.log(this, "unknown protocol \"" + u.getProtocol() + "\"");
+ throw new JavaScriptException("unknown protocol \"" + u.getProtocol() + "\"");
+ }
+
+ } catch (MalformedURLException me) {
+ if (Log.on) Log.log(this, "Malformed URL: " + args[0]);
+ if (Log.on) Log.log(this, me);
+ throw new JavaScriptException(me.toString());
+
+ } catch (IOException ioe) {
+ if (Log.on) Log.log(this, "IOException while loading archive:");
+ if (Log.on) Log.log(this, ioe);
+ throw new JavaScriptException(ioe.toString());
+
+ } finally {
+ ThreadMessage.resumeThread();
+
+ }
+ return null;
+ }
+ };
+
+ private static final JSObject.JSFunction prefetchImage = new JSObject.JSFunction() {
+ public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+ if (args == null || args.length < 1 || args[0] == null) return null;
+ Box.getImage(args[0].toString(), args.length > 1 && args[1] instanceof Function ? (Function)args[1] : null);
+ return null;
+ }
+ };
+