improve logic for header-stripping in MIME.java
[org.ibex.mail.git] / src / org / ibex / mail / MIME.java
index c8dce2a..477ce63 100644 (file)
@@ -19,44 +19,59 @@ import java.io.*;
 /** This class contains logic for encoding and decoding MIME multipart messages */
 public class MIME {
 
+    /** Part = Headers+Body */
     public static class Part extends JSReflection implements Fountain {
-        public  final  Headers      headers;
-        public  final  ContentType  contentType;
-        private final  String       encoding;
+        public  final Headers      headers;
+        public  final ContentType  contentType;
+        private final String       encoding;
 
         private final Fountain     all;
         private final Fountain     body;
 
-        public Stream getStream() { return all.getStream(); }
-        public int getNumLines()  { return all.getNumLines(); }
-        public int getLength()    { return all.getLength(); }
+        public Stream getStream()   { return all.getStream(); }
+        public int getNumLines()    { return all.getNumLines(); }
+        public long getLength()     { return all.getLength(); }
         public Fountain getBody()   { return body; }
 
-        private class BodyFountain implements Fountain {
-            public int getNumLines()  { return Stream.countLines(getStream()); }
-            public int getLength()    { return Part.this.getLength() - headers.getLength() - 2; }
-            public Stream getStream() {
-                return /*
-                         "quoted-printable".equals(encoding) ? Encode.QuotedPrintable.decode(body.toString(),false) :
-                         "base64".equals(encoding)           ? Encode.fromBase64(body.toString()) :
-                       */
-                    Headers.Original.skip(all.getStream());
+        public JS get(JS key) throws JSExn {
+            String k = JSU.toString(key);
+            if ("body".equals(k)) {
+                StringBuffer sb = new StringBuffer();
+                getBody().getStream().transcribe(sb);
+                return JSU.S(sb.toString());
             }
+            return super.get(key);
         }
 
-        public Part(Fountain all) {
-            this.headers     = new Headers.Original(all.getStream());
+        public Part(final Fountain fount, String[] keyval) {
+            Headers h        = new Headers(fount);
+            this.headers     = keyval==null ? h : new Headers(h, keyval);
             String ctype     = headers.get("content-type");
             this.encoding    = headers.get("content-transfer-encoding");
-            if (!(encoding == null || encoding.equals("7bit") || encoding.equals("8bit") || encoding.equals("binary") ||
-                  encoding.equals("quoted-printable") || encoding.equals("base64"))) {
-                // FIXME: "7BIT" is popular
+            String enc = this.encoding;
+            if (enc!=null) enc = enc.toLowerCase();
+            if (!(enc == null || enc.equals("7bit") || enc.equals("8bit") || enc.equals("binary") ||
+                  enc.equals("quoted-printable") || enc.equals("base64"))) {
                 Log.warn(MIME.class, "unknown TransferEncoding \"" + encoding + "\"");
                 ctype = "application/octet-stream";
             }
             this.contentType = new ContentType(ctype, headers.get("content-description"), headers.get("content-id"), encoding);
-            this.all = all;
-            this.body = new BodyFountain();
+            // FIXME: this is a horrible, tangled mess.
+            this.body = new Fountain() {
+                    public int getNumLines()  { return Stream.countLines(this.getStream()); }
+                    public long getLength()   { return Stream.countBytes(this.getStream()); }
+                    public Stream getStream() { return transformBodyStream(Headers.skip(fount.getStream())); }
+                };
+            this.all =
+                keyval==null
+                ? fount
+                : Fountain.Util.concat(this.headers, Fountain.Util.create("\r\n"), this.body);
+        }
+
+        private Stream transformBodyStream(Stream body) {
+            //"quoted-printable".equals(encoding) ? Encode.QuotedPrintable.decode(body.toString(),false) :
+            //"base64".equals(encoding)           ? Encode.fromBase64(body.toString()) :
+            return body;
         }
 
         /*
@@ -76,6 +91,7 @@ public class MIME {
         }
         */
     }
+
     /*
     public static class Boundary implements Stream.Transformer {
         private final String boundary;