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 $
58d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *
59d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead.
60d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
61d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath *     for further details.
62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */
63d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated
64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic class QuotedPrintableCodec implements BinaryEncoder, BinaryDecoder, StringEncoder, StringDecoder {
65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * The default charset used for string decoding and encoding.
67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private String charset = StringEncodings.UTF8;
69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * BitSet of printable characters as defined in RFC 1521.
72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final BitSet PRINTABLE_CHARS = new BitSet(256);
74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static byte ESCAPE_CHAR = '=';
76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static byte TAB = 9;
78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static byte SPACE = 32;
80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    // Static initializer for printable chars collection
81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    static {
82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        // alpha characters
83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = 33; i <= 60; i++) {
84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            PRINTABLE_CHARS.set(i);
85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = 62; i <= 126; i++) {
87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            PRINTABLE_CHARS.set(i);
88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        PRINTABLE_CHARS.set(TAB);
90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        PRINTABLE_CHARS.set(SPACE);
91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Default constructor.
95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public QuotedPrintableCodec() {
97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        super();
98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Constructor which allows for the selection of a default charset
102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param charset
104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  the default string charset to use.
105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public QuotedPrintableCodec(String charset) {
107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        super();
108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        this.charset = charset;
109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encodes byte into its quoted-printable representation.
113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param b
115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  byte to encode
116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param buffer
117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  the buffer to write to
118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    private static final void encodeQuotedPrintable(int b, ByteArrayOutputStream buffer) {
120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        buffer.write(ESCAPE_CHAR);
121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16));
122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16));
123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        buffer.write(hex1);
124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        buffer.write(hex2);
125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped.
129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p>
131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in
132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * RFC 1521 and is suitable for encoding binary data and unformatted text.
133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * </p>
134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param printable
136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  bitset of characters deemed quoted-printable
137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param bytes
138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  array of bytes to be encoded
139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return array of bytes containing quoted-printable data
140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public static final byte[] encodeQuotedPrintable(BitSet printable, byte[] bytes) {
142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (bytes == null) {
143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (printable == null) {
146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            printable = PRINTABLE_CHARS;
147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = 0; i < bytes.length; i++) {
150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int b = bytes[i];
151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (b < 0) {
152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                b = 256 + b;
153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (printable.get(b)) {
155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                buffer.write(b);
156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                encodeQuotedPrintable(b, buffer);
158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return buffer.toByteArray();
161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Decodes an array quoted-printable characters into an array of original bytes. Escaped characters are converted
165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * back to their original representation.
166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p>
168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in
169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * RFC 1521.
170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * </p>
171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param bytes
173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  array of quoted-printable characters
174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return array of original bytes
175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException
176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable decoding is unsuccessful
177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public static final byte[] decodeQuotedPrintable(byte[] bytes) throws DecoderException {
179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (bytes == null) {
180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        for (int i = 0; i < bytes.length; i++) {
184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            int b = bytes[i];
185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            if (b == ESCAPE_CHAR) {
186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                try {
187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    int u = Character.digit((char) bytes[++i], 16);
188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    int l = Character.digit((char) bytes[++i], 16);
189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    if (u == -1 || l == -1) {
190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                        throw new DecoderException("Invalid quoted-printable encoding");
191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    }
192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    buffer.write((char) ((u << 4) + l));
193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                } catch (ArrayIndexOutOfBoundsException e) {
194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                    throw new DecoderException("Invalid quoted-printable encoding");
195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                }
196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            } else {
197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                buffer.write(b);
198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            }
199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return buffer.toByteArray();
201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encodes an array of bytes into an array of quoted-printable 7-bit characters. Unsafe characters are escaped.
205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p>
207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in
208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * RFC 1521 and is suitable for encoding binary data and unformatted text.
209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * </p>
210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param bytes
212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  array of bytes to be encoded
213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return array of bytes containing quoted-printable data
214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public byte[] encode(byte[] bytes) {
216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return encodeQuotedPrintable(PRINTABLE_CHARS, bytes);
217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Decodes an array of quoted-printable characters into an array of original bytes. Escaped characters are converted
221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * back to their original representation.
222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p>
224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in
225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * RFC 1521.
226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * </p>
227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param bytes
229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  array of quoted-printable characters
230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return array of original bytes
231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException
232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable decoding is unsuccessful
233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public byte[] decode(byte[] bytes) throws DecoderException {
235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return decodeQuotedPrintable(bytes);
236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encodes a string into its quoted-printable form using the default string charset. Unsafe characters are escaped.
240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p>
242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in
243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * RFC 1521 and is suitable for encoding binary data.
244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * </p>
245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param pString
247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  string to convert to quoted-printable form
248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return quoted-printable string
249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws EncoderException
251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable encoding is unsuccessful
252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #getDefaultCharset()
254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String encode(String pString) throws EncoderException {
256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (pString == null) {
257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return encode(pString, getDefaultCharset());
261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } catch (UnsupportedEncodingException e) {
262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new EncoderException(e.getMessage());
263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Decodes a quoted-printable string into its original form using the specified string charset. Escaped characters
268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * are converted back to their original representation.
269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param pString
271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  quoted-printable string to convert into its original form
272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param charset
273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  the original string charset
274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return original string
275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException
276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable decoding is unsuccessful
277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws UnsupportedEncodingException
278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if charset is not supported
279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String decode(String pString, String charset) throws DecoderException, UnsupportedEncodingException {
281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (pString == null) {
282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new String(decode(pString.getBytes(StringEncodings.US_ASCII)), charset);
285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Decodes a quoted-printable string into its original form using the default string charset. Escaped characters are
289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * converted back to their original representation.
290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param pString
292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  quoted-printable string to convert into its original form
293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return original string
294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException
295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable decoding is unsuccessful
296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws UnsupportedEncodingException
297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if charset is not supported
298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @see #getDefaultCharset()
299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String decode(String pString) throws DecoderException {
301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (pString == null) {
302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        try {
305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return decode(pString, getDefaultCharset());
306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } catch (UnsupportedEncodingException e) {
307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new DecoderException(e.getMessage());
308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encodes an object into its quoted-printable safe form. Unsafe characters are escaped.
313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param pObject
315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  string to convert to a quoted-printable form
316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return quoted-printable object
317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws EncoderException
318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable encoding is not applicable to objects of this type or if encoding is
319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  unsuccessful
320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public Object encode(Object pObject) throws EncoderException {
322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (pObject == null) {
323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (pObject instanceof byte[]) {
325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return encode((byte[]) pObject);
326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (pObject instanceof String) {
327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return encode((String) pObject);
328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new EncoderException("Objects of type "
330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                + pObject.getClass().getName()
331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                + " cannot be quoted-printable encoded");
332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Decodes a quoted-printable object into its original form. Escaped characters are converted back to their original
337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * representation.
338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param pObject
340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  quoted-printable object to convert into its original form
341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return original object
342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws DecoderException
343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if quoted-printable decoding is not applicable to objects of this type if decoding is
344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  unsuccessful
345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public Object decode(Object pObject) throws DecoderException {
347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (pObject == null) {
348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (pObject instanceof byte[]) {
350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return decode((byte[]) pObject);
351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else if (pObject instanceof String) {
352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return decode((String) pObject);
353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        } else {
354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            throw new DecoderException("Objects of type "
355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                + pObject.getClass().getName()
356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project                + " cannot be quoted-printable decoded");
357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Returns the default charset used for string decoding and encoding.
362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return the default string charset.
364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String getDefaultCharset() {
366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return this.charset;
367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project
369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    /**
370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * Encodes a string into its quoted-printable form using the specified charset. Unsafe characters are escaped.
371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * <p>
373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * This function implements a subset of quoted-printable encoding specification (rule #1 and rule #2) as defined in
374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * RFC 1521 and is suitable for encoding binary data and unformatted text.
375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * </p>
376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param pString
378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  string to convert to quoted-printable form
379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @param charset
380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  the charset for pString
381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @return quoted-printable string
382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *
383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     * @throws UnsupportedEncodingException
384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     *                  Thrown if the charset is not supported
385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project     */
386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    public String encode(String pString, String charset) throws UnsupportedEncodingException {
387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        if (pString == null) {
388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project            return null;
389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        }
390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project        return new String(encode(pString.getBytes(charset)), StringEncodings.US_ASCII);
391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project    }
392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project}
393