10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport com.android.internal.telephony.GsmAlphabet;
20d720945f2be5ea5fe0faf67e67d9ea0e184eba67Alex Yakavenkaimport com.android.internal.telephony.uicc.IccUtils;
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport junit.framework.TestCase;
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.test.suitebuilder.annotation.LargeTest;
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.test.suitebuilder.annotation.SmallTest;
260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
270825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class GsmAlphabetTest extends TestCase {
280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private static final String sGsmExtendedChars = "{|}\\[~]\f\u20ac";
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @SmallTest
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void test7bitWithHeader() throws Exception {
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        concatRef.refNumber = 1;
350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        concatRef.seqNumber = 2;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        concatRef.msgCount = 2;
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        concatRef.isEightBits = true;
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        SmsHeader header = new SmsHeader();
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        header.concatRef = concatRef;
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String message = "aaaaaaaaaabbbbbbbbbbcccccccccc";
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message,
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                SmsHeader.toByteArray(header), 0, 0);
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int septetCount = GsmAlphabet.countGsmSeptetsUsingTables(message, true, 0, 0);
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        String parsedMessage = GsmAlphabet.gsm7BitPackedToString(
460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                userData, SmsHeader.toByteArray(header).length+2, septetCount, 1, 0, 0);
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(message, parsedMessage);
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // TODO: This method should *really* be a series of individual test methods.
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    // However, it's a SmallTest because it executes quickly.
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @SmallTest
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testBasic() throws Exception {
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // '@' maps to char 0
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0, GsmAlphabet.charToGsm('@'));
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // `a (a with grave accent) maps to last GSM character
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0'));
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // These are the extended chars
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // They should all return GsmAlphabet.GSM_EXTENDED_ESCAPE
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE,
670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    GsmAlphabet.charToGsm(sGsmExtendedChars.charAt(i)));
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // euro symbol
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE,
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.charToGsm('\u20ac'));
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // An unmappable char (the 'cent' char) maps to a space
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(GsmAlphabet.charToGsm(' '),
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.charToGsm('\u00a2'));
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // unmappable = space = 1 septet
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(1, GsmAlphabet.countGsmSeptets('\u00a2'));
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test extended table
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            assertEquals(sGsmExtendedChars.charAt(i),
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    GsmAlphabet.gsmExtendedToChar(
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                            GsmAlphabet.charToGsmExtended(sGsmExtendedChars.charAt(i))));
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unmappable extended char
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(GsmAlphabet.charToGsm(' '),
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.charToGsmExtended('@'));
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // gsmToChar()
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals('@', GsmAlphabet.gsmToChar(0));
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // `a (a with grave accent) maps to last GSM character
1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals('\u00e0', GsmAlphabet.gsmToChar(0x7f));
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals('\uffff',
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsmToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE));
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Out-of-range/unmappable value
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(' ', GsmAlphabet.gsmToChar(0x80));
1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // gsmExtendedToChar()
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals('{', GsmAlphabet.gsmExtendedToChar(0x28));
1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // No double-escapes
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(' ', GsmAlphabet.gsmExtendedToChar(
1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.GSM_EXTENDED_ESCAPE));
1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Reserved for extension to extension table (mapped to space)
1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(' ', GsmAlphabet.gsmExtendedToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE));
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unmappable (mapped to character in default or national locking shift table)
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals('@', GsmAlphabet.gsmExtendedToChar(0));
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals('\u00e0', GsmAlphabet.gsmExtendedToChar(0x7f));
1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // stringTo7BitPacked, gsm7BitPackedToString
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte[] packed;
1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        StringBuilder testString = new StringBuilder(300);
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Check all alignment cases
1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < 9; i++, testString.append('@')) {
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            assertEquals(testString.toString(),
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Check full non-extended alphabet
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < 0x80; i++) {
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            char c;
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (i == GsmAlphabet.GSM_EXTENDED_ESCAPE) {
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                continue;
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c = GsmAlphabet.gsmToChar(i);
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            testString.append(c);
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // These are all non-extended chars, so it should be
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // one septet per char
1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            assertEquals(1, GsmAlphabet.countGsmSeptets(c));
1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(testString.toString(),
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test extended chars too
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        testString.append(sGsmExtendedChars);
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) {
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // These are all extended chars, so it should be
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // two septets per char
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            assertEquals(2, GsmAlphabet.countGsmSeptets(sGsmExtendedChars.charAt(i)));
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(testString.toString(),
1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // stringTo7BitPacked handles up to 255 septets
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        testString.setLength(0);
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < 255; i++) {
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            testString.append('@');
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(testString.toString(),
1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // > 255 septets throws runtime exception
1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        testString.append('@');
1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            fail("expected exception");
1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (EncodeException ex) {
1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // exception expected
1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Try 254 septets with 127 extended chars
2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        testString.setLength(0);
2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        for (int i = 0; i < (255 / 2); i++) {
2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            testString.append('{');
2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(testString.toString(),
2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0]));
2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // > 255 septets throws runtime exception
2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        testString.append('{');
2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0);
2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            fail("expected exception");
2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (EncodeException ex) {
2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // exception expected
2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Reserved for extension to extension table (mapped to space)
2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed = new byte[]{(byte)(0x1b | 0x80), 0x1b >> 1};
2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(" ", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unmappable (mapped to character in default alphabet table)
2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed[0] = 0x1b;
2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed[1] = 0x00;
2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("@", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed[0] = (byte)(0x1b | 0x80);
2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        packed[1] = (byte)(0x7f >> 1);
2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("\u00e0", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2));
2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // 8 bit unpacked format
2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        //
2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Note: we compare hex strings here
2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // because Assert doesn't have array comparisons
2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte unpacked[];
2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = IccUtils.hexStringToBytes("566F696365204D61696C");
2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("Voice Mail",
2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(IccUtils.bytesToHexString(unpacked),
2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                IccUtils.bytesToHexString(
2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        GsmAlphabet.stringToGsm8BitPacked("Voice Mail")));
2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // two bytes for every extended char
2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(2 * sGsmExtendedChars.length(), unpacked.length);
2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(sGsmExtendedChars,
2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // should be two bytes per extended char
2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(2 * sGsmExtendedChars.length(), unpacked.length);
2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test truncation of unaligned extended chars
2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = new byte[3];
2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmAlphabet.stringToGsm8BitUnpackedField(sGsmExtendedChars, unpacked,
2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                0, unpacked.length);
2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Should be one extended char and an 0xff at the end
2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0xff, 0xff & unpacked[2]);
2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(sGsmExtendedChars.substring(0, 1),
2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test truncation of normal chars
2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = new byte[3];
2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                0, unpacked.length);
2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("abc",
2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test truncation of mixed normal and extended chars
2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = new byte[3];
2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked,
2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                0, unpacked.length);
2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("a{",
2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test padding after normal char
2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = new byte[3];
2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked,
2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                0, unpacked.length);
2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("a",
2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0xff, 0xff & unpacked[1]);
2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0xff, 0xff & unpacked[2]);
2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test malformed input -- escape char followed by end of field
2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[0] = 0;
2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[1] = 0;
2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE;
2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("@@",
3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length));
3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // non-zero offset
3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("@",
3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // test non-zero offset
3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[0] = 0;
3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked,
3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                1, unpacked.length - 1);
3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0, unpacked[0]);
3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("ab",
3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // test non-zero offset with truncated extended char
3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[0] = 0;
3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked,
3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                1, unpacked.length - 1);
3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(0, unpacked[0]);
3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("a",
3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1));
3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Reserved for extension to extension table (mapped to space)
3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[0] = 0x1b;
3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[1] = 0x1b;
3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(" ", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Unmappable (mapped to character in default or national locking shift table)
3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[1] = 0x00;
3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("@", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked[1] = 0x7f;
3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("\u00e0", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2));
3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    @SmallTest
3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public void testGsm8BitUpackedWithEuckr() throws Exception {
3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Some feature phones in Korea store contacts as euc-kr.
3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test this situations.
3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        byte unpacked[];
3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test general alphabet strings.
3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = IccUtils.hexStringToBytes("61626320646566FF");
3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("abc def",
3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test korean strings.
3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = IccUtils.hexStringToBytes("C5D7BDBAC6AEFF");
3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals("\uD14C\uC2A4\uD2B8",
3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // Test gsm Extented Characters.
3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars);
3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        assertEquals(sGsmExtendedChars,
3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr"));
3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
363