/** 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;
- public Stream getStream() { return all.getStream(); }
- public int getNumLines() { return all.getNumLines(); }
- public int getLength() { return all.getLength(); }
+ private final Fountain body;
- public Stream getBody() {
- return /*
- "quoted-printable".equals(encoding) ? Encode.QuotedPrintable.decode(body.toString(),false) :
- "base64".equals(encoding) ? Encode.fromBase64(body.toString()) :
- */
- Headers.skip(getStream());
+ public Stream getStream() { return all.getStream(); }
+ public int getNumLines() { return all.getNumLines(); }
+ public long getLength() { return all.getLength(); }
+ public Fountain getBody() { return body; }
+
+ 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(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"))) {
+ 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;
+ // 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;
}
/*
}
*/
}
+
/*
public static class Boundary implements Stream.Transformer {
private final String boundary;