15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2001-2004 The Apache Software Foundation. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you may not use this file except in compliance with the License. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may obtain a copy of the License at 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See the License for the specific language governing permissions and 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * limitations under the License. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.apache.commons.codec.net; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.ByteArrayOutputStream; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.io.UnsupportedEncodingException; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import java.util.BitSet; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.apache.commons.codec.BinaryDecoder; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.apache.commons.codec.BinaryEncoder; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.apache.commons.codec.DecoderException; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.apache.commons.codec.EncoderException; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.apache.commons.codec.StringDecoder; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import org.apache.commons.codec.StringEncoder; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Codec for the Quoted-Printable section of <a href="http://www.ietf.org/rfc/rfc1521.txt">RFC 1521 </a>. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Quoted-Printable encoding is intended to represent data that largely consists of octets that correspond to 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * printable characters in the ASCII character set. It encodes the data in such a way that the resulting octets are 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unlikely to be modified by mail transport. If the data being encoded are mostly ASCII text, the encoded form of the 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * data remains largely recognizable by humans. A body which is entirely ASCII may also be encoded in Quoted-Printable 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to ensure the integrity of the data should the message pass through a character- translating, and/or line-wrapping 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * gateway. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Rules #3, #4, and #5 of the quoted-printable spec are not implemented yet because the complete quoted-printable spec 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * does not lend itself well into the byte[] oriented codec framework. Complete the codec once the steamable codec 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * framework is ready. The motivation behind providing the codec in a partial form is that it can already come in handy 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for those applications that do not require quoted-printable line formatting (rules #3, #4, #5), for instance Q codec. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @see <a href="http://www.ietf.org/rfc/rfc1521.txt"> RFC 1521 MIME (Multipurpose Internet Mail Extensions) Part One: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Mechanisms for Specifying and Describing the Format of Internet Message Bodies </a> 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author Apache Software Foundation 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @since 1.3 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @version $Id: QuotedPrintableCodec.java,v 1.7 2004/04/09 22:21:07 ggregory Exp $ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @deprecated Please use {@link java.net.URL#openConnection} instead. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for further details. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@Deprecated 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class QuotedPrintableCodec implements BinaryEncoder, BinaryDecoder, StringEncoder, StringDecoder { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The default charset used for string decoding and encoding. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private String charset = StringEncodings.UTF8; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BitSet of printable characters as defined in RFC 1521. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static final BitSet PRINTABLE_CHARS = new BitSet(256); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static byte ESCAPE_CHAR = '='; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static byte TAB = 9; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static byte SPACE = 32; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Static initializer for printable chars collection 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alpha characters 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 33; i <= 60; i++) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRINTABLE_CHARS.set(i); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 62; i <= 126; i++) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRINTABLE_CHARS.set(i); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRINTABLE_CHARS.set(TAB); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRINTABLE_CHARS.set(SPACE); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Default constructor. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public QuotedPrintableCodec() { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) super(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Constructor which allows for the selection of a default charset 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param charset 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the default string charset to use. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public QuotedPrintableCodec(String charset) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) super(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.charset = charset; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Encodes byte into its quoted-printable representation. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param b 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * byte to encode 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param buffer 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the buffer to write to 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private static final void encodeQuotedPrintable(int b, ByteArrayOutputStream buffer) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.write(ESCAPE_CHAR); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.write(hex1); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.write(hex2); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RFC 1521 and is suitable for encoding binary data and unformatted text. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param printable 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * bitset of characters deemed quoted-printable 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param bytes 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array of bytes to be encoded 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return array of bytes containing quoted-printable data 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public static final byte[] encodeQuotedPrintable(BitSet printable, byte[] bytes) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes == null) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printable == null) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printable = PRINTABLE_CHARS; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bytes.length; i++) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int b = bytes[i]; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b < 0) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b = 256 + b; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printable.get(b)) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.write(b); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encodeQuotedPrintable(b, buffer); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer.toByteArray(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decodes an array quoted-printable characters into an array of original bytes. Escaped characters are converted 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * back to their original representation. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RFC 1521. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param bytes 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array of quoted-printable characters 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return array of original bytes 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws DecoderException 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable decoding is unsuccessful 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public static final byte[] decodeQuotedPrintable(byte[] bytes) throws DecoderException { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes == null) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < bytes.length; i++) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int b = bytes[i]; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (b == ESCAPE_CHAR) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int u = Character.digit((char) bytes[++i], 16); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int l = Character.digit((char) bytes[++i], 16); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (u == -1 || l == -1) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new DecoderException("Invalid quoted-printable encoding"); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.write((char) ((u << 4) + l)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (ArrayIndexOutOfBoundsException e) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new DecoderException("Invalid quoted-printable encoding"); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.write(b); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer.toByteArray(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RFC 1521 and is suitable for encoding binary data and unformatted text. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param bytes 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array of bytes to be encoded 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return array of bytes containing quoted-printable data 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public byte[] encode(byte[] bytes) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return encodeQuotedPrintable(PRINTABLE_CHARS, bytes); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decodes an array of quoted-printable characters into an array of original bytes. Escaped characters are converted 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * back to their original representation. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RFC 1521. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param bytes 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * array of quoted-printable characters 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return array of original bytes 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws DecoderException 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable decoding is unsuccessful 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public byte[] decode(byte[] bytes) throws DecoderException { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decodeQuotedPrintable(bytes); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Encodes a string into its quoted-printable form using the default string charset. Unsafe characters are escaped. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RFC 1521 and is suitable for encoding binary data. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param pString 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string to convert to quoted-printable form 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return quoted-printable string 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws EncoderException 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable encoding is unsuccessful 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @see #getDefaultCharset() 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public String encode(String pString) throws EncoderException { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pString == null) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return encode(pString, getDefaultCharset()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (UnsupportedEncodingException e) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new EncoderException(e.getMessage()); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decodes a quoted-printable string into its original form using the specified string charset. Escaped characters 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are converted back to their original representation. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param pString 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * quoted-printable string to convert into its original form 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param charset 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the original string charset 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return original string 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws DecoderException 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable decoding is unsuccessful 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws UnsupportedEncodingException 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if charset is not supported 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public String decode(String pString, String charset) throws DecoderException, UnsupportedEncodingException { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pString == null) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new String(decode(pString.getBytes(StringEncodings.US_ASCII)), charset); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decodes a quoted-printable string into its original form using the default string charset. Escaped characters are 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * converted back to their original representation. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param pString 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * quoted-printable string to convert into its original form 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return original string 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws DecoderException 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable decoding is unsuccessful 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws UnsupportedEncodingException 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if charset is not supported 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @see #getDefaultCharset() 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public String decode(String pString) throws DecoderException { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pString == null) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decode(pString, getDefaultCharset()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (UnsupportedEncodingException e) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new DecoderException(e.getMessage()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Encodes an object into its quoted-printable safe form. Unsafe characters are escaped. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param pObject 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string to convert to a quoted-printable form 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return quoted-printable object 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws EncoderException 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable encoding is not applicable to objects of this type or if encoding is 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unsuccessful 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public Object encode(Object pObject) throws EncoderException { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pObject == null) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pObject instanceof byte[]) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return encode((byte[]) pObject); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pObject instanceof String) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return encode((String) pObject); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new EncoderException("Objects of type " 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + pObject.getClass().getName() 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + " cannot be quoted-printable encoded"); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Decodes a quoted-printable object into its original form. Escaped characters are converted back to their original 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * representation. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param pObject 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * quoted-printable object to convert into its original form 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return original object 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws DecoderException 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if quoted-printable decoding is not applicable to objects of this type if decoding is 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unsuccessful 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public Object decode(Object pObject) throws DecoderException { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pObject == null) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pObject instanceof byte[]) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decode((byte[]) pObject); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pObject instanceof String) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return decode((String) pObject); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new DecoderException("Objects of type " 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + pObject.getClass().getName() 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + " cannot be quoted-printable decoded"); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the default charset used for string decoding and encoding. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return the default string charset. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public String getDefaultCharset() { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.charset; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Encodes a string into its quoted-printable form using the specified charset. Unsafe characters are escaped. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * <p> 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * RFC 1521 and is suitable for encoding binary data and unformatted text. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * </p> 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param pString 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string to convert to quoted-printable form 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param charset 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the charset for pString 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return quoted-printable string 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @throws UnsupportedEncodingException 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thrown if the charset is not supported 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public String encode(String pString, String charset) throws UnsupportedEncodingException { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pString == null) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new String(encode(pString.getBytes(charset)), StringEncodings.US_ASCII); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)