Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / www / mime / MultipartInputStream.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/mime/MultipartInputStream.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/mime/MultipartInputStream.java
new file mode 100644 (file)
index 0000000..355bfbc
--- /dev/null
@@ -0,0 +1,216 @@
+// MultipartInputStream.java\r
+// $Id: MultipartInputStream.java,v 1.1 2010/06/15 12:26:32 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.www.mime ;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+/**\r
+ * A class to handle multipart MIME input streams. See RC 1521.\r
+ * This class handles multipart input streams, as defined by the RFC 1521. \r
+ * It prvides a sequential interface to all MIME parts, and for each part\r
+ * it delivers a suitable InputStream for getting its body.\r
+ */\r
+\r
+public class MultipartInputStream extends InputStream {\r
+    InputStream in         = null;\r
+    byte        boundary[] = null ;\r
+    byte        buffer[]   = null ;\r
+    boolean     partEnd    = false ;\r
+    boolean     fileEnd    = false ;\r
+\r
+    // Read boundary bytes of input in buffer\r
+    // Return true if enough bytes available, false otherwise.\r
+\r
+    private final boolean readBoundaryBytes() \r
+       throws IOException\r
+    {\r
+       int pos = 0;\r
+       while ( pos < buffer.length ) {\r
+           int got = in.read(buffer, pos, buffer.length-pos);\r
+           if ( got < 0 ) \r
+               return false;\r
+           pos += got;\r
+       }\r
+       return true;\r
+    }\r
+\r
+    // Skip to next input boundary, set stream at begining of content:\r
+    // Returns true if boundary was found, false otherwise.\r
+\r
+    protected boolean skipToBoundary() \r
+       throws IOException\r
+    {\r
+       int ch = in.read() ;\r
+      skip:\r
+       while ( ch != -1 ) {\r
+           if ( ch != '-' ) {\r
+               ch = in.read() ;\r
+               continue ;\r
+           }\r
+           if ((ch = in.read()) != '-') \r
+               continue ;\r
+           in.mark(boundary.length) ;\r
+           if ( ! readBoundaryBytes() ) {\r
+               in.reset();\r
+               ch = in.read();\r
+               continue skip;\r
+           }\r
+           for (int i = 0 ; i < boundary.length ; i++) {\r
+               if ( buffer[i] != boundary[i] ) {\r
+                   in.reset() ;\r
+                   ch = in.read() ;\r
+                   continue skip ;\r
+               }\r
+           }\r
+           // FIXME: should we check for a properly syntaxed part, which\r
+           // means that we should expect '\r\n'. For now, we just skip\r
+           // as much as we can.\r
+           if ( (ch = in.read()) == '\r' ) {\r
+               ch = in.read() ;\r
+           } \r
+           in.mark(3);\r
+           if( in.read() == '-' )   {      // check fileEnd!\r
+               if( in.read() == '\r' && in.read() == '\n' )   {\r
+                   fileEnd = true ;\r
+                   return false ;\r
+               }\r
+           }\r
+           in.reset();\r
+           return true ;\r
+       }\r
+       fileEnd = true ;\r
+       return false ;\r
+    }\r
+\r
+    /**\r
+     * Read one byte of data from the current part.\r
+     * @return A byte of data, or <strong>-1</strong> if end of file.\r
+     * @exception IOException If some IO error occured.\r
+     */\r
+\r
+    public int read()\r
+       throws IOException \r
+    {\r
+       int ch ;\r
+       if ( partEnd )\r
+           return -1 ;\r
+       switch (ch = in.read()) {\r
+         case '\r':\r
+             // check for a boundary \r
+             in.mark(boundary.length+3) ;\r
+             int c1 = in.read() ;\r
+             int c2 = in.read() ;\r
+             int c3 = in.read() ;\r
+             if ((c1 == '\n') && (c2 == '-') && (c3 == '-')) {\r
+                 if ( ! readBoundaryBytes() ) {\r
+                     in.reset();\r
+                     return ch;\r
+                 }\r
+                 for (int i = 0 ; i < boundary.length ; i++) {\r
+                     if ( buffer[i] != boundary[i] ) {\r
+                         in.reset() ;\r
+                         return ch ;\r
+                     }\r
+                 }\r
+                 partEnd = true ;\r
+                 if ( (ch = in.read()) == '\r' ) {\r
+                     in.read() ;\r
+                 } else if (ch == '-') {\r
+                     // FIXME, check the second hyphen\r
+                     if (in.read() == '-')\r
+                         fileEnd = true ;\r
+                 } else {\r
+                     fileEnd = (ch == -1);\r
+                 }\r
+                 return -1 ;\r
+             } else {\r
+                 in.reset () ;\r
+                 return ch ;\r
+             }\r
+             // not reached\r
+         case -1:\r
+             fileEnd = true ;\r
+             return -1 ;\r
+         default:\r
+             return ch ;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Read n bytes of data from the current part.\r
+     * @return the number of bytes data, read or <strong>-1</strong> \r
+     * if end of file.\r
+     * @exception IOException If some IO error occured.\r
+     */\r
+    public int read (byte b[], int off, int len)\r
+       throws IOException \r
+    {\r
+       int got = 0 ;\r
+       int ch ;\r
+\r
+       while ( got < len ) {\r
+           if ((ch = read()) == -1)\r
+               return (got == 0) ? -1 : got ;\r
+           b[off+(got++)] = (byte) (ch & 0xFF) ;\r
+       }\r
+       return got ;\r
+    }\r
+\r
+    public long skip (long n) \r
+       throws IOException \r
+    {\r
+       while ((--n >= 0) && (read() != -1))\r
+           ;\r
+       return n ;\r
+    }\r
+\r
+    public int available ()\r
+       throws IOException\r
+    {\r
+       return in.available();\r
+    }\r
+\r
+    /**\r
+     * Switch to the next available part of data.\r
+     * One can interrupt the current part, and use this method to switch\r
+     * to next part before current part was totally read.\r
+     * @return A boolean <strong>true</strong> if there next partis ready,\r
+     * or <strong>false</strong> if this was the last part.\r
+     */\r
+\r
+    public boolean nextInputStream() \r
+       throws IOException\r
+    {\r
+       if ( fileEnd ) {\r
+           return false ;\r
+       }\r
+       if ( ! partEnd ) { \r
+           return skipToBoundary() ;\r
+       } else {\r
+           partEnd = false ;\r
+           return true ;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Construct a new multipart input stream.\r
+     * @param in The initial (multipart) input stream.\r
+     * @param boundary The input stream MIME boundary.\r
+     */\r
+\r
+    public MultipartInputStream (InputStream in, byte boundary[]) {\r
+       this.in       = (in.markSupported() \r
+                        ? in \r
+                        : new BufferedInputStream(in, boundary.length+4));\r
+       this.boundary = boundary ;\r
+       this.buffer   = new byte[boundary.length] ;\r
+       this.partEnd  = false ;\r
+       this.fileEnd  = false ;\r
+    }\r
+\r
+}\r