1 16 17 package org.apache.commons.codec.net; 18 19 import java.io.UnsupportedEncodingException ; 20 import java.util.BitSet ; 21 22 import org.apache.commons.codec.DecoderException; 23 import org.apache.commons.codec.EncoderException; 24 import org.apache.commons.codec.StringDecoder; 25 import org.apache.commons.codec.StringEncoder; 26 27 47 public class QCodec extends RFC1522Codec implements StringEncoder, StringDecoder { 48 51 private String charset = StringEncodings.UTF8; 52 53 56 private static final BitSet PRINTABLE_CHARS = new BitSet (256); 57 static { 59 PRINTABLE_CHARS.set(' '); 61 PRINTABLE_CHARS.set('!'); 62 PRINTABLE_CHARS.set('"'); 63 PRINTABLE_CHARS.set('#'); 64 PRINTABLE_CHARS.set('$'); 65 PRINTABLE_CHARS.set('%'); 66 PRINTABLE_CHARS.set('&'); 67 PRINTABLE_CHARS.set('\''); 68 PRINTABLE_CHARS.set('('); 69 PRINTABLE_CHARS.set(')'); 70 PRINTABLE_CHARS.set('*'); 71 PRINTABLE_CHARS.set('+'); 72 PRINTABLE_CHARS.set(','); 73 PRINTABLE_CHARS.set('-'); 74 PRINTABLE_CHARS.set('.'); 75 PRINTABLE_CHARS.set('/'); 76 for (int i = '0'; i <= '9'; i++) { 77 PRINTABLE_CHARS.set(i); 78 } 79 PRINTABLE_CHARS.set(':'); 80 PRINTABLE_CHARS.set(';'); 81 PRINTABLE_CHARS.set('<'); 82 PRINTABLE_CHARS.set('>'); 83 PRINTABLE_CHARS.set('@'); 84 for (int i = 'A'; i <= 'Z'; i++) { 85 PRINTABLE_CHARS.set(i); 86 } 87 PRINTABLE_CHARS.set('['); 88 PRINTABLE_CHARS.set('\\'); 89 PRINTABLE_CHARS.set(']'); 90 PRINTABLE_CHARS.set('^'); 91 PRINTABLE_CHARS.set('`'); 92 for (int i = 'a'; i <= 'z'; i++) { 93 PRINTABLE_CHARS.set(i); 94 } 95 PRINTABLE_CHARS.set('{'); 96 PRINTABLE_CHARS.set('|'); 97 PRINTABLE_CHARS.set('}'); 98 PRINTABLE_CHARS.set('~'); 99 } 100 101 private static byte BLANK = 32; 102 103 private static byte UNDERSCORE = 95; 104 105 private boolean encodeBlanks = false; 106 107 110 public QCodec() { 111 super(); 112 } 113 114 123 public QCodec(final String charset) { 124 super(); 125 this.charset = charset; 126 } 127 128 protected String getEncoding() { 129 return "Q"; 130 } 131 132 protected byte[] doEncoding(byte[] bytes) throws EncoderException { 133 if (bytes == null) { 134 return null; 135 } 136 byte[] data = QuotedPrintableCodec.encodeQuotedPrintable(PRINTABLE_CHARS, bytes); 137 if (this.encodeBlanks) { 138 for (int i = 0; i < data.length; i++) { 139 if (data[i] == BLANK) { 140 data[i] = UNDERSCORE; 141 } 142 } 143 } 144 return data; 145 } 146 147 protected byte[] doDecoding(byte[] bytes) throws DecoderException { 148 if (bytes == null) { 149 return null; 150 } 151 boolean hasUnderscores = false; 152 for (int i = 0; i < bytes.length; i++) { 153 if (bytes[i] == UNDERSCORE) { 154 hasUnderscores = true; 155 break; 156 } 157 } 158 if (hasUnderscores) { 159 byte[] tmp = new byte[bytes.length]; 160 for (int i = 0; i < bytes.length; i++) { 161 byte b = bytes[i]; 162 if (b != UNDERSCORE) { 163 tmp[i] = b; 164 } else { 165 tmp[i] = BLANK; 166 } 167 } 168 return QuotedPrintableCodec.decodeQuotedPrintable(tmp); 169 } 170 return QuotedPrintableCodec.decodeQuotedPrintable(bytes); 171 } 172 173 185 public String encode(final String pString, final String charset) throws EncoderException { 186 if (pString == null) { 187 return null; 188 } 189 try { 190 return encodeText(pString, charset); 191 } catch (UnsupportedEncodingException e) { 192 throw new EncoderException(e.getMessage()); 193 } 194 } 195 196 206 public String encode(String pString) throws EncoderException { 207 if (pString == null) { 208 return null; 209 } 210 return encode(pString, getDefaultCharset()); 211 } 212 213 225 public String decode(String pString) throws DecoderException { 226 if (pString == null) { 227 return null; 228 } 229 try { 230 return decodeText(pString); 231 } catch (UnsupportedEncodingException e) { 232 throw new DecoderException(e.getMessage()); 233 } 234 } 235 236 246 public Object encode(Object pObject) throws EncoderException { 247 if (pObject == null) { 248 return null; 249 } else if (pObject instanceof String ) { 250 return encode((String ) pObject); 251 } else { 252 throw new EncoderException("Objects of type " 253 + pObject.getClass().getName() 254 + " cannot be encoded using Q codec"); 255 } 256 } 257 258 270 public Object decode(Object pObject) throws DecoderException { 271 if (pObject == null) { 272 return null; 273 } else if (pObject instanceof String ) { 274 return decode((String ) pObject); 275 } else { 276 throw new DecoderException("Objects of type " 277 + pObject.getClass().getName() 278 + " cannot be decoded using Q codec"); 279 } 280 } 281 282 287 public String getDefaultCharset() { 288 return this.charset; 289 } 290 291 296 public boolean isEncodeBlanks() { 297 return this.encodeBlanks; 298 } 299 300 306 public void setEncodeBlanks(boolean b) { 307 this.encodeBlanks = b; 308 } 309 } | Popular Tags |