1 36 package org.columba.ristretto.coder; 37 38 import java.io.UnsupportedEncodingException ; 39 import java.nio.ByteBuffer ; 40 import java.nio.CharBuffer ; 41 import java.nio.charset.Charset ; 42 import java.util.logging.Logger ; 43 import java.util.regex.Matcher ; 44 import java.util.regex.Pattern ; 45 46 54 public class QuotedPrintable { 55 56 57 private static final Logger LOG = Logger.getLogger("org.columba.ristretto.coder"); 58 59 60 private static final char[] hexTable = 61 { 62 '0', 63 '1', 64 '2', 65 '3', 66 '4', 67 '5', 68 '6', 69 '7', 70 '8', 71 '9', 72 'A', 73 'B', 74 'C', 75 'D', 76 'E', 77 'F' }; 78 79 private static final Pattern packPattern = 80 Pattern.compile("=([0-9a-fA-F\r][0-9a-fA-F\n])"); 81 82 90 public static CharSequence decode(CharSequence input, Charset charset) { 91 ByteBuffer buffer = ByteBuffer.allocate(input.length()); 92 Matcher matcher = packPattern.matcher(input); 93 int lastMatchEnd = 0; 94 String group; 95 96 98 while (matcher.find()) { 99 try { 100 buffer.put(input.subSequence(lastMatchEnd, matcher.start()).toString().getBytes("US-ASCII")); 102 } catch (UnsupportedEncodingException e) { 103 LOG.severe(e.getMessage()); 105 } 106 group = matcher.group(1); 107 if (!group.equals("\r\n")) { 108 buffer.put((byte) Integer.parseInt(group, 16)); 109 } 110 lastMatchEnd = matcher.end(); 111 } 112 113 try { 115 buffer.put(input.subSequence(lastMatchEnd, input.length()).toString().getBytes("US-ASCII")); 117 } catch (UnsupportedEncodingException e) { 118 LOG.severe(e.getMessage()); 120 } 121 buffer.limit(buffer.position()); 122 buffer.rewind(); 123 124 return charset.decode(buffer); 125 } 126 127 136 public static StringBuffer encode(CharSequence input, Charset charset) { 137 StringBuffer result = new StringBuffer (input.length()); 138 CharBuffer current = CharBuffer.allocate(1); 139 ByteBuffer decoded; 140 int lineLength = 0; 141 142 for (int i = 0; i < input.length(); i++) { 143 current.rewind(); 144 current.put(0, input.charAt(i)); 145 decoded = charset.encode(current); 146 147 while( decoded.remaining() != 0) { 153 byte next = decoded.get(); 154 155 if (((next == '\t' || next == ' ') 156 && !(lineLength == 74 || input.charAt(i + 1) == '\r' || input.charAt(i + 1) == '\n')) 157 || (next >= 33 158 && next != 61 159 && next <= 126)) { 160 result.append((char) next); 161 lineLength++; 162 } else if (next == '\r') { 163 result.append("\r\n"); 164 i++; 165 lineLength = 0; 166 } else { 167 if (lineLength > 71) { 168 result.append("=\r\n"); 169 lineLength = 0; 170 } 171 result.append('='); 172 result.append(toHexString(next)); 173 lineLength += 3; 174 } 175 176 if (lineLength > 74) { 177 result.append("=\r\n"); 178 lineLength = 0; 179 } 180 } 181 } 182 183 return result; 184 } 185 186 192 private static char[] toHexString(byte in) { 193 char[] result = new char[2]; 194 int value; 195 if (in < 0) { 196 value = 0x080 | (0x07f & in); 197 } else { 198 value = in; 199 } 200 201 int hi = value / 16; 202 int lo = value % 16; 203 204 result[0] = hexTable[hi]; 205 result[1] = hexTable[lo]; 206 207 return result; 208 } 209 210 } 211 | Popular Tags |