Author: mwiederkehr
Date: Fri Jan 23 12:36:57 2009
New Revision: 737178
URL: http://svn.apache.org/viewvc?rev=737178&view=rev
Log:
MIME4J-100: move code to encode a Content-Type parameter value to class
EncoderUtil
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/codec/EncoderUtil.java
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/codec/EncoderUtilTest.java
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/codec/EncoderUtil.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/codec/EncoderUtil.java?rev=737178&r1=737177&r2=737178&view=diff
==============================================================================
---
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/codec/EncoderUtil.java
(original)
+++
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/codec/EncoderUtil.java
Fri Jan 23 12:36:57 2009
@@ -21,12 +21,14 @@
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
+import java.util.BitSet;
import org.apache.james.mime4j.util.CharsetUtil;
/**
- * Static methods for encoding encoded-words as defined in <a
- * href='http://www.faqs.org/rfcs/rfc2047.html'>RFC 2047</a>.
+ * Static methods for encoding header field values. This includes encoded-words
+ * as defined in <a href='http://www.faqs.org/rfcs/rfc2047.html'>RFC 2047</a>
+ * or display-names of an e-mail address, for example.
*/
public class EncoderUtil {
private static final byte[] BASE64_TABLE = Base64OutputStream.BASE64_TABLE;
@@ -50,6 +52,18 @@
private static final int ENCODED_WORD_MAX_LENGTH = 75; // RFC 2047
+ private static final BitSet TOKEN_CHARS = initChars("()<>@,;:\\\"/[]?=");
+
+ private static BitSet initChars(String specials) {
+ BitSet bs = new BitSet(128);
+ for (char ch = 33; ch < 127; ch++) {
+ if (specials.indexOf(ch) == -1) {
+ bs.set(ch);
+ }
+ }
+ return bs;
+ }
+
/**
* Selects one of the two encodings specified in RFC 2047.
*/
@@ -81,6 +95,24 @@
}
/**
+ * Encodes the specified string as a value of a Content-Type parameter as
+ * described in RFC 2045 section 5.1. The specified string should not
+ * contain any illegal (control or non-ASCII) characters.
+ *
+ * @param value
+ * string to encode.
+ * @return encoded result.
+ */
+ public static String encodeContentTypeParameterValue(String value) {
+ // value := token / quoted-string
+ if (isToken(value)) {
+ return value;
+ } else {
+ return quote(value);
+ }
+ }
+
+ /**
* Shortcut method that encodes the specified text into an encoded-word if
* the text has to be encoded.
*
@@ -323,6 +355,35 @@
return sb.toString();
}
+ // RFC 2045 section 5.1
+ private static boolean isToken(String str) {
+ // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>
+ // tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" /
+ // <"> / "/" / "[" / "]" / "?" / "="
+ // CTL := 0.- 31., 127.
+
+ final int length = str.length();
+ for (int idx = 0; idx < length; idx++) {
+ char ch = str.charAt(idx);
+ if (!TOKEN_CHARS.get(ch))
+ return false;
+ }
+ return true;
+ }
+
+ // RFC 5322 section 3.2.4
+ private static String quote(String str) {
+ // quoted-string = [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
+ // qcontent = qtext / quoted-pair
+ // qtext = %d33 / %d35-91 / %d93-126
+ // quoted-pair = ("\" (VCHAR / WSP))
+ // VCHAR = %x21-7E
+ // DQUOTE = %x22
+
+ String escaped = str.replaceAll("[\\\\\"]", "\\\\$0");
+ return "\"" + escaped + "\"";
+ }
+
private static String encodeB(String prefix, String text,
int usedCharacters, Charset charset, byte[] bytes) {
int encodedLength = bEncodedLength(bytes);
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java?rev=737178&r1=737177&r2=737178&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
(original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/field/Fields.java
Fri Jan 23 12:36:57 2009
@@ -22,7 +22,6 @@
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
-import java.util.BitSet;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
@@ -34,18 +33,6 @@
public class Fields {
- private static final BitSet TOKEN_CHARS;
-
- static {
- final String specials = "()<>@,;:\\\"/[]?=";
- TOKEN_CHARS = new BitSet(128);
- for (char ch = 33; ch < 127; ch++) {
- if (specials.indexOf(ch) == -1) {
- TOKEN_CHARS.set(ch);
- }
- }
- }
-
private Fields() {
}
@@ -66,7 +53,7 @@
sb.append("; ");
sb.append(entry.getKey());
sb.append('=');
- sb.append(encodeValue(entry.getValue()));
+
sb.append(EncoderUtil.encodeContentTypeParameterValue(entry.getValue()));
}
String contentType = sb.toString();
return contentType(contentType);
@@ -117,40 +104,6 @@
return (UnstructuredField) Field.parse(Field.SUBJECT, rawValue);
}
- // value := token / quoted-string
- private static String encodeValue(String value) {
- if (isToken(value)) {
- return value;
- } else {
- return quote(value);
- }
- }
-
- // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>
- // tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" / <"> /
- // "/" / "[" / "]" / "?" / "="
- // CTL := 0.- 31., 127.
- private static boolean isToken(String str) {
- final int length = str.length();
- for (int idx = 0; idx < length; idx++) {
- char ch = str.charAt(idx);
- if (!TOKEN_CHARS.get(ch))
- return false;
- }
- return true;
- }
-
- // quoted-string = [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
- // qcontent = qtext / quoted-pair
- // qtext = %d33 / %d35-91 / %d93-126
- // quoted-pair = ("\" (VCHAR / WSP))
- // VCHAR = %x21-7E
- // DQUOTE = %x22
- private static String quote(String str) {
- String escaped = str.replaceAll("[\\\"]", "\\\\$0");
- return "\"" + escaped + "\"";
- }
-
private static final ThreadLocal<DateFormat> RFC822_DATE_FORMAT = new
ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
Modified:
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/codec/EncoderUtilTest.java
URL:
http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/codec/EncoderUtilTest.java?rev=737178&r1=737177&r2=737178&view=diff
==============================================================================
---
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/codec/EncoderUtilTest.java
(original)
+++
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/codec/EncoderUtilTest.java
Fri Jan 23 12:36:57 2009
@@ -30,6 +30,19 @@
public class EncoderUtilTest extends TestCase {
+ public void testEncodeContentTypeParameterValue() throws Exception {
+ assertEquals("test", EncoderUtil
+ .encodeContentTypeParameterValue("test"));
+ assertEquals("\"test test\"", EncoderUtil
+ .encodeContentTypeParameterValue("test test"));
+ assertEquals("\"=test\"", EncoderUtil
+ .encodeContentTypeParameterValue("=test"));
+ assertEquals("\"\\\\test\"", EncoderUtil
+ .encodeContentTypeParameterValue("\\test"));
+ assertEquals("\"\\\"\\\\\\\"\"", EncoderUtil
+ .encodeContentTypeParameterValue("\"\\\""));
+ }
+
public void testHasToBeEncoded() throws Exception {
assertFalse(EncoderUtil.hasToBeEncoded("", 0));
assertFalse(EncoderUtil.hasToBeEncoded("only ascii characters", 0));
@@ -57,8 +70,8 @@
public void testEncodeEncodedWordForceCharset() throws Exception {
assertTrue(EncoderUtil.encodeEncodedWord("only ascii",
- Usage.TEXT_TOKEN, 0, CharsetUtil.UTF_8, null)
- .startsWith("=?UTF-8?"));
+ Usage.TEXT_TOKEN, 0, CharsetUtil.UTF_8, null).startsWith(
+ "=?UTF-8?"));
}
public void testEncodeEncodedWordDetectEncoding() throws Exception {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]