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