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