1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/* 2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright 2001-2004 The Apache Software Foundation. 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * you may not use this file except in compliance with the License. 6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * You may obtain a copy of the License at 7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See the License for the specific language governing permissions and 14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * limitations under the License. 15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.commons.codec.net; 18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.ByteArrayOutputStream; 20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.UnsupportedEncodingException; 21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.BitSet; 22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.BinaryDecoder; 23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.BinaryEncoder; 24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.DecoderException; 25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.EncoderException; 26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.StringDecoder; 27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport org.apache.commons.codec.StringEncoder; 28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/** 30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Codec for the Quoted-Printable section of <a href="http://www.ietf.org/rfc/rfc1521.txt">RFC 1521 </a>. 32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The Quoted-Printable encoding is intended to represent data that largely consists of octets that correspond to 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * printable characters in the ASCII character set. It encodes the data in such a way that the resulting octets are 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * unlikely to be modified by mail transport. If the data being encoded are mostly ASCII text, the encoded form of the 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * data remains largely recognizable by humans. A body which is entirely ASCII may also be encoded in Quoted-Printable 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to ensure the integrity of the data should the message pass through a character- translating, and/or line-wrapping 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * gateway. 40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note: 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Rules #3, #4, and #5 of the quoted-printable spec are not implemented yet because the complete quoted-printable spec 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * does not lend itself well into the byte[] oriented codec framework. Complete the codec once the steamable codec 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * framework is ready. The motivation behind providing the codec in a partial form is that it can already come in handy 49069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * for those applications that do not require quoted-printable line formatting (rules #3, #4, #5), for instance Q codec. 50069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 51069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 52069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see <a href="http://www.ietf.org/rfc/rfc1521.txt"> RFC 1521 MIME (Multipurpose Internet Mail Extensions) Part One: 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Mechanisms for Specifying and Describing the Format of Internet Message Bodies </a> 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 55069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Apache Software Foundation 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.3 57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Id: QuotedPrintableCodec.java,v 1.7 2004/04/09 22:21:07 ggregory Exp $ 58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class QuotedPrintableCodec implements BinaryEncoder, BinaryDecoder, StringEncoder, StringDecoder { 60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The default charset used for string decoding and encoding. 62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private String charset = StringEncodings.UTF8; 64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * BitSet of printable characters as defined in RFC 1521. 67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final BitSet PRINTABLE_CHARS = new BitSet(256); 69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static byte ESCAPE_CHAR = '='; 71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static byte TAB = 9; 73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static byte SPACE = 32; 75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Static initializer for printable chars collection 76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project static { 77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // alpha characters 78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 33; i <= 60; i++) { 79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project PRINTABLE_CHARS.set(i); 80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 62; i <= 126; i++) { 82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project PRINTABLE_CHARS.set(i); 83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project PRINTABLE_CHARS.set(TAB); 85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project PRINTABLE_CHARS.set(SPACE); 86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Default constructor. 90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public QuotedPrintableCodec() { 92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project super(); 93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Constructor which allows for the selection of a default charset 97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param charset 99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the default string charset to use. 100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public QuotedPrintableCodec(String charset) { 102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project super(); 103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project this.charset = charset; 104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes byte into its quoted-printable representation. 108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param b 110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * byte to encode 111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param buffer 112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the buffer to write to 113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final void encodeQuotedPrintable(int b, ByteArrayOutputStream buffer) { 115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buffer.write(ESCAPE_CHAR); 116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16)); 117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16)); 118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buffer.write(hex1); 119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buffer.write(hex2); 120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped. 124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * RFC 1521 and is suitable for encoding binary data and unformatted text. 128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param printable 131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * bitset of characters deemed quoted-printable 132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param bytes 133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of bytes to be encoded 134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return array of bytes containing quoted-printable data 135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final byte[] encodeQuotedPrintable(BitSet printable, byte[] bytes) { 137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (bytes == null) { 138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (printable == null) { 141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project printable = PRINTABLE_CHARS; 142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 0; i < bytes.length; i++) { 145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int b = bytes[i]; 146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (b < 0) { 147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project b = 256 + b; 148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (printable.get(b)) { 150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buffer.write(b); 151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project encodeQuotedPrintable(b, buffer); 153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return buffer.toByteArray(); 156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Decodes an array quoted-printable characters into an array of original bytes. Escaped characters are converted 160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * back to their original representation. 161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * RFC 1521. 165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param bytes 168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of quoted-printable characters 169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return array of original bytes 170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException 171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable decoding is unsuccessful 172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final byte[] decodeQuotedPrintable(byte[] bytes) throws DecoderException { 174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (bytes == null) { 175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for (int i = 0; i < bytes.length; i++) { 179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int b = bytes[i]; 180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (b == ESCAPE_CHAR) { 181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int u = Character.digit((char) bytes[++i], 16); 183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project int l = Character.digit((char) bytes[++i], 16); 184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (u == -1 || l == -1) { 185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException("Invalid quoted-printable encoding"); 186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buffer.write((char) ((u << 4) + l)); 188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ArrayIndexOutOfBoundsException e) { 189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException("Invalid quoted-printable encoding"); 190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buffer.write(b); 193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return buffer.toByteArray(); 196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped. 200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * RFC 1521 and is suitable for encoding binary data and unformatted text. 204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param bytes 207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of bytes to be encoded 208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return array of bytes containing quoted-printable data 209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public byte[] encode(byte[] bytes) { 211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return encodeQuotedPrintable(PRINTABLE_CHARS, bytes); 212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Decodes an array of quoted-printable characters into an array of original bytes. Escaped characters are converted 216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * back to their original representation. 217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * RFC 1521. 221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param bytes 224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * array of quoted-printable characters 225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return array of original bytes 226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException 227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable decoding is unsuccessful 228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public byte[] decode(byte[] bytes) throws DecoderException { 230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return decodeQuotedPrintable(bytes); 231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes a string into its quoted-printable form using the default string charset. Unsafe characters are escaped. 235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * RFC 1521 and is suitable for encoding binary data. 239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param pString 242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * string to convert to quoted-printable form 243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return quoted-printable string 244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws EncoderException 246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable encoding is unsuccessful 247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see #getDefaultCharset() 249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public String encode(String pString) throws EncoderException { 251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (pString == null) { 252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return encode(pString, getDefaultCharset()); 256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (UnsupportedEncodingException e) { 257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new EncoderException(e.getMessage()); 258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Decodes a quoted-printable string into its original form using the specified string charset. Escaped characters 263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * are converted back to their original representation. 264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param pString 266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * quoted-printable string to convert into its original form 267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param charset 268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the original string charset 269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return original string 270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException 271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable decoding is unsuccessful 272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws UnsupportedEncodingException 273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if charset is not supported 274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public String decode(String pString, String charset) throws DecoderException, UnsupportedEncodingException { 276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (pString == null) { 277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return new String(decode(pString.getBytes(StringEncodings.US_ASCII)), charset); 280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Decodes a quoted-printable string into its original form using the default string charset. Escaped characters are 284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * converted back to their original representation. 285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param pString 287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * quoted-printable string to convert into its original form 288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return original string 289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException 290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable decoding is unsuccessful 291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws UnsupportedEncodingException 292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if charset is not supported 293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @see #getDefaultCharset() 294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public String decode(String pString) throws DecoderException { 296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (pString == null) { 297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return decode(pString, getDefaultCharset()); 301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (UnsupportedEncodingException e) { 302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException(e.getMessage()); 303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes an object into its quoted-printable safe form. Unsafe characters are escaped. 308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param pObject 310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * string to convert to a quoted-printable form 311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return quoted-printable object 312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws EncoderException 313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable encoding is not applicable to objects of this type or if encoding is 314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * unsuccessful 315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object encode(Object pObject) throws EncoderException { 317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (pObject == null) { 318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else if (pObject instanceof byte[]) { 320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return encode((byte[]) pObject); 321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else if (pObject instanceof String) { 322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return encode((String) pObject); 323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new EncoderException("Objects of type " 325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + pObject.getClass().getName() 326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " cannot be quoted-printable encoded"); 327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Decodes a quoted-printable object into its original form. Escaped characters are converted back to their original 332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * representation. 333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param pObject 335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * quoted-printable object to convert into its original form 336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return original object 337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws DecoderException 338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if quoted-printable decoding is not applicable to objects of this type if decoding is 339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * unsuccessful 340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object decode(Object pObject) throws DecoderException { 342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (pObject == null) { 343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else if (pObject instanceof byte[]) { 345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return decode((byte[]) pObject); 346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else if (pObject instanceof String) { 347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return decode((String) pObject); 348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new DecoderException("Objects of type " 350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + pObject.getClass().getName() 351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " cannot be quoted-printable decoded"); 352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Returns the default charset used for string decoding and encoding. 357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return the default string charset. 359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public String getDefaultCharset() { 361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return this.charset; 362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Encodes a string into its quoted-printable form using the specified charset. Unsafe characters are escaped. 366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in 369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * RFC 1521 and is suitable for encoding binary data and unformatted text. 370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param pString 373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * string to convert to quoted-printable form 374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param charset 375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the charset for pString 376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return quoted-printable string 377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws UnsupportedEncodingException 379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Thrown if the charset is not supported 380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public String encode(String pString, String charset) throws UnsupportedEncodingException { 382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (pString == null) { 383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return new String(encode(pString.getBytes(charset)), StringEncodings.US_ASCII); 386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 388