2002/05/29 23:54:51
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 06:47:42 +0000 (06:47 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 06:47:42 +0000 (06:47 +0000)
darcs-hash:20040130064742-2ba56-740c8300dd4dcc39fb2903dbd50f2efb6e138b5d.gz

src/org/xwt/ByteStream.java [new file with mode: 0644]

diff --git a/src/org/xwt/ByteStream.java b/src/org/xwt/ByteStream.java
new file mode 100644 (file)
index 0000000..cd3982a
--- /dev/null
@@ -0,0 +1,146 @@
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.xwt;
+import java.io.*;
+import java.util.*;
+import org.xwt.util.*;
+import org.mozilla.javascript.*;
+
+/** A ByteStream encapsulates a <i>source</i> of a stream of bytes --
+ *  currently either a local file or a Base64-encoded XMLRPC/SOAP element */
+
+public class ByteStream extends JSObject {
+
+    private byte[] bytes = null;
+    private File file = null;
+
+    private ByteStream() { setSeal(true); }
+
+    public String toString() { return "ByteStream, source=" + file.getAbsolutePath(); }
+    public String getClassName() { return "ByteStream"; }
+
+    ByteStream(String filename) {
+        this();
+        this.file = new File(filename);
+    }
+
+    ByteStream(byte[] bytes) {
+        this();
+        this.bytes = bytes;
+    }
+
+    public Object get(String name, Scriptable start) {
+        if (name == null) return null;
+        else if (name.equals("getUTF")) return getUTF;
+        else if (name.equals("getDOM")) return getDOM;
+        else if (name.equals("fileName")) return file == null ? null : file.getAbsolutePath();
+        else return null;
+    }
+
+    /** Helper class for defining functions. */
+    private abstract class JSFunction extends JSObject implements Function {
+        JSFunction() { this.setSeal(true); }
+        public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; }
+    }
+
+    private class XMLHelper extends XML {
+        Vector obStack = new Vector();
+
+        public void startElement(String name, String[] keys, Object[] vals, int line, int col) throws SAXException {
+            JSObject o = new JSObject();
+            o.put("$name", null, name);
+            for(int i=0; i<keys.length; i++) o.put(keys[i], null, vals[i]);
+            o.put("$numchildren", null, new Integer(0));
+            obStack.addElement(o);
+        }
+
+        public void endElement(String name, int line, int col) throws SAXException {
+            if (obStack.size() == 1) return;
+            JSObject me = (JSObject)obStack.lastElement();
+            obStack.setSize(obStack.size() - 1);
+            JSObject parent = (JSObject)obStack.lastElement();
+            int numchildren = ((Integer)parent.get("$numchildren", null)).intValue();
+            parent.put("$numchildren", null, new Integer(numchildren + 1));
+            parent.put(numchildren, null, me);
+        }
+
+        public void content(char[] content, int start, int length, int line, int col) throws SAXException {
+            String s = new String(content, start, length);
+            JSObject parent = (JSObject)obStack.lastElement();
+            int numchildren = ((Integer)parent.get("$numchildren", null)).intValue();
+            Object lastChild = parent.get(numchildren - 1, null);
+            if (lastChild instanceof String) {
+                parent.put(numchildren - 1, null, lastChild + s);
+            } else {
+                parent.put("$numchildren", null, new Integer(numchildren + 1));
+                parent.put(numchildren, null, s);
+            }
+        }
+
+        public Scriptable doParse() throws JavaScriptException {
+            try { 
+                InputStream is = getInputStream();
+                BufferedReader r = new BufferedReader(new InputStreamReader(is));
+                parse(r);
+            } catch (XML.SAXException e) {
+                throw new JavaScriptException("error parsing XML: " + e.toString());
+            } catch (IOException e) {
+                if (Log.on) Log.log(ByteStream.class, "IO Exception while reading from file");
+                if (Log.on) Log.log(ByteStream.class, e);
+                throw new JavaScriptException("error reading from ByteStream");
+            }
+            return obStack.size() >= 1 ? (Scriptable)obStack.elementAt(0) : null;
+        }
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return file == null ?
+            (InputStream)(new ByteArrayInputStream(bytes)) :
+            (InputStream)(new FileInputStream(file));
+    }
+
+    public void writeTo(OutputStream os) throws IOException {
+        InputStream is = getInputStream();
+        byte[] buf = new byte[1024];
+        while(true) {
+            int numread = is.read(buf, 0, 1024);
+            if (numread == -1) break;
+            if (Log.on) Log.log(this, "wrote " + numread + " bytes");
+            os.write(buf, 0, numread);
+        }
+        os.flush();
+
+        // we have to close this because flush() doesn't work on Win32-GCJ
+        os.close();
+    }
+
+    private final JSFunction getDOM = new JSFunction() {
+            public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+                if (args.length != 0) return null;
+                return new XMLHelper().doParse();
+            }
+        };
+
+    private final JSFunction getUTF = new JSFunction() {
+            public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+                if (args.length != 0) return null;
+                try {
+                    CharArrayWriter caw = new CharArrayWriter();
+                    InputStream is = getInputStream();
+                    BufferedReader r = new BufferedReader(new InputStreamReader(is));
+                    char[] buf = new char[1024];
+                    while(true) {
+                        int numread = r.read(buf, 0, 1024);
+                        if (numread == -1) break;
+                        caw.write(buf, 0, numread);
+                    }
+                    return caw.toString();
+                } catch (IOException e) {
+                    if (Log.on) Log.log(ByteStream.class, "IO Exception while reading from file");
+                    if (Log.on) Log.log(ByteStream.class, e);
+                    throw new JavaScriptException("error while reading from ByteStream");
+                }
+            }
+        };
+
+}
+