-package javajs.util;\r
-\r
-import java.io.BufferedWriter;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.io.OutputStreamWriter;\r
-\r
-\r
-\r
-import javajs.J2SIgnoreImport;\r
-import javajs.api.BytePoster;\r
-import javajs.api.JmolObjectInterface;\r
-\r
-/**\r
- * \r
- * A generic output method. JmolOutputChannel can be used to:\r
- * \r
- * add characters to a StringBuffer \r
- * using fileName==null, append() and toString()\r
- * \r
- * add bytes utilizing ByteArrayOutputStream \r
- * using writeBytes(), writeByteAsInt(), append()*, and bytesAsArray()\r
- * *append() can be used as long as os==ByteArrayOutputStream\r
- * or it is not used before one of the writeByte methods. \r
- * \r
- * output characters to a FileOutputStream \r
- * using os==FileOutputStream, asWriter==true, append(), and closeChannel()\r
- * \r
- * output bytes to a FileOutputStream \r
- * using os==FileOutputStream, writeBytes(), writeByteAsInt(), append(), and closeChannel()\r
- * \r
- * post characters or bytes to a remote server\r
- * using fileName=="http://..." or "https://...",\r
- * writeBytes(), writeByteAsInt(), append(), and closeChannel()\r
- * \r
- * send characters or bytes to a JavaScript function\r
- * when JavaScript and (typeof fileName == "function")\r
- * \r
- * if fileName equals ";base64,", then the data are base64-encoded\r
- * prior to writing, and closeChannel() returns the data.\r
- * \r
- * @author hansonr Bob Hanson hansonr@stolaf.edu 9/2013\r
- * \r
- * \r
- */\r
-\r
-@J2SIgnoreImport({ java.io.FileOutputStream.class })\r
-public class OC extends OutputStream {\r
- \r
- private BytePoster bytePoster; // only necessary for writing to http:// or https://\r
- private String fileName;\r
- private BufferedWriter bw;\r
- private boolean isLocalFile;\r
- private int byteCount;\r
- private boolean isCanceled;\r
- private boolean closed;\r
- private OutputStream os;\r
- private SB sb;\r
- private String type;\r
- private boolean isBase64;\r
- private OutputStream os0;\r
- private byte[] bytes; // preset bytes; output only\r
- \r
- public OC setParams(BytePoster bytePoster, String fileName,\r
- boolean asWriter, OutputStream os) {\r
- this.bytePoster = bytePoster;\r
- this.fileName = fileName;\r
- isBase64 = ";base64,".equals(fileName);\r
- if (isBase64) {\r
- fileName = null;\r
- os0 = os;\r
- os = null;\r
- }\r
- this.os = os;\r
- isLocalFile = (fileName != null && !isRemote(fileName));\r
- if (asWriter && !isBase64 && os != null)\r
- bw = new BufferedWriter(new OutputStreamWriter(os));\r
- return this;\r
- }\r
-\r
- public OC setBytes(byte[] b) {\r
- bytes = b;\r
- return this;\r
- }\r
- \r
- public String getFileName() {\r
- return fileName;\r
- }\r
- \r
- public String getName() {\r
- return (fileName == null ? null : fileName.substring(fileName.lastIndexOf("/") + 1));\r
- }\r
-\r
- public int getByteCount() {\r
- return byteCount;\r
- }\r
-\r
- /**\r
- * \r
- * @param type user-identified type (PNG, JPG, etc)\r
- */\r
- public void setType(String type) {\r
- this.type = type;\r
- }\r
- \r
- public String getType() {\r
- return type;\r
- }\r
-\r
- /**\r
- * will go to string buffer if bw == null and os == null\r
- * \r
- * @param s\r
- * @return this, for chaining like a standard StringBuffer\r
- * \r
- */\r
- public OC append(String s) {\r
- try {\r
- if (bw != null) {\r
- bw.write(s);\r
- } else if (os == null) {\r
- if (sb == null)\r
- sb = new SB();\r
- sb.append(s);\r
- } else {\r
- byte[] b = s.getBytes();\r
- os.write(b, 0, b.length);\r
- byteCount += b.length;\r
- return this;\r
- }\r
- } catch (IOException e) {\r
- // ignore\r
- }\r
- byteCount += s.length(); // not necessarily exactly correct if unicode\r
- return this;\r
- }\r
-\r
- public void reset() {\r
- sb = null;\r
- initOS();\r
- }\r
-\r
-\r
- private void initOS() {\r
- if (sb != null) {\r
- String s = sb.toString();\r
- reset();\r
- append(s);\r
- return;\r
- }\r
- try {\r
- /**\r
- * @j2sNative\r
- * \r
- * this.os = null;\r
- */\r
- {\r
- if (os instanceof FileOutputStream) {\r
- os.close();\r
- os = new FileOutputStream(fileName);\r
- } else {\r
- os = null;\r
- }\r
- }\r
- if (os == null)\r
- os = new ByteArrayOutputStream();\r
- if (bw != null) {\r
- bw.close();\r
- bw = new BufferedWriter(new OutputStreamWriter(os));\r
- }\r
- } catch (Exception e) {\r
- // not perfect here.\r
- System.out.println(e.toString());\r
- }\r
- byteCount = 0;\r
- }\r
-\r
- /**\r
- * @j2sOverride\r
- */\r
- @Override\r
- public void write(byte[] buf, int i, int len) {\r
- if (os == null)\r
- initOS();\r
- try {\r
- os.write(buf, i, len);\r
- } catch (IOException e) {\r
- }\r
- byteCount += len;\r
- }\r
- \r
- /**\r
- * @param b \r
- */\r
- public void writeByteAsInt(int b) {\r
- if (os == null)\r
- initOS();\r
- /**\r
- * @j2sNative\r
- * \r
- * this.os.writeByteAsInt(b);\r
- * \r
- */\r
- {\r
- try {\r
- os.write(b);\r
- } catch (IOException e) {\r
- }\r
- }\r
- byteCount++;\r
- }\r
- \r
- /**\r
- * Will break JavaScript if used.\r
- * \r
- * @j2sIgnore\r
- * \r
- * @param b\r
- */\r
- @Override\r
- @Deprecated\r
- public void write(int b) {\r
- // required by standard ZipOutputStream -- do not use, as it will break JavaScript methods\r
- if (os == null)\r
- initOS();\r
- try {\r
- os.write(b);\r
- } catch (IOException e) {\r
- }\r
- byteCount++;\r
- }\r
-\r
-// /**\r
-// * Will break if used; no equivalent in JavaScript.\r
-// * \r
-// * @j2sIgnore\r
-// * \r
-// * @param b\r
-// */\r
-// @Override\r
-// @Deprecated\r
-// public void write(byte[] b) {\r
-// // not used in JavaScript due to overloading problem there\r
-// write(b, 0, b.length);\r
-// }\r
-\r
- public void cancel() {\r
- isCanceled = true;\r
- closeChannel();\r
- }\r
-\r
- @SuppressWarnings({ "null", "unused" })\r
- public String closeChannel() {\r
- if (closed)\r
- return null;\r
- // can't cancel file writers\r
- try {\r
- if (bw != null) {\r
- bw.flush();\r
- bw.close();\r
- } else if (os != null) {\r
- os.flush();\r
- os.close();\r
- }\r
- if (os0 != null && isCanceled) {\r
- os0.flush();\r
- os0.close();\r
- }\r
- } catch (Exception e) {\r
- // ignore closing issues\r
- }\r
- if (isCanceled) {\r
- closed = true;\r
- return null;\r
- }\r
- if (fileName == null) {\r
- if (isBase64) {\r
- String s = getBase64();\r
- if (os0 != null) {\r
- os = os0;\r
- append(s);\r
- }\r
- sb = new SB();\r
- sb.append(s);\r
- isBase64 = false;\r
- return closeChannel();\r
- }\r
- return (sb == null ? null : sb.toString());\r
- }\r
- closed = true;\r
- JmolObjectInterface jmol = null;\r
- Object _function = null;\r
- /**\r
- * @j2sNative\r
- * \r
- * jmol = Jmol; _function = (typeof this.fileName == "function" ?\r
- * this.fileName : null);\r
- * \r
- */\r
- {\r
- if (!isLocalFile) {\r
- String ret = postByteArray(); // unsigned applet could do this\r
- if (ret.startsWith("java.net"))\r
- byteCount = -1;\r
- return ret;\r
- }\r
- }\r
- if (jmol != null) {\r
- Object data = (sb == null ? toByteArray() : sb.toString());\r
- if (_function == null)\r
- jmol._doAjax(fileName, null, data);\r
- else\r
- jmol._apply(fileName, data);\r
- }\r
- return null;\r
- }\r
-\r
- public boolean isBase64() {\r
- return isBase64;\r
- }\r
-\r
- public String getBase64() {\r
- return Base64.getBase64(toByteArray()).toString();\r
- }\r
- \r
- public byte[] toByteArray() {\r
- return (bytes != null ? bytes : os instanceof ByteArrayOutputStream ? ((ByteArrayOutputStream)os).toByteArray() : null);\r
- }\r
-\r
- @Override\r
- @Deprecated\r
- public void close() {\r
- closeChannel();\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- if (bw != null)\r
- try {\r
- bw.flush();\r
- } catch (IOException e) {\r
- // TODO\r
- }\r
- if (sb != null)\r
- return closeChannel();\r
- return byteCount + " bytes";\r
- }\r
-\r
- private String postByteArray() {\r
- byte[] bytes = (sb == null ? toByteArray() : sb.toString().getBytes());\r
- return bytePoster.postByteArray(fileName, bytes);\r
- }\r
-\r
- public final static String[] urlPrefixes = { "http:", "https:", "sftp:", "ftp:",\r
- "file:" };\r
- // note that SFTP is not supported\r
- public final static int URL_LOCAL = 4;\r
-\r
- public static boolean isRemote(String fileName) {\r
- if (fileName == null)\r
- return false;\r
- int itype = urlTypeIndex(fileName);\r
- return (itype >= 0 && itype != URL_LOCAL);\r
- }\r
-\r
- public static boolean isLocal(String fileName) {\r
- if (fileName == null)\r
- return false;\r
- int itype = urlTypeIndex(fileName);\r
- return (itype < 0 || itype == URL_LOCAL);\r
- }\r
-\r
- public static int urlTypeIndex(String name) {\r
- if (name == null)\r
- return -2; // local unsigned applet\r
- for (int i = 0; i < urlPrefixes.length; ++i) {\r
- if (name.startsWith(urlPrefixes[i])) {\r
- return i;\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
-}\r
+package javajs.util;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+
+
+import javajs.J2SIgnoreImport;
+import javajs.api.BytePoster;
+import javajs.api.JmolObjectInterface;
+
+/**
+ *
+ * A generic output method. JmolOutputChannel can be used to:
+ *
+ * add characters to a StringBuffer
+ * using fileName==null, append() and toString()
+ *
+ * add bytes utilizing ByteArrayOutputStream
+ * using writeBytes(), writeByteAsInt(), append()*, and bytesAsArray()
+ * *append() can be used as long as os==ByteArrayOutputStream
+ * or it is not used before one of the writeByte methods.
+ *
+ * output characters to a FileOutputStream
+ * using os==FileOutputStream, asWriter==true, append(), and closeChannel()
+ *
+ * output bytes to a FileOutputStream
+ * using os==FileOutputStream, writeBytes(), writeByteAsInt(), append(), and closeChannel()
+ *
+ * post characters or bytes to a remote server
+ * using fileName=="http://..." or "https://...",
+ * writeBytes(), writeByteAsInt(), append(), and closeChannel()
+ *
+ * send characters or bytes to a JavaScript function
+ * when JavaScript and (typeof fileName == "function")
+ *
+ * if fileName equals ";base64,", then the data are base64-encoded
+ * prior to writing, and closeChannel() returns the data.
+ *
+ * @author hansonr Bob Hanson hansonr@stolaf.edu 9/2013
+ *
+ *
+ */
+
+@J2SIgnoreImport({ java.io.FileOutputStream.class })
+public class OC extends OutputStream {
+
+ private BytePoster bytePoster; // only necessary for writing to http:// or https://
+ private String fileName;
+ private BufferedWriter bw;
+ private boolean isLocalFile;
+ private int byteCount;
+ private boolean isCanceled;
+ private boolean closed;
+ private OutputStream os;
+ private SB sb;
+ private String type;
+ private boolean isBase64;
+ private OutputStream os0;
+ private byte[] bytes; // preset bytes; output only
+
+ public OC setParams(BytePoster bytePoster, String fileName,
+ boolean asWriter, OutputStream os) {
+ this.bytePoster = bytePoster;
+ this.fileName = fileName;
+ isBase64 = ";base64,".equals(fileName);
+ if (isBase64) {
+ fileName = null;
+ os0 = os;
+ os = null;
+ }
+ this.os = os;
+ isLocalFile = (fileName != null && !isRemote(fileName));
+ if (asWriter && !isBase64 && os != null)
+ bw = new BufferedWriter(new OutputStreamWriter(os));
+ return this;
+ }
+
+ public OC setBytes(byte[] b) {
+ bytes = b;
+ return this;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public String getName() {
+ return (fileName == null ? null : fileName.substring(fileName.lastIndexOf("/") + 1));
+ }
+
+ public int getByteCount() {
+ return byteCount;
+ }
+
+ /**
+ *
+ * @param type user-identified type (PNG, JPG, etc)
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * will go to string buffer if bw == null and os == null
+ *
+ * @param s
+ * @return this, for chaining like a standard StringBuffer
+ *
+ */
+ public OC append(String s) {
+ try {
+ if (bw != null) {
+ bw.write(s);
+ } else if (os == null) {
+ if (sb == null)
+ sb = new SB();
+ sb.append(s);
+ } else {
+ byte[] b = s.getBytes();
+ os.write(b, 0, b.length);
+ byteCount += b.length;
+ return this;
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ byteCount += s.length(); // not necessarily exactly correct if unicode
+ return this;
+ }
+
+ public void reset() {
+ sb = null;
+ initOS();
+ }
+
+
+ private void initOS() {
+ if (sb != null) {
+ String s = sb.toString();
+ reset();
+ append(s);
+ return;
+ }
+ try {
+ /**
+ * @j2sNative
+ *
+ * this.os = null;
+ */
+ {
+ if (os instanceof FileOutputStream) {
+ os.close();
+ os = new FileOutputStream(fileName);
+ } else {
+ os = null;
+ }
+ }
+ if (os == null)
+ os = new ByteArrayOutputStream();
+ if (bw != null) {
+ bw.close();
+ bw = new BufferedWriter(new OutputStreamWriter(os));
+ }
+ } catch (Exception e) {
+ // not perfect here.
+ System.out.println(e.toString());
+ }
+ byteCount = 0;
+ }
+
+ /**
+ * @j2sOverride
+ */
+ @Override
+ public void write(byte[] buf, int i, int len) {
+ if (os == null)
+ initOS();
+ try {
+ os.write(buf, i, len);
+ } catch (IOException e) {
+ }
+ byteCount += len;
+ }
+
+ /**
+ * @param b
+ */
+ public void writeByteAsInt(int b) {
+ if (os == null)
+ initOS();
+ /**
+ * @j2sNative
+ *
+ * this.os.writeByteAsInt(b);
+ *
+ */
+ {
+ try {
+ os.write(b);
+ } catch (IOException e) {
+ }
+ }
+ byteCount++;
+ }
+
+ /**
+ * Will break JavaScript if used.
+ *
+ * @j2sIgnore
+ *
+ * @param b
+ */
+ @Override
+ @Deprecated
+ public void write(int b) {
+ // required by standard ZipOutputStream -- do not use, as it will break JavaScript methods
+ if (os == null)
+ initOS();
+ try {
+ os.write(b);
+ } catch (IOException e) {
+ }
+ byteCount++;
+ }
+
+// /**
+// * Will break if used; no equivalent in JavaScript.
+// *
+// * @j2sIgnore
+// *
+// * @param b
+// */
+// @Override
+// @Deprecated
+// public void write(byte[] b) {
+// // not used in JavaScript due to overloading problem there
+// write(b, 0, b.length);
+// }
+
+ public void cancel() {
+ isCanceled = true;
+ closeChannel();
+ }
+
+ @SuppressWarnings({ "null", "unused" })
+ public String closeChannel() {
+ if (closed)
+ return null;
+ // can't cancel file writers
+ try {
+ if (bw != null) {
+ bw.flush();
+ bw.close();
+ } else if (os != null) {
+ os.flush();
+ os.close();
+ }
+ if (os0 != null && isCanceled) {
+ os0.flush();
+ os0.close();
+ }
+ } catch (Exception e) {
+ // ignore closing issues
+ }
+ if (isCanceled) {
+ closed = true;
+ return null;
+ }
+ if (fileName == null) {
+ if (isBase64) {
+ String s = getBase64();
+ if (os0 != null) {
+ os = os0;
+ append(s);
+ }
+ sb = new SB();
+ sb.append(s);
+ isBase64 = false;
+ return closeChannel();
+ }
+ return (sb == null ? null : sb.toString());
+ }
+ closed = true;
+ JmolObjectInterface jmol = null;
+ Object _function = null;
+ /**
+ * @j2sNative
+ *
+ * jmol = Jmol; _function = (typeof this.fileName == "function" ?
+ * this.fileName : null);
+ *
+ */
+ {
+ if (!isLocalFile) {
+ String ret = postByteArray(); // unsigned applet could do this
+ if (ret.startsWith("java.net"))
+ byteCount = -1;
+ return ret;
+ }
+ }
+ if (jmol != null) {
+ Object data = (sb == null ? toByteArray() : sb.toString());
+ if (_function == null)
+ jmol._doAjax(fileName, null, data);
+ else
+ jmol._apply(fileName, data);
+ }
+ return null;
+ }
+
+ public boolean isBase64() {
+ return isBase64;
+ }
+
+ public String getBase64() {
+ return Base64.getBase64(toByteArray()).toString();
+ }
+
+ public byte[] toByteArray() {
+ return (bytes != null ? bytes : os instanceof ByteArrayOutputStream ? ((ByteArrayOutputStream)os).toByteArray() : null);
+ }
+
+ @Override
+ @Deprecated
+ public void close() {
+ closeChannel();
+ }
+
+ @Override
+ public String toString() {
+ if (bw != null)
+ try {
+ bw.flush();
+ } catch (IOException e) {
+ // TODO
+ }
+ if (sb != null)
+ return closeChannel();
+ return byteCount + " bytes";
+ }
+
+ private String postByteArray() {
+ byte[] bytes = (sb == null ? toByteArray() : sb.toString().getBytes());
+ return bytePoster.postByteArray(fileName, bytes);
+ }
+
+ public final static String[] urlPrefixes = { "http:", "https:", "sftp:", "ftp:",
+ "file:" };
+ // note that SFTP is not supported
+ public final static int URL_LOCAL = 4;
+
+ public static boolean isRemote(String fileName) {
+ if (fileName == null)
+ return false;
+ int itype = urlTypeIndex(fileName);
+ return (itype >= 0 && itype != URL_LOCAL);
+ }
+
+ public static boolean isLocal(String fileName) {
+ if (fileName == null)
+ return false;
+ int itype = urlTypeIndex(fileName);
+ return (itype < 0 || itype == URL_LOCAL);
+ }
+
+ public static int urlTypeIndex(String name) {
+ if (name == null)
+ return -2; // local unsigned applet
+ for (int i = 0; i < urlPrefixes.length; ++i) {
+ if (name.startsWith(urlPrefixes[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+}