1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2007 Esmertec AG. 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2007 The Android Open Source Project 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.mmslib.pdu; 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.ByteArrayOutputStream; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class QuotedPrintable { 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static byte ESCAPE_CHAR = '='; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Decodes an array quoted-printable characters into an array of original bytes. 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Escaped characters are converted back to their original representation. 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <p> 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This function implements a subset of 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * quoted-printable encoding specification (rule #1 and rule #2) 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * as defined in RFC 1521. 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * </p> 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param bytes array of quoted-printable characters 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return array of original bytes, 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * null if quoted-printable decoding is unsuccessful. 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final byte[] decodeQuotedPrintable(byte[] bytes) { 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (bytes == null) { 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0; i < bytes.length; i++) { 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int b = bytes[i]; 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (b == ESCAPE_CHAR) { 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if ('\r' == (char) bytes[i + 1] && 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd '\n' == (char) bytes[i + 2]) { 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd i += 2; 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd continue; 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int u = Character.digit((char) bytes[++i], 16); 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int l = Character.digit((char) bytes[++i], 16); 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (u == -1 || l == -1) { 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd buffer.write((char) ((u << 4) + l)); 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (ArrayIndexOutOfBoundsException e) { 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd buffer.write(b); 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return buffer.toByteArray(); 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 69