GsmAlphabetTest.java revision c38bb60d867c5d61d90b7179a9ed2b2d1848124f
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony; 18 19import com.android.internal.telephony.GsmAlphabet; 20 21import junit.framework.TestCase; 22 23import android.test.suitebuilder.annotation.LargeTest; 24import android.test.suitebuilder.annotation.SmallTest; 25 26public class GsmAlphabetTest extends TestCase { 27 28 private static final String sGsmExtendedChars = "{|}\\[~]\f\u20ac"; 29 30 @SmallTest 31 public void test7bitWithHeader() throws Exception { 32 SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); 33 concatRef.refNumber = 1; 34 concatRef.seqNumber = 2; 35 concatRef.msgCount = 2; 36 concatRef.isEightBits = true; 37 SmsHeader header = new SmsHeader(); 38 header.concatRef = concatRef; 39 40 String message = "aaaaaaaaaabbbbbbbbbbcccccccccc"; 41 byte[] userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, 42 SmsHeader.toByteArray(header), 0, 0); 43 int septetCount = GsmAlphabet.countGsmSeptetsUsingTables(message, true, 0, 0); 44 String parsedMessage = GsmAlphabet.gsm7BitPackedToString( 45 userData, SmsHeader.toByteArray(header).length+2, septetCount, 1, 0, 0); 46 assertEquals(message, parsedMessage); 47 } 48 49 // TODO: This method should *really* be a series of individual test methods. 50 // However, it's a SmallTest because it executes quickly. 51 @SmallTest 52 public void testBasic() throws Exception { 53 // '@' maps to char 0 54 assertEquals(0, GsmAlphabet.charToGsm('@')); 55 56 // `a (a with grave accent) maps to last GSM character 57 assertEquals(0x7f, GsmAlphabet.charToGsm('\u00e0')); 58 59 // 60 // These are the extended chars 61 // They should all return GsmAlphabet.GSM_EXTENDED_ESCAPE 62 // 63 64 for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { 65 assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE, 66 GsmAlphabet.charToGsm(sGsmExtendedChars.charAt(i))); 67 68 } 69 70 // euro symbol 71 assertEquals(GsmAlphabet.GSM_EXTENDED_ESCAPE, 72 GsmAlphabet.charToGsm('\u20ac')); 73 74 // An unmappable char (the 'cent' char) maps to a space 75 assertEquals(GsmAlphabet.charToGsm(' '), 76 GsmAlphabet.charToGsm('\u00a2')); 77 78 // unmappable = space = 1 septet 79 assertEquals(1, GsmAlphabet.countGsmSeptets('\u00a2')); 80 81 // 82 // Test extended table 83 // 84 85 for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { 86 assertEquals(sGsmExtendedChars.charAt(i), 87 GsmAlphabet.gsmExtendedToChar( 88 GsmAlphabet.charToGsmExtended(sGsmExtendedChars.charAt(i)))); 89 90 } 91 92 // Unmappable extended char 93 assertEquals(GsmAlphabet.charToGsm(' '), 94 GsmAlphabet.charToGsmExtended('@')); 95 96 // 97 // gsmToChar() 98 // 99 100 assertEquals('@', GsmAlphabet.gsmToChar(0)); 101 102 // `a (a with grave accent) maps to last GSM character 103 assertEquals('\u00e0', GsmAlphabet.gsmToChar(0x7f)); 104 105 assertEquals('\uffff', 106 GsmAlphabet.gsmToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE)); 107 108 // Out-of-range/unmappable value 109 assertEquals(' ', GsmAlphabet.gsmToChar(0x80)); 110 111 // 112 // gsmExtendedToChar() 113 // 114 115 assertEquals('{', GsmAlphabet.gsmExtendedToChar(0x28)); 116 117 // No double-escapes 118 assertEquals(' ', GsmAlphabet.gsmExtendedToChar( 119 GsmAlphabet.GSM_EXTENDED_ESCAPE)); 120 121 // Reserved for extension to extension table (mapped to space) 122 assertEquals(' ', GsmAlphabet.gsmExtendedToChar(GsmAlphabet.GSM_EXTENDED_ESCAPE)); 123 124 // Unmappable (mapped to character in default or national locking shift table) 125 assertEquals('@', GsmAlphabet.gsmExtendedToChar(0)); 126 assertEquals('\u00e0', GsmAlphabet.gsmExtendedToChar(0x7f)); 127 128 // 129 // stringTo7BitPacked, gsm7BitPackedToString 130 // 131 132 byte[] packed; 133 StringBuilder testString = new StringBuilder(300); 134 135 // Check all alignment cases 136 for (int i = 0; i < 9; i++, testString.append('@')) { 137 packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 138 assertEquals(testString.toString(), 139 GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); 140 } 141 142 // Check full non-extended alphabet 143 for (int i = 0; i < 0x80; i++) { 144 char c; 145 146 if (i == GsmAlphabet.GSM_EXTENDED_ESCAPE) { 147 continue; 148 } 149 150 c = GsmAlphabet.gsmToChar(i); 151 testString.append(c); 152 153 // These are all non-extended chars, so it should be 154 // one septet per char 155 assertEquals(1, GsmAlphabet.countGsmSeptets(c)); 156 } 157 158 packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 159 assertEquals(testString.toString(), 160 GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); 161 162 // Test extended chars too 163 164 testString.append(sGsmExtendedChars); 165 166 for (int i = 0, s = sGsmExtendedChars.length(); i < s; i++) { 167 // These are all extended chars, so it should be 168 // two septets per char 169 assertEquals(2, GsmAlphabet.countGsmSeptets(sGsmExtendedChars.charAt(i))); 170 171 } 172 173 packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 174 assertEquals(testString.toString(), 175 GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); 176 177 // stringTo7BitPacked handles up to 255 septets 178 179 testString.setLength(0); 180 for (int i = 0; i < 255; i++) { 181 testString.append('@'); 182 } 183 184 packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 185 assertEquals(testString.toString(), 186 GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); 187 188 // > 255 septets throws runtime exception 189 testString.append('@'); 190 191 try { 192 GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 193 fail("expected exception"); 194 } catch (EncodeException ex) { 195 // exception expected 196 } 197 198 // Try 254 septets with 127 extended chars 199 200 testString.setLength(0); 201 for (int i = 0; i < (255 / 2); i++) { 202 testString.append('{'); 203 } 204 205 packed = GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 206 assertEquals(testString.toString(), 207 GsmAlphabet.gsm7BitPackedToString(packed, 1, 0xff & packed[0])); 208 209 // > 255 septets throws runtime exception 210 testString.append('{'); 211 212 try { 213 GsmAlphabet.stringToGsm7BitPacked(testString.toString(), 0, 0); 214 fail("expected exception"); 215 } catch (EncodeException ex) { 216 // exception expected 217 } 218 219 // Reserved for extension to extension table (mapped to space) 220 packed = new byte[]{(byte)(0x1b | 0x80), 0x1b >> 1}; 221 assertEquals(" ", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2)); 222 223 // Unmappable (mapped to character in default alphabet table) 224 packed[0] = 0x1b; 225 packed[1] = 0x00; 226 assertEquals("@", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2)); 227 packed[0] = (byte)(0x1b | 0x80); 228 packed[1] = (byte)(0x7f >> 1); 229 assertEquals("\u00e0", GsmAlphabet.gsm7BitPackedToString(packed, 0, 2)); 230 231 // 232 // 8 bit unpacked format 233 // 234 // Note: we compare hex strings here 235 // because Assert doesn't have array comparisons 236 237 byte unpacked[]; 238 239 unpacked = IccUtils.hexStringToBytes("566F696365204D61696C"); 240 assertEquals("Voice Mail", 241 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 242 243 assertEquals(IccUtils.bytesToHexString(unpacked), 244 IccUtils.bytesToHexString( 245 GsmAlphabet.stringToGsm8BitPacked("Voice Mail"))); 246 247 unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars); 248 // two bytes for every extended char 249 assertEquals(2 * sGsmExtendedChars.length(), unpacked.length); 250 assertEquals(sGsmExtendedChars, 251 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 252 253 // should be two bytes per extended char 254 assertEquals(2 * sGsmExtendedChars.length(), unpacked.length); 255 256 // Test truncation of unaligned extended chars 257 unpacked = new byte[3]; 258 GsmAlphabet.stringToGsm8BitUnpackedField(sGsmExtendedChars, unpacked, 259 0, unpacked.length); 260 261 // Should be one extended char and an 0xff at the end 262 263 assertEquals(0xff, 0xff & unpacked[2]); 264 assertEquals(sGsmExtendedChars.substring(0, 1), 265 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 266 267 // Test truncation of normal chars 268 unpacked = new byte[3]; 269 GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, 270 0, unpacked.length); 271 272 assertEquals("abc", 273 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 274 275 // Test truncation of mixed normal and extended chars 276 unpacked = new byte[3]; 277 GsmAlphabet.stringToGsm8BitUnpackedField("a{cd", unpacked, 278 0, unpacked.length); 279 280 assertEquals("a{", 281 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 282 283 // Test padding after normal char 284 unpacked = new byte[3]; 285 GsmAlphabet.stringToGsm8BitUnpackedField("a", unpacked, 286 0, unpacked.length); 287 288 assertEquals("a", 289 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 290 291 assertEquals(0xff, 0xff & unpacked[1]); 292 assertEquals(0xff, 0xff & unpacked[2]); 293 294 // Test malformed input -- escape char followed by end of field 295 unpacked[0] = 0; 296 unpacked[1] = 0; 297 unpacked[2] = GsmAlphabet.GSM_EXTENDED_ESCAPE; 298 299 assertEquals("@@", 300 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length)); 301 302 // non-zero offset 303 assertEquals("@", 304 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); 305 306 // test non-zero offset 307 unpacked[0] = 0; 308 GsmAlphabet.stringToGsm8BitUnpackedField("abcd", unpacked, 309 1, unpacked.length - 1); 310 311 312 assertEquals(0, unpacked[0]); 313 314 assertEquals("ab", 315 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); 316 317 // test non-zero offset with truncated extended char 318 unpacked[0] = 0; 319 320 GsmAlphabet.stringToGsm8BitUnpackedField("a{", unpacked, 321 1, unpacked.length - 1); 322 323 assertEquals(0, unpacked[0]); 324 325 assertEquals("a", 326 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 1, unpacked.length - 1)); 327 328 // Reserved for extension to extension table (mapped to space) 329 unpacked[0] = 0x1b; 330 unpacked[1] = 0x1b; 331 assertEquals(" ", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2)); 332 333 // Unmappable (mapped to character in default or national locking shift table) 334 unpacked[1] = 0x00; 335 assertEquals("@", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2)); 336 unpacked[1] = 0x7f; 337 assertEquals("\u00e0", GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, 2)); 338 } 339 340 @SmallTest 341 public void testGsm8BitUpackedWithEuckr() throws Exception { 342 // Some feature phones in Korea store contacts as euc-kr. 343 // Test this situations. 344 byte unpacked[]; 345 346 // Test general alphabet strings. 347 unpacked = IccUtils.hexStringToBytes("61626320646566FF"); 348 assertEquals("abc def", 349 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr")); 350 351 // Test korean strings. 352 unpacked = IccUtils.hexStringToBytes("C5D7BDBAC6AEFF"); 353 assertEquals("\uD14C\uC2A4\uD2B8", 354 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr")); 355 356 // Test gsm Extented Characters. 357 unpacked = GsmAlphabet.stringToGsm8BitPacked(sGsmExtendedChars); 358 assertEquals(sGsmExtendedChars, 359 GsmAlphabet.gsm8BitUnpackedToString(unpacked, 0, unpacked.length, "euc-kr")); 360 } 361} 362