+ private static String stripContinuationCRLF(String value) {
+ int length = value.length();
+ StringBuffer result = new StringBuffer(length);
+ boolean lastWasLF = false;
+ for (int i = 0; i < length; i++) {
+ if (lastWasLF) {
+ lastWasLF = false;
+ continue;
+ }
+ char c = value.charAt(i);
+ lastWasLF = false;
+ switch (c) {
+ case '\n':
+ lastWasLF = true;
+ break;
+ case '\r':
+ break;
+ default:
+ result.append(c);
+ }
+ }
+ return result.toString();
+ }
+
+ private static String decodeQuotedPrintable(String value, String charset) {
+ int length = value.length();
+ StringBuffer result = new StringBuffer(length);
+ ByteArrayOutputStream fragmentBuffer = new ByteArrayOutputStream();
+ for (int i = 0; i < length; i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '\r':
+ case '\n':
+ break;
+ case '=':
+ if (i < length - 2) {
+ char nextChar = value.charAt(i+1);
+ if (nextChar == '\r' || nextChar == '\n') {
+ // Ignore, it's just a continuation symbol
+ } else {
+ char nextNextChar = value.charAt(i+2);
+ try {
+ int encodedByte = 16 * toHexValue(nextChar) + toHexValue(nextNextChar);
+ fragmentBuffer.write(encodedByte);
+ } catch (IllegalArgumentException iae) {
+ // continue, assume it was incorrectly encoded
+ }
+ i += 2;
+ }
+ }
+ break;
+ default:
+ maybeAppendFragment(fragmentBuffer, charset, result);
+ result.append(c);
+ }
+ }
+ maybeAppendFragment(fragmentBuffer, charset, result);
+ return result.toString();
+ }
+
+ private static int toHexValue(char c) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ } else if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ private static void maybeAppendFragment(ByteArrayOutputStream fragmentBuffer,
+ String charset,
+ StringBuffer result) {
+ if (fragmentBuffer.size() > 0) {
+ byte[] fragmentBytes = fragmentBuffer.toByteArray();
+ String fragment;
+ if (charset == null) {
+ fragment = new String(fragmentBytes);
+ } else {
+ try {
+ fragment = new String(fragmentBytes, charset);
+ } catch (UnsupportedEncodingException e) {
+ // Yikes, well try anyway:
+ fragment = new String(fragmentBytes);
+ }
+ }
+ fragmentBuffer.reset();
+ result.append(fragment);
+ }
+ }
+