Author: rdonkin
Date: Sat Mar 8 08:05:56 2008
New Revision: 634996
URL: http://svn.apache.org/viewvc?rev=634996&view=rev
Log:
Added getReader a conveniance method that returns a correct configured reader
suitable for decoding bodies.
Added:
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java?rev=634996&r1=634995&r2=634996&view=diff
==============================================================================
---
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
(original)
+++
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/MimeTokenStream.java
Sat Mar 8 08:05:56 2008
@@ -21,12 +21,17 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
import org.apache.james.mime4j.util.MimeUtil;
@@ -777,6 +782,47 @@
return currentStateMachine.read();
}
+ /**
+ * Gets a reader configured for the current body or body part.
+ * The reader will return a transfer and charset decoded
+ * stream of characters based on the MIME fields with the standard
+ * defaults.
+ * This is a conveniance method and relies on [EMAIL PROTECTED]
#getInputStream()}.
+ * Consult the javadoc for that method for known limitations.
+ *
+ * @return <code>Reader</code>, not null
+ * @see #getInputStream
+ * @throws IllegalStateException [EMAIL PROTECTED] #getState()} returns an
+ * invalid value
+ * @throws UnsupportedCharsetException if there is no JVM support
+ * for decoding the charset
+ * @throws IllegalCharsetNameException if the charset name specified
+ * in the mime type is illegal
+ */
+ public Reader getReader() {
+ final BodyDescriptor bodyDescriptor = getBodyDescriptor();
+ final String mimeCharset = bodyDescriptor.getCharset();
+ final String transferEncoding = bodyDescriptor.getTransferEncoding();
+ final Charset charset;
+ if (mimeCharset == null || "".equals(mimeCharset)) {
+ charset = Charset.forName("US-ASCII");
+ } else {
+ charset = Charset.forName(mimeCharset);
+ }
+
+ final InputStream inputStream;
+ final InputStream transferEncodedStream = getInputStream();
+ if (MimeUtil.isBase64Encoding(transferEncoding)) {
+ inputStream = new Base64InputStream(transferEncodedStream);
+ } else if (MimeUtil.isQuotedPrintableEncoded(transferEncoding)) {
+ inputStream = new
QuotedPrintableInputStream(transferEncodedStream);
+ } else {
+ inputStream = transferEncodedStream;
+ }
+ final InputStreamReader result = new InputStreamReader(inputStream,
charset);
+ return result;
+ }
+
/**
* This method is valid, if [EMAIL PROTECTED] #getState()} returns
* [EMAIL PROTECTED] #T_BODY}, or [EMAIL PROTECTED] #T_START_MULTIPART}.
It returns the current
Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java?rev=634996&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
(added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
Sat Mar 8 08:05:56 2008
@@ -0,0 +1,111 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.mime4j;
+
+
+public class EncodeUtils {
+
+ public static final int MASK = 0x3F;
+ public static final int FIRST_MASK = MASK << 18;
+ public static final int SECOND_MASK = MASK << 12;
+ public static final int THIRD_MASK = MASK << 6;
+ public static final int FORTH_MASK = MASK;
+
+ public static final byte[] ENCODING = {'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P' ,'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'};
+
+ public static final void main(String[] args) throws Exception {
+ byte[] bytes = {(byte) 0, (byte) 128, (byte) 0};
+ System.out.println(new String(toBase64(bytes)));
+ System.out.println(new String(toBase64("Hello, World".getBytes())));
+ System.out.println(new String(toBase64("Monday".getBytes())));
+ System.out.println(new
String(toBase64("M\u00F6nchengladbach\r\n".getBytes("ISO-8859-1"))));
+ }
+
+ public static byte[] toBase64(byte[] in) {
+ int inputLength = in.length;
+ int outputLength = (int) Math.floor((4*inputLength) / 3f) + 3;
+ outputLength = outputLength + 2 * (int) Math.floor(outputLength / 76f);
+ byte[] results = new byte[outputLength];
+ int inputIndex = 0;
+ int outputIndex = 0;
+ while (inputLength - inputIndex > 2) {
+ int one = (toInt(in[inputIndex++]) << 16);
+ int two = (toInt(in[inputIndex++]) << 8);
+ int three = toInt(in[inputIndex++]);
+ int quantum = one | two | three;
+ int index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & THIRD_MASK) >> 6;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & FORTH_MASK);
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ }
+
+ switch (inputLength - inputIndex) {
+ case 1:
+ int quantum = in[inputIndex++] << 16;
+ int index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ outputIndex = setResult(results, outputIndex, (byte) '=');
+ outputIndex = setResult(results, outputIndex, (byte) '=');
+ break;
+
+ case 2:
+ quantum = (in[inputIndex++] << 16) + (in[inputIndex++] << 8);
+ index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ index = (quantum & THIRD_MASK) >> 6;
+ outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ outputIndex = setResult(results, outputIndex, (byte) '=');
+ break;
+ }
+
+ return results;
+ }
+
+ private static int toInt(byte b) {
+ return (int)(b & 255);
+ }
+
+
+ private static int setResult(byte[] results, int outputIndex, byte value) {
+ results[outputIndex++] = value;
+ outputIndex = checkLineLength(results, outputIndex);
+ return outputIndex;
+ }
+
+
+ private static int checkLineLength(byte[] results, int outputIndex) {
+ if (outputIndex == 76 || outputIndex > 76 && (outputIndex -
2*Math.floor(outputIndex/76f - 1)) % 76 == 0) {
+ results[outputIndex++] = '\r';
+ results[outputIndex++] = '\n';
+ }
+ return outputIndex;
+ }
+}
Added: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java?rev=634996&view=auto
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
(added)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
Sat Mar 8 08:05:56 2008
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.james.mime4j;
+
+import java.nio.charset.Charset;
+
+public class ExampleMail {
+
+ public static final Charset US_ASCII = Charset.forName("US-ASCII");
+ public static final Charset LATIN1 = Charset.forName("ISO-8859-1");
+
+ public static final String ONE_PART_MIME_ASCII_BODY = "A single part MIME
mail.\r\n";
+
+ public static final String RFC822_SIMPLE_BODY = "This is a very simple
email.\r\n";
+
+ public static final String ONE_PART_MIME_8859_BODY =
"M\u00F6nchengladbach\r\n";
+
+ public static final String ONE_PART_MIME_BASE64_LATIN1_BODY = "Hello
Mo\u00F6nchengladbach\r\n";
+
+ public static final String ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY =
"Sonnet LXXXI By William Shakespeare\r\n" +
+ "Or I shall live your epitaph to make,\r\n" +
+ "Or you survive when I in earth am rotten;\r\n" +
+ "From hence your memory death cannot take,\r\n" +
+ "Although in me each part will be forgotten.\r\n" +
+ "Your name from hence immortal life shall have,\r\n" +
+ "Though I, once gone, to all the world must die:\r\n" +
+ "The earth can yield me but a common grave,\r\n" +
+ "When you entombed in men's eyes shall lie.\r\n" +
+ "Your monument shall be my gentle verse,\r\n" +
+ "Which eyes not yet created shall o'er-read;\r\n" +
+ "And tongues to be, your being shall rehearse,\r\n" +
+ "When all the breathers of this world are dead;\r\n" +
+ " You still shall live,--such virtue hath my pen,--\r\n" +
+ " Where breath most breathes, even in the mouths of men.\r\n";
+
+ private static final byte[] ONE_PART_MIME_BASE64_LATIN1_ENCODED =
EncodeUtils.toBase64(latin1(ONE_PART_MIME_BASE64_LATIN1_BODY));
+
+ public static final String ONE_PART_MIME_BASE64_ASCII_BODY = "Hello,
World!\r\n";
+
+ private static final byte[] ONE_PART_MIME_BASE64_ASCII_ENCODED =
EncodeUtils.toBase64(ascii(ONE_PART_MIME_BASE64_ASCII_BODY));
+
+ public static final String ONE_PART_MIME_ASCII = "Received: by
10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <[EMAIL PROTECTED]>\r\n" +
+ "To: \"James Developers List\" <[email protected]>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: 7bit\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: [EMAIL PROTECTED]" +
+ "\r\n" +
+ ONE_PART_MIME_ASCII_BODY;
+
+ public static final String ONE_PART_MIME_8859 = "Received: by
10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <[EMAIL PROTECTED]>\r\n" +
+ "To: \"James Developers List\" <[email protected]>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
+ "Content-Transfer-Encoding: 8bit\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: [EMAIL PROTECTED]" +
+ "\r\n" +
+ ONE_PART_MIME_8859_BODY;
+
+ public static final String ONE_PART_MIME_BASE64_ASCII_HEADERS = "Received:
by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800 (PST)\r\n" +
+ "Message-ID: <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <[EMAIL PROTECTED]>\r\n" +
+ "To: \"James Developers List\" <[email protected]>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: [EMAIL PROTECTED]" +
+ "\r\n";
+
+ public static final String ONE_PART_MIME_BASE64_LATIN1_HEADERS =
"Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800
(PST)\r\n" +
+ "Message-ID: <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <[EMAIL PROTECTED]>\r\n" +
+ "To: \"James Developers List\" <[email protected]>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: [EMAIL PROTECTED]" +
+ "\r\n";
+
+ public static final String ONE_PART_MIME_QUOTED_PRINTABLE_ASCII =
"Received: by 10.114.126.16 with HTTP; Thu, 6 Mar 2008 10:02:03 -0800
(PST)\r\n" +
+ "Message-ID: <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+ "From: \"Robert Burrell Donkin\" <[EMAIL PROTECTED]>\r\n" +
+ "To: \"James Developers List\" <[email protected]>\r\n" +
+ "Subject: [Mime4J] getReader\r\n" +
+ "MIME-Version: 1.0\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: Quoted-Printable\r\n" +
+ "Content-Disposition: inline\r\n" +
+ "Delivered-To: [EMAIL PROTECTED]" +
+ "\r\n" +
breakLines(ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY.replaceAll("\r\n",
"=0D=0A"));
+
+ public static final String RFC_SIMPLE =
+ "From: Timothy Tayler <[EMAIL PROTECTED]>\r\n" +
+ "To: Samual Smith <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 14 Feb 2008 12:00:00 +0000 (GMT)\r\n" +
+ "Subject: A Simple Email\r\n" +
+ "\r\n" +
+ RFC822_SIMPLE_BODY;
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_7BIT =
"Sonnet XXXIII By William Shakespeare\r\n" +
+ "\r\n" +
+ "Full many a glorious morning have I seen\r\n" +
+ "Flatter the mountain tops with sovereign eye,\r\n" +
+ "Kissing with golden face the meadows green,\r\n" +
+ "Gilding pale streams with heavenly alchemy;\r\n" +
+ "Anon permit the basest clouds to ride\r\n" +
+ "With ugly rack on his celestial face,\r\n" +
+ "And from the forlorn world his visage hide,\r\n" +
+ "Stealing unseen to west with this disgrace:\r\n" +
+ "Even so my sun one early morn did shine,\r\n" +
+ "With all triumphant splendour on my brow;\r\n" +
+ "But out! alack! he was but one hour mine,\r\n" +
+ "The region cloud hath mask'd him from me now.\r\n" +
+ " Yet him for this my love no whit disdaineth;\r\n" +
+ " Suns of the world may stain when heaven's sun staineth.\r\n";
+
+ public static final String
MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_QUOTED_PRINTABLE = "Sonnet XXXV By
William Shakespeare\r\n" +
+ "\r\n" +
+ "No more be griev'd at that which thou hast done:\r\n" +
+ "Roses have thorns, and silver fountains mud:\r\n" +
+ "Clouds and eclipses stain both moon and sun,\r\n" +
+ "And loathsome canker lives in sweetest bud.\r\n" +
+ "All men make faults, and even I in this,\r\n" +
+ "Authorizing thy trespass with compare,\r\n" +
+ "Myself corrupting, salving thy amiss,\r\n" +
+ "Excusing thy sins more than thy sins are;\r\n" +
+ "For to thy sensual fault I bring in sense,--\r\n" +
+ "Thy adverse party is thy advocate,--\r\n" +
+ "And 'gainst myself a lawful plea commence:\r\n" +
+ "Such civil war is in my love and hate,\r\n" +
+ " That I an accessary needs must be,\r\n" +
+ " To that sweet thief which sourly robs from me.\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BASE64 =
"Sonnet XXXVIII By William Shakespeare\r\n" +
+ "\r\n" +
+ "How can my muse want subject to invent,\r\n" +
+ "While thou dost breathe, that pour'st into my verse\r\n" +
+ "Thine own sweet argument, too excellent\r\n" +
+ "For every vulgar paper to rehearse?\r\n" +
+ "O! give thy self the thanks, if aught in me\r\n" +
+ "Worthy perusal stand against thy sight;\r\n" +
+ "For who's so dumb that cannot write to thee,\r\n" +
+ "When thou thy self dost give invention light?\r\n" +
+ "Be thou the tenth Muse, ten times more in worth\r\n" +
+ "Than those old nine which rhymers invocate;\r\n" +
+ "And he that calls on thee, let him bring forth\r\n" +
+ "Eternal numbers to outlive long date.\r\n" +
+ " If my slight muse do please these curious days,\r\n" +
+ " The pain be mine, but thine shall be the praise.\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_ONE =
+ "From: Timothy Tayler <[EMAIL PROTECTED]>\r\n" +
+ "To: Samual Smith <[EMAIL PROTECTED]>\r\n" +
+ "Date: Thu, 14 Feb 2008 12:00:00 +0000 (GMT)\r\n" +
+ "Subject: A Multipart Email\r\n" +
+ "Content-Type: multipart/mixed;boundary=1729\r\n" +
+ "\r\n" +
+ "Start with a preamble\r\n" +
+ "\r\n" +
+ "--1729\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: 7bit\r\n\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_TWO =
+ "\r\n--1729\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: Quoted-Printable\r\n\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_THREE =
+ "\r\n--1729\r\n" +
+ "Content-Type: text/plain; charset=US-ASCII\r\n" +
+ "Content-Transfer-Encoding: base64\r\n\r\n";
+
+ public static final String MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_END =
+ "\r\n--1729--\r\n";
+
+ private static final byte[][]
MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTE_ARRAYS = {
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_ONE),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_7BIT),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_TWO),
+
ascii(breakLines(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_QUOTED_PRINTABLE.replaceAll("\r\n",
"=0D=0A"))),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_THREE),
+
EncodeUtils.toBase64(ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BASE64)),
+ ascii(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_END),
+ };
+ public static final byte[] MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTES =
join(MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTE_ARRAYS);
+ public static final byte[] ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BYTES =
ascii(ONE_PART_MIME_QUOTED_PRINTABLE_ASCII);
+ public static final byte[] ONE_PART_MIME_BASE64_LATIN1_BYTES =
join(ascii(ONE_PART_MIME_BASE64_LATIN1_HEADERS),
ONE_PART_MIME_BASE64_LATIN1_ENCODED);
+ public static final byte[] ONE_PART_MIME_BASE64_ASCII_BYTES =
join(ascii(ONE_PART_MIME_BASE64_ASCII_HEADERS),
ONE_PART_MIME_BASE64_ASCII_ENCODED);
+ public static final byte[] RFC822_SIMPLE_BYTES =
US_ASCII.encode(RFC_SIMPLE).array();
+ public static final byte[] ONE_PART_MIME_ASCII_BYTES =
US_ASCII.encode(ONE_PART_MIME_ASCII).array();
+ public static final byte[] ONE_PART_MIME_8859_BYTES =
LATIN1.encode(ONE_PART_MIME_8859).array();
+
+ public static final byte[] ascii(String text) {
+
+ return US_ASCII.encode(text).array();
+ }
+
+ public static final byte[] latin1(String text) {
+
+ return LATIN1.encode(text).array();
+ }
+
+ public static final byte[] join(byte[] one, byte[] two) {
+ byte[] results = new byte[one.length + two.length];
+ System.arraycopy(one, 0, results, 0, one.length);
+ System.arraycopy(two, 0, results, one.length, two.length);
+ return results;
+ }
+
+ public static final byte[] join(byte[][] byteArrays) {
+ int length = 0;
+ for (int i = 0; i < byteArrays.length; i++) {
+ byte[] bytes = byteArrays[i];
+ length += bytes.length;
+ }
+ byte[] results = new byte[length];
+ int count = 0;
+ for (int i = 0; i < byteArrays.length; i++) {
+ byte[] bytes = byteArrays[i];
+ System.arraycopy(bytes, 0, results, count, bytes.length);
+ count += bytes.length;
+ }
+ return results;
+ }
+
+ public static String breakLines(String original) {
+ StringBuffer buffer = new StringBuffer(original);
+ int count = 76;
+ while(count < buffer.length()) {
+ if (buffer.charAt(count) == '=') {
+ count = count - 1;
+ } else if (buffer.charAt(count-1) == '=') {
+ count = count - 4;
+ } else if (buffer.charAt(count-2) == '=') {
+ count = count - 3;
+ }
+ buffer.insert(count, '\n');
+ buffer.insert(count, '\r');
+ buffer.insert(count, '=');
+ count += 79;
+ }
+ final String result = buffer.toString();
+ return result;
+ }
+}
Added:
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java?rev=634996&view=auto
==============================================================================
---
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java
(added)
+++
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/MimeTokenStreamReaderTest.java
Sat Mar 8 08:05:56 2008
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.james.mime4j;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.apache.commons.io.IOUtils;
+
+import junit.framework.TestCase;
+
+public class MimeTokenStreamReaderTest extends TestCase {
+
+ MimeTokenStream parser;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parser = new MimeTokenStream();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testShouldReadSimpleBody() throws Exception {
+ byte[] bytes = ExampleMail.RFC822_SIMPLE_BYTES;
+ String body = ExampleMail.RFC822_SIMPLE_BODY;
+ checkSimpleMail(bytes, body, 4);
+ }
+
+ public void testShouldReadOnePartMimeASCIIBody() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_ASCII_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_ASCII_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMime8859Body() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_8859_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_8859_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMimeBase64ASCIIBody() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_BASE64_ASCII_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_BASE64_ASCII_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMimeBase64Latin1Body() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_BASE64_LATIN1_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_BASE64_LATIN1_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadOnePartMimeQuotedPrintable() throws Exception {
+ byte[] bytes = ExampleMail.ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BYTES;
+ String body = ExampleMail.ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY;
+ checkSimpleMail(bytes, body, 11);
+ }
+
+ public void testShouldReadPartBodies() throws IOException, MimeException {
+ InputStream in = new
ByteArrayInputStream(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BYTES);
+ parser.parse(in);
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ for (int i=0;i<5;i++) {
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ }
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_MULTIPART),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_PREAMBLE),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_7BIT);
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+
checkBody(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_QUOTED_PRINTABLE);
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(ExampleMail.MIME_MIXED_MULTIPART_VARIOUS_ENCODINGS_BASE64);
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_BODYPART),MimeTokenStream.stateToString(parser.next()));
+
+
+ }
+
+ private void checkSimpleMail(byte[] bytes, String body, int fields) throws
IOException, MimeException {
+ InputStream in = new ByteArrayInputStream(bytes);
+ parser.parse(in);
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_START_HEADER),MimeTokenStream.stateToString(parser.next()));
+ for (int i=0;i<fields;i++) {
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_FIELD),MimeTokenStream.stateToString(parser.next()));
+ }
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_END_HEADER),MimeTokenStream.stateToString(parser.next()));
+
assertEquals(MimeTokenStream.stateToString(MimeTokenStream.T_BODY),MimeTokenStream.stateToString(parser.next()));
+ checkBody(body);
+ }
+
+ private void checkBody(String body) throws IOException {
+ Reader reader = parser.getReader();
+ assertNotNull(reader);
+ assertEquals(body, IOUtils.toString(reader));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]