| /* |
| * Copyright (C) 2006 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.internal.telephony; |
| |
| import junit.framework.TestCase; |
| |
| import android.test.suitebuilder.annotation.LargeTest; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.test.suitebuilder.annotation.Suppress; |
| |
| public class GsmAlphabetTest extends TestCase { |
| |
| private static final String sGsmExtendedChars = "{|}\\[~]\f\u20ac"; |
| |
| @SmallTest |
| public void test7bitWithHeader() throws Exception { |
| byte[] data = new byte[3]; |
| data[0] = (byte) 1; |
| data[1] = (byte) 2; |
| data[2] = (byte) 2; |
| SmsHeader header = new SmsHeader(); |
| header.add(new SmsHeader.Element(SmsHeader.CONCATENATED_8_BIT_REFERENCE, data)); |
| |
| String message = "aaaaaaaaaabbbbbbbbbbcccccccccc"; |
| byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header.toByteArray()); |
| int septetCount = GsmAlphabet.countGsmSeptets(message, false); |
| String parsedMessage = GsmAlphabet.gsm7BitPackedToString( |
| userData, header.toByteArray().length+1, septetCount, 1); |
| assertEquals(message, parsedMessage); |
| } |
| |
| // TODO: This method should *really* be a series of individual test methods. |
| @LargeTest |
| public void testBasic() throws Exception { |
| // '@' maps to char 0 |
| assertEquals(0, GsmAlphabet.charToGsm('@')); |
| |
| // `a (a with grave accent) maps to last GSM charater |
| assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0')); |
| |
| // |
| // These are the extended chars |
| // They should all return GsmAlphabet.GSM_EXTENDED_ESCAPE |
| // |
| |
| for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { |
| assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE, |
| GsmAlphabet.charToGsm(sGsmExtendedChars.charAt(i))); |
| |
| } |
| |
| // euro symbol |
| assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE, |
| GsmAlphabet.charToGsm('\u20ac')); |
| |
| // An unmappable char (the 'cent' char) maps to a space |
| assertEquals(GsmAlphabet.charToGsm(' '), |
| GsmAlphabet.charToGsm('\u00a2')); |
| |
| // unmappable = space = 1 septet |
| assertEquals(1, GsmAlphabet.countGsmSeptets('\u00a2')); |
| |
| // |
| // Test extended table |
| // |
| |
| for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { |
| assertEquals(sGsmExtendedChars.charAt(i), |
| GsmAlphabet.gsmExtendedToChar( |
| GsmAlphabet.charToGsmExtended(sGsmExtendedChars.charAt(i)))); |
| |
| } |
| |
| // Unmappable extended char |
| assertEquals(GsmAlphabet.charToGsm(' '), |
| GsmAlphabet.charToGsmExtended('@')); |
| |
| // |
| // gsmToChar() |
| // |
| |
| assertEquals('@', GsmAlphabet.gsmToChar(0)); |
| |
| // `a (a with grave accent) maps to last GSM charater |
| assertEquals('\u00e0', GsmAlphabet.gsmToChar(0x7f)); |
| |
| assertEquals('\uffff', |
| GsmAlphabet.gsmToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE)); |
| |
| // Out-of-range/unmappable value |
| assertEquals(' ', GsmAlphabet.gsmToChar(0x80)); |
| |
| // |
| // gsmExtendedToChar() |
| // |
| |
| assertEquals('{', GsmAlphabet.gsmExtendedToChar(0x28)); |
| |
| // No double-escapes |
| assertEquals(' ', GsmAlphabet.gsmExtendedToChar( |
| GsmAlphabet.GSM_EXTENDED_ESCAPE)); |
| |
| // Unmappable |
| assertEquals(' ', GsmAlphabet.gsmExtendedToChar(0)); |
| |
| // |
| // stringTo7BitPacked, gsm7BitPackedToString |
| // |
| |
| byte[] packed; |
| StringBuilder testString = new StringBuilder(300); |
| |
| // Check all alignment cases |
| for (int i = 0; i < 9; i++, testString.append('@')) { |
| packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| assertEquals(testString.toString(), |
| GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); |
| } |
| |
| // Check full non-extended alphabet |
| for (int i = 0; i < 0x80; i++) { |
| char c; |
| |
| if (i == GsmAlphabet.GSM_EXTENDED_ESCAPE) { |
| continue; |
| } |
| |
| c = GsmAlphabet.gsmToChar(i); |
| testString.append(c); |
| |
| // These are all non-extended chars, so it should be |
| // one septet per char |
| assertEquals(1, GsmAlphabet.countGsmSeptets(c)); |
| } |
| |
| packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| assertEquals(testString.toString(), |
| GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); |
| |
| // Test extended chars too |
| |
| testString.append(sGsmExtendedChars); |
| |
| for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { |
| // These are all extended chars, so it should be |
| // two septets per char |
| assertEquals(2, GsmAlphabet.countGsmSeptets(sGsmExtendedChars.charAt(i))); |
| |
| } |
| |
| packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| assertEquals(testString.toString(), |
| GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); |
| |
| // stringTo7BitPacked handles up to 255 septets |
| |
| testString.setLength(0); |
| for (int i = 0; i < 255; i++) { |
| testString.append('@'); |
| } |
| |
| packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| assertEquals(testString.toString(), |
| GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); |
| |
| // > 255 septets throws runtime exception |
| testString.append('@'); |
| |
| try { |
| GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| fail("expected exception"); |
| } catch (EncodeException ex) { |
| // exception expected |
| } |
| |
| // Try 254 septets with 127 extended chars |
| |
| testString.setLength(0); |
| for (int i = 0; i < (255 / 2); i++) { |
| testString.append('{'); |
| } |
| |
| packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| assertEquals(testString.toString(), |
| GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); |
| |
| // > 255 septets throws runtime exception |
| testString.append('{'); |
| |
| try { |
| GsmAlphabet.stringToGsm7BitPacked(testString.toString()); |
| fail("expected exception"); |
| } catch (EncodeException ex) { |
| // exception expected |
| } |
| |
| // |
| // 8 bit unpacked format |
| // |
| // Note: we compare hex strings here |
| // because Assert doesnt have array-comparisons |
| |
| byte unpacked[]; |
| |
| unpacked = IccUtils.hexStringToBytes("566F696365204D61696C"); |
| assertEquals("Voice Mail", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| assertEquals(IccUtils.bytesToHexString(unpacked), |
| IccUtils.bytesToHexString( |
| GsmAlphabet.stringToGsm8BitPacked("Voice Mail"))); |
| |
| unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars); |
| // two bytes for every extended char |
| assertEquals(2 * sGsmExtendedChars.length(), unpacked.length); |
| assertEquals(sGsmExtendedChars, |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| // should be two bytes per extended char |
| assertEquals(2 * sGsmExtendedChars.length(), unpacked.length); |
| |
| // Test truncation of unaligned extended chars |
| unpacked = new byte[3]; |
| GsmAlphabet.stringToGsm8BitUnpackedField(sGsmExtendedChars, unpacked, |
| 0, unpacked.length); |
| |
| // Should be one extended char and an 0xff at the end |
| |
| assertEquals(0xff, 0xff & unpacked[2]); |
| assertEquals(sGsmExtendedChars.substring(0, 1), |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| // Test truncation of normal chars |
| unpacked = new byte[3]; |
| GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, |
| 0, unpacked.length); |
| |
| assertEquals("abc", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| // Test truncation of mixed normal and extended chars |
| unpacked = new byte[3]; |
| GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked, |
| 0, unpacked.length); |
| |
| assertEquals("a{", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| // Test padding after normal char |
| unpacked = new byte[3]; |
| GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked, |
| 0, unpacked.length); |
| |
| assertEquals("a", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| assertEquals(0xff, 0xff & unpacked[1]); |
| assertEquals(0xff, 0xff & unpacked[2]); |
| |
| // Test malformed input -- escape char followed by end of field |
| unpacked[0] = 0; |
| unpacked[1] = 0; |
| unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE; |
| |
| assertEquals("@@", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); |
| |
| // non-zero offset |
| assertEquals("@", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); |
| |
| // test non-zero offset |
| unpacked[0] = 0; |
| GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, |
| 1, unpacked.length - 1); |
| |
| |
| assertEquals(0, unpacked[0]); |
| |
| assertEquals("ab", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); |
| |
| // test non-zero offset with truncated extended char |
| unpacked[0] = 0; |
| |
| GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked, |
| 1, unpacked.length - 1); |
| |
| assertEquals(0, unpacked[0]); |
| |
| assertEquals("a", |
| GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); |
| } |
| } |
| |