You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/03/08 17:05:56 UTC

svn commit: r634996 - in /james/mime4j/trunk/src: main/java/org/apache/james/mime4j/ test/java/org/apache/james/mime4j/

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 {@link #getInputStream()}.
+     * Consult the javadoc for that method for known limitations.
+     * 
+     * @return <code>Reader</code>, not null
+     * @see #getInputStream 
+     * @throws IllegalStateException {@link #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 {@link #getState()} returns
      * {@link #T_BODY}, or {@link #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: <f4...@mail.gmail.com>\r\n" +
+    "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+    "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+    "To: \"James Developers List\" <se...@james.apache.org>\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: robertburrelldonkin@gmail.com\r\n" +
+    "\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: <f4...@mail.gmail.com>\r\n" +
+    "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+    "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+    "To: \"James Developers List\" <se...@james.apache.org>\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: robertburrelldonkin@gmail.com\r\n" +
+    "\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: <f4...@mail.gmail.com>\r\n" +
+    "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+    "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+    "To: \"James Developers List\" <se...@james.apache.org>\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: robertburrelldonkin@gmail.com\r\n" +
+    "\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: <f4...@mail.gmail.com>\r\n" +
+    "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+    "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+    "To: \"James Developers List\" <se...@james.apache.org>\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: robertburrelldonkin@gmail.com\r\n" +
+    "\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: <f4...@mail.gmail.com>\r\n" +
+    "Date: Thu, 6 Mar 2008 18:02:03 +0000\r\n" +
+    "From: \"Robert Burrell Donkin\" <ro...@gmail.com>\r\n" +
+    "To: \"James Developers List\" <se...@james.apache.org>\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: robertburrelldonkin@gmail.com\r\n" +
+    "\r\n" + breakLines(ONE_PART_MIME_QUOTED_PRINTABLE_ASCII_BODY.replaceAll("\r\n", "=0D=0A"));
+    
+    public static final String RFC_SIMPLE = 
+            "From: Timothy Tayler <ti...@example.org>\r\n" +
+            "To: Samual Smith <sa...@example.org>\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 <ti...@example.org>\r\n" +
+            "To: Samual Smith <sa...@example.org>\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: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org