1526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen/*
2526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2007 Esmertec AG.
3526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2007 The Android Open Source Project
4526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen *
5526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Licensed under the Apache License, Version 2.0 (the "License");
6526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * you may not use this file except in compliance with the License.
7526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * You may obtain a copy of the License at
8526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen *
9526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen *      http://www.apache.org/licenses/LICENSE-2.0
10526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen *
11526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Unless required by applicable law or agreed to in writing, software
12526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * distributed under the License is distributed on an "AS IS" BASIS,
13526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * See the License for the specific language governing permissions and
15526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * limitations under the License.
16526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */
17526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen
18526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpackage com.google.android.mms.pdu;
19526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen
20526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.ByteArrayOutputStream;
21526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen
22526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpublic class QuotedPrintable {
23526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen    private static byte ESCAPE_CHAR = '=';
24526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen
25526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen    /**
26526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * Decodes an array quoted-printable characters into an array of original bytes.
27526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * Escaped characters are converted back to their original representation.
28526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     *
29526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * <p>
30526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * This function implements a subset of
31526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * quoted-printable encoding specification (rule #1 and rule #2)
32526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * as defined in RFC 1521.
33526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * </p>
34526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     *
35526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * @param bytes array of quoted-printable characters
36526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     * @return array of original bytes,
37526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     *         null if quoted-printable decoding is unsuccessful.
38526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen     */
39526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen    public static final byte[] decodeQuotedPrintable(byte[] bytes) {
40526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen        if (bytes == null) {
41526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen            return null;
42526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen        }
43526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
44526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen        for (int i = 0; i < bytes.length; i++) {
45526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen            int b = bytes[i];
46526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen            if (b == ESCAPE_CHAR) {
47526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                try {
48526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    if('\r' == (char)bytes[i + 1] &&
49526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                            '\n' == (char)bytes[i + 2]) {
50526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                        i += 2;
51526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                        continue;
52526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    }
53526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    int u = Character.digit((char) bytes[++i], 16);
54526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    int l = Character.digit((char) bytes[++i], 16);
55526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    if (u == -1 || l == -1) {
56526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                        return null;
57526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    }
58526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    buffer.write((char) ((u << 4) + l));
59526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                } catch (ArrayIndexOutOfBoundsException e) {
60526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                    return null;
61526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                }
62526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen            } else {
63526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen                buffer.write(b);
64526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen            }
65526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen        }
66526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen        return buffer.toByteArray();
67526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen    }
68526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen}
69