1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1998-2014, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 /* 7 * File test.c 8 * 9 * Modification History: 10 * 11 * Date Name Description 12 * 05/01/2000 Madhu Creation 13 ******************************************************************************* 14 */ 15 16 #include "unicode/utypes.h" 17 #include "unicode/utf16.h" 18 #include "unicode/ustring.h" 19 #include "cmemory.h" 20 #include "cstring.h" 21 #include "cintltst.h" 22 #include <stdio.h> 23 24 static void printUChars(const UChar *uchars); 25 26 static void TestCodeUnitValues(void); 27 static void TestCharLength(void); 28 static void TestGetChar(void); 29 static void TestNextPrevChar(void); 30 static void TestNulTerminated(void); 31 static void TestFwdBack(void); 32 static void TestSetChar(void); 33 static void TestAppendChar(void); 34 static void TestAppend(void); 35 static void TestSurrogate(void); 36 37 void addUTF16Test(TestNode** root); 38 39 void 40 addUTF16Test(TestNode** root) 41 { 42 addTest(root, &TestCodeUnitValues, "utf16tst/TestCodeUnitValues"); 43 addTest(root, &TestCharLength, "utf16tst/TestCharLength"); 44 addTest(root, &TestGetChar, "utf16tst/TestGetChar"); 45 addTest(root, &TestNextPrevChar, "utf16tst/TestNextPrevChar"); 46 addTest(root, &TestNulTerminated, "utf16tst/TestNulTerminated"); 47 addTest(root, &TestFwdBack, "utf16tst/TestFwdBack"); 48 addTest(root, &TestSetChar, "utf16tst/TestSetChar"); 49 addTest(root, &TestAppendChar, "utf16tst/TestAppendChar"); 50 addTest(root, &TestAppend, "utf16tst/TestAppend"); 51 addTest(root, &TestSurrogate, "utf16tst/TestSurrogate"); 52 } 53 54 static void TestCodeUnitValues() 55 { 56 static uint16_t codeunit[]={0x0000,0xe065,0x20ac,0xd7ff,0xd800,0xd841,0xd905,0xdbff,0xdc00,0xdc02,0xddee,0xdfff,0}; 57 58 int16_t i; 59 for(i=0; i<sizeof(codeunit)/sizeof(codeunit[0]); i++){ 60 UChar c=codeunit[i]; 61 log_verbose("Testing code unit value of %x\n", c); 62 if(i<4){ 63 if(!UTF16_IS_SINGLE(c) || UTF16_IS_LEAD(c) || UTF16_IS_TRAIL(c) || !U16_IS_SINGLE(c) || U16_IS_LEAD(c) || U16_IS_TRAIL(c)){ 64 log_err("ERROR: %x is a single character\n", c); 65 } 66 } 67 if(i >= 4 && i< 8){ 68 if(!UTF16_IS_LEAD(c) || UTF16_IS_SINGLE(c) || UTF16_IS_TRAIL(c) || !U16_IS_LEAD(c) || U16_IS_SINGLE(c) || U16_IS_TRAIL(c)){ 69 log_err("ERROR: %x is a first surrogate\n", c); 70 } 71 } 72 if(i >= 8 && i< 12){ 73 if(!UTF16_IS_TRAIL(c) || UTF16_IS_SINGLE(c) || UTF16_IS_LEAD(c) || !U16_IS_TRAIL(c) || U16_IS_SINGLE(c) || U16_IS_LEAD(c)){ 74 log_err("ERROR: %x is a second surrogate\n", c); 75 } 76 } 77 } 78 } 79 80 static void TestCharLength() 81 { 82 static uint32_t codepoint[]={ 83 1, 0x0061, 84 1, 0xe065, 85 1, 0x20ac, 86 2, 0x20402, 87 2, 0x23456, 88 2, 0x24506, 89 2, 0x20402, 90 2, 0x10402, 91 1, 0xd7ff, 92 1, 0xe000 93 }; 94 95 int16_t i; 96 UBool multiple; 97 for(i=0; i<sizeof(codepoint)/sizeof(codepoint[0]); i=(int16_t)(i+2)){ 98 UChar32 c=codepoint[i+1]; 99 if(UTF16_CHAR_LENGTH(c) != (uint16_t)codepoint[i] || U16_LENGTH(c) != (uint16_t)codepoint[i]){ 100 log_err("The no: of code units for %lx:- Expected: %d Got: %d\n", c, codepoint[i], UTF16_CHAR_LENGTH(c)); 101 }else{ 102 log_verbose("The no: of code units for %lx is %d\n",c, UTF16_CHAR_LENGTH(c) ); 103 } 104 multiple=(UBool)(codepoint[i] == 1 ? FALSE : TRUE); 105 if(UTF16_NEED_MULTIPLE_UCHAR(c) != multiple){ 106 log_err("ERROR: UTF16_NEED_MULTIPLE_UCHAR failed for %lx\n", c); 107 } 108 } 109 } 110 111 static void TestGetChar() 112 { 113 static UChar input[]={ 114 /* code unit,*/ 115 0xdc00, 116 0x20ac, 117 0xd841, 118 0x61, 119 0xd841, 120 0xdc02, 121 0xd842, 122 0xdc06, 123 0, 124 0xd842, 125 0xd7ff, 126 0xdc41, 127 0xe000, 128 0xd800 129 }; 130 static UChar32 result[]={ 131 /*codepoint-unsafe, codepoint-safe(not strict) codepoint-safe(strict)*/ 132 (UChar32)0xfca10000, 0xdc00, UTF_ERROR_VALUE, 133 0x20ac, 0x20ac, 0x20ac, 134 0x12861, 0xd841, UTF_ERROR_VALUE, 135 0x61, 0x61, 0x61, 136 0x20402, 0x20402, 0x20402, 137 0x20402, 0x20402, 0x20402, 138 0x20806, 0x20806, 0x20806, 139 0x20806, 0x20806, 0x20806, 140 0x00, 0x00, 0x00, 141 0x203ff, 0xd842, UTF_ERROR_VALUE, 142 0xd7ff, 0xd7ff, 0xd7ff, 143 0xfc41, 0xdc41, UTF_ERROR_VALUE, 144 0xe000, 0xe000, 0xe000, 145 0x11734, 0xd800, UTF_ERROR_VALUE 146 }; 147 uint16_t i=0; 148 UChar32 c; 149 uint16_t offset=0; 150 for(offset=0; offset<sizeof(input)/U_SIZEOF_UCHAR; offset++) { 151 if(0<offset && offset<sizeof(input)/U_SIZEOF_UCHAR-1){ 152 UTF16_GET_CHAR_UNSAFE(input, offset, c); 153 if(c != result[i]){ 154 log_err("ERROR: UTF16_GET_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c); 155 } 156 157 U16_GET_UNSAFE(input, offset, c); 158 if(c != result[i]){ 159 log_err("ERROR: U16_GET_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c); 160 } 161 } 162 163 UTF16_GET_CHAR_SAFE(input, 0, offset, sizeof(input)/U_SIZEOF_UCHAR, c, FALSE); 164 if(c != result[i+1]){ 165 log_err("ERROR: UTF16_GET_CHAR_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c); 166 } 167 168 U16_GET(input, 0, offset, sizeof(input)/U_SIZEOF_UCHAR, c); 169 if(c != result[i+1]){ 170 log_err("ERROR: U16_GET failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c); 171 } 172 173 UTF16_GET_CHAR_SAFE(input, 0, offset, sizeof(input)/U_SIZEOF_UCHAR, c, TRUE); 174 if(c != result[i+2]){ 175 log_err("ERROR: UTF16_GET_CHAR_SAFE(strict) failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c); 176 } 177 i=(uint16_t)(i+3); 178 } 179 180 } 181 182 static void TestNextPrevChar(){ 183 184 static UChar input[]={0x0061, 0xd800, 0xdc00, 0xdbff, 0xdfff, 0x0062, 0xd841, 0xd7ff, 0xd841, 0xdc41, 0xdc00, 0x0000}; 185 static UChar32 result[]={ 186 /*next_unsafe next_safe_ns next_safe_s prev_unsafe prev_safe_ns prev_safe_s*/ 187 0x0061, 0x0061, 0x0061, 0x0000, 0x0000, 0x0000, 188 0x10000, 0x10000, 0x10000, 0x120400, 0xdc00, UTF_ERROR_VALUE, 189 0xdc00, 0xdc00, UTF_ERROR_VALUE, 0x20441, 0x20441, 0x20441, 190 0x10ffff, 0x10ffff, 0x10ffff, 0xd841, 0xd841, UTF_ERROR_VALUE, 191 0xdfff, 0xdfff, UTF_ERROR_VALUE, 0xd7ff, 0xd7ff, 0xd7ff, 192 0x0062, 0x0062, 0x0062, 0xd841, 0xd841, UTF_ERROR_VALUE, 193 0x1ffff, 0xd841, UTF_ERROR_VALUE, 0x0062, 0x0062, 0x0062, 194 0xd7ff, 0xd7ff, 0xd7ff, 0x10ffff, 0x10ffff, 0x10ffff, 195 0x20441, 0x20441, 0x20441, 0xdbff, 0xdbff, UTF_ERROR_VALUE, 196 0xdc41, 0xdc41, UTF_ERROR_VALUE, 0x10000, 0x10000, 0x10000, 197 0xdc00, 0xdc00, UTF_ERROR_VALUE, 0xd800, 0xd800, UTF_ERROR_VALUE, 198 0x0000, 0x0000, 0x0000, 0x0061, 0x0061, 0x0061 199 }; 200 static uint16_t movedOffset[]={ 201 /*next_unsafe next_safe_ns next_safe_s prev_unsafe prev_safe_ns prev_safe_s*/ 202 1, 1, 1, 11, 11, 11, 203 3, 3, 3, 9, 10 , 10, 204 3, 3, 3, 8, 8, 8, 205 5, 5, 4, 8, 8, 8, 206 5, 5, 5, 7, 7, 7, 207 6, 6, 6, 6, 6, 6, 208 8, 7, 7, 5, 5, 5, 209 8, 8, 8, 3, 3, 3, 210 10, 10, 10, 3, 3, 3, 211 10, 10, 10, 1, 1, 1, 212 11, 11, 11, 1, 1, 1, 213 12, 12, 12, 0, 0, 0, 214 }; 215 216 217 UChar32 c=0x0000; 218 uint16_t i=0; 219 uint16_t offset=0, setOffset=0; 220 for(offset=0; offset<sizeof(input)/U_SIZEOF_UCHAR; offset++){ 221 setOffset=offset; 222 UTF16_NEXT_CHAR_UNSAFE(input, setOffset, c); 223 if(setOffset != movedOffset[i]){ 224 log_err("ERROR: UTF16_NEXT_CHAR_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 225 offset, movedOffset[i], setOffset); 226 } 227 if(c != result[i]){ 228 log_err("ERROR: UTF16_NEXT_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c); 229 } 230 231 setOffset=offset; 232 U16_NEXT_UNSAFE(input, setOffset, c); 233 if(setOffset != movedOffset[i]){ 234 log_err("ERROR: U16_NEXT_CHAR_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 235 offset, movedOffset[i], setOffset); 236 } 237 if(c != result[i]){ 238 log_err("ERROR: U16_NEXT_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c); 239 } 240 241 setOffset=offset; 242 UTF16_NEXT_CHAR_SAFE(input, setOffset, sizeof(input)/U_SIZEOF_UCHAR, c, FALSE); 243 if(setOffset != movedOffset[i+1]){ 244 log_err("ERROR: UTF16_NEXT_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 245 offset, movedOffset[i+1], setOffset); 246 } 247 if(c != result[i+1]){ 248 log_err("ERROR: UTF16_NEXT_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c); 249 } 250 251 setOffset=offset; 252 U16_NEXT(input, setOffset, sizeof(input)/U_SIZEOF_UCHAR, c); 253 if(setOffset != movedOffset[i+1]){ 254 log_err("ERROR: U16_NEXT failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 255 offset, movedOffset[i+1], setOffset); 256 } 257 if(c != result[i+1]){ 258 log_err("ERROR: U16_NEXT failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+1], c); 259 } 260 261 setOffset=offset; 262 UTF16_NEXT_CHAR_SAFE(input, setOffset, sizeof(input)/U_SIZEOF_UCHAR, c, TRUE); 263 if(setOffset != movedOffset[i+1]){ 264 log_err("ERROR: UTF16_NEXT_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 265 offset, movedOffset[i+2], setOffset); 266 } 267 if(c != result[i+2]){ 268 log_err("ERROR: UTF16_NEXT_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c); 269 } 270 271 i=(uint16_t)(i+6); 272 } 273 i=0; 274 for(offset=(uint16_t)sizeof(input)/U_SIZEOF_UCHAR; offset > 0; --offset){ 275 setOffset=offset; 276 UTF16_PREV_CHAR_UNSAFE(input, setOffset, c); 277 if(setOffset != movedOffset[i+3]){ 278 log_err("ERROR: UTF16_PREV_CHAR_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 279 offset, movedOffset[i+3], setOffset); 280 } 281 if(c != result[i+3]){ 282 log_err("ERROR: UTF16_PREV_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+3], c); 283 } 284 285 setOffset=offset; 286 U16_PREV_UNSAFE(input, setOffset, c); 287 if(setOffset != movedOffset[i+3]){ 288 log_err("ERROR: U16_PREV_CHAR_UNSAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 289 offset, movedOffset[i+3], setOffset); 290 } 291 if(c != result[i+3]){ 292 log_err("ERROR: U16_PREV_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+3], c); 293 } 294 295 setOffset=offset; 296 UTF16_PREV_CHAR_SAFE(input, 0, setOffset, c, FALSE); 297 if(setOffset != movedOffset[i+4]){ 298 log_err("ERROR: UTF16_PREV_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 299 offset, movedOffset[i+4], setOffset); 300 } 301 if(c != result[i+4]){ 302 log_err("ERROR: UTF16_PREV_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+4], c); 303 } 304 305 setOffset=offset; 306 U16_PREV(input, 0, setOffset, c); 307 if(setOffset != movedOffset[i+4]){ 308 log_err("ERROR: U16_PREV failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 309 offset, movedOffset[i+4], setOffset); 310 } 311 if(c != result[i+4]){ 312 log_err("ERROR: U16_PREV failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+4], c); 313 } 314 315 setOffset=offset; 316 UTF16_PREV_CHAR_SAFE(input, 0, setOffset, c, TRUE); 317 if(setOffset != movedOffset[i+5]){ 318 log_err("ERROR: UTF16_PREV_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n", 319 offset, movedOffset[i+5], setOffset); 320 } 321 if(c != result[i+5]){ 322 log_err("ERROR: UTF16_PREV_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+5], c); 323 } 324 325 i=(uint16_t)(i+6); 326 } 327 328 } 329 330 /* keep this in sync with utf8tst.c's TestNulTerminated() */ 331 static void TestNulTerminated() { 332 static const UChar input[]={ 333 /* 0 */ 0x61, 334 /* 1 */ 0xd801, 0xdc01, 335 /* 3 */ 0xdc01, 336 /* 4 */ 0x62, 337 /* 5 */ 0xd801, 338 /* 6 */ 0x00 339 /* 7 */ 340 }; 341 static const UChar32 result[]={ 342 0x61, 343 0x10401, 344 0xdc01, 345 0x62, 346 0xd801, 347 0 348 }; 349 350 UChar32 c, c2; 351 int32_t i0, i=0, j, k, expectedIndex; 352 int32_t cpIndex=0; 353 do { 354 i0=i; 355 U16_NEXT(input, i, -1, c); 356 if(c!=result[cpIndex]) { 357 log_err("U16_NEXT(from %d)=U+%04x != U+%04x\n", i0, c, result[cpIndex]); 358 } 359 j=i0; 360 U16_FWD_1(input, j, -1); 361 if(j!=i) { 362 log_err("U16_FWD_1() moved to index %d but U16_NEXT() moved to %d\n", j, i); 363 } 364 ++cpIndex; 365 /* 366 * Move by this many code points from the start. 367 * U16_FWD_N() stops at the end of the string, that is, at the NUL if necessary. 368 */ 369 expectedIndex= (c==0) ? i-1 : i; 370 k=0; 371 U16_FWD_N(input, k, -1, cpIndex); 372 if(k!=expectedIndex) { 373 log_err("U16_FWD_N(code points from 0) moved to index %d but expected %d\n", k, expectedIndex); 374 } 375 } while(c!=0); 376 377 i=0; 378 do { 379 j=i0=i; 380 U16_NEXT(input, i, -1, c); 381 do { 382 U16_GET(input, 0, j, -1, c2); 383 if(c2!=c) { 384 log_err("U16_NEXT(from %d)=U+%04x != U+%04x=U16_GET(at %d)\n", i0, c, c2, j); 385 } 386 /* U16_SET_CP_LIMIT moves from a non-lead byte to the limit of the code point */ 387 k=j+1; 388 U16_SET_CP_LIMIT(input, 0, k, -1); 389 if(k!=i) { 390 log_err("U16_NEXT() moved to %d but U16_SET_CP_LIMIT(%d) moved to %d\n", i, j+1, k); 391 } 392 } while(++j<i); 393 } while(c!=0); 394 } 395 396 static void TestFwdBack(){ 397 static UChar input[]={0x0061, 0xd800, 0xdc00, 0xdbff, 0xdfff, 0x0062, 0xd841, 0xd7ff, 0xd841, 0xdc41, 0xdc00, 0x0000}; 398 static uint16_t fwd_unsafe[] ={1, 3, 5, 6, 8, 10, 11, 12}; 399 static uint16_t fwd_safe[] ={1, 3, 5, 6, 7, 8, 10, 11, 12}; 400 static uint16_t back_unsafe[]={11, 9, 8, 7, 6, 5, 3, 1, 0}; 401 static uint16_t back_safe[] ={11, 10, 8, 7, 6, 5, 3, 1, 0}; 402 403 static uint16_t Nvalue[]= {0, 1, 2, 3, 1, 2, 1}; 404 static uint16_t fwd_N_unsafe[] ={0, 1, 5, 10, 11}; 405 static uint16_t fwd_N_safe[] ={0, 1, 5, 8, 10, 12, 12}; /*safe macro keeps it at the end of the string */ 406 static uint16_t back_N_unsafe[]={12, 11, 8, 5, 3}; 407 static uint16_t back_N_safe[] ={12, 11, 8, 5, 3, 0, 0}; 408 409 uint16_t offunsafe=0, offsafe=0; 410 uint16_t i=0; 411 while(offunsafe < sizeof(input)/U_SIZEOF_UCHAR){ 412 UTF16_FWD_1_UNSAFE(input, offunsafe); 413 if(offunsafe != fwd_unsafe[i]){ 414 log_err("ERROR: Forward_unsafe offset expected:%d, Got:%d\n", fwd_unsafe[i], offunsafe); 415 } 416 i++; 417 } 418 419 offunsafe=0, offsafe=0; 420 i=0; 421 while(offunsafe < sizeof(input)/U_SIZEOF_UCHAR){ 422 U16_FWD_1_UNSAFE(input, offunsafe); 423 if(offunsafe != fwd_unsafe[i]){ 424 log_err("ERROR: U16_FWD_1_UNSAFE offset expected:%d, Got:%d\n", fwd_unsafe[i], offunsafe); 425 } 426 i++; 427 } 428 429 i=0; 430 while(offsafe < sizeof(input)/U_SIZEOF_UCHAR){ 431 UTF16_FWD_1_SAFE(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR); 432 if(offsafe != fwd_safe[i]){ 433 log_err("ERROR: Forward_safe offset expected:%d, Got:%d\n", fwd_safe[i], offsafe); 434 } 435 i++; 436 } 437 438 i=0; 439 while(offsafe < sizeof(input)/U_SIZEOF_UCHAR){ 440 U16_FWD_1(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR); 441 if(offsafe != fwd_safe[i]){ 442 log_err("ERROR: U16_FWD_1 offset expected:%d, Got:%d\n", fwd_safe[i], offsafe); 443 } 444 i++; 445 } 446 447 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 448 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 449 i=0; 450 while(offunsafe > 0){ 451 UTF16_BACK_1_UNSAFE(input, offunsafe); 452 if(offunsafe != back_unsafe[i]){ 453 log_err("ERROR: Backward_unsafe offset expected:%d, Got:%d\n", back_unsafe[i], offunsafe); 454 } 455 i++; 456 } 457 458 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 459 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 460 i=0; 461 while(offunsafe > 0){ 462 U16_BACK_1_UNSAFE(input, offunsafe); 463 if(offunsafe != back_unsafe[i]){ 464 log_err("ERROR: U16_BACK_1_UNSAFE offset expected:%d, Got:%d\n", back_unsafe[i], offunsafe); 465 } 466 i++; 467 } 468 469 i=0; 470 while(offsafe > 0){ 471 UTF16_BACK_1_SAFE(input,0, offsafe); 472 if(offsafe != back_safe[i]){ 473 log_err("ERROR: Backward_safe offset expected:%d, Got:%d\n", back_unsafe[i], offsafe); 474 } 475 i++; 476 } 477 478 i=0; 479 while(offsafe > 0){ 480 U16_BACK_1(input,0, offsafe); 481 if(offsafe != back_safe[i]){ 482 log_err("ERROR: U16_BACK_1 offset expected:%d, Got:%d\n", back_unsafe[i], offsafe); 483 } 484 i++; 485 } 486 487 offunsafe=0; 488 offsafe=0; 489 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ /*didn't want it to fail(we assume 0<i<length)*/ 490 UTF16_FWD_N_UNSAFE(input, offunsafe, Nvalue[i]); 491 if(offunsafe != fwd_N_unsafe[i]){ 492 log_err("ERROR: Forward_N_unsafe offset expected:%d, Got:%d\n", fwd_N_unsafe[i], offunsafe); 493 } 494 } 495 496 offunsafe=0; 497 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ /*didn't want it to fail(we assume 0<i<length)*/ 498 U16_FWD_N_UNSAFE(input, offunsafe, Nvalue[i]); 499 if(offunsafe != fwd_N_unsafe[i]){ 500 log_err("ERROR: U16_FWD_N_UNSAFE offset expected:%d, Got:%d\n", fwd_N_unsafe[i], offunsafe); 501 } 502 } 503 504 offsafe=0; 505 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 506 UTF16_FWD_N_SAFE(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR, Nvalue[i]); 507 if(offsafe != fwd_N_safe[i]){ 508 log_err("ERROR: Forward_N_safe offset expected:%d, Got:%d\n", fwd_N_safe[i], offsafe); 509 } 510 511 } 512 513 offsafe=0; 514 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 515 U16_FWD_N(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR, Nvalue[i]); 516 if(offsafe != fwd_N_safe[i]){ 517 log_err("ERROR: U16_FWD_N offset expected:%d, Got:%d\n", fwd_N_safe[i], offsafe); 518 } 519 520 } 521 522 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 523 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ 524 UTF16_BACK_N_UNSAFE(input, offunsafe, Nvalue[i]); 525 if(offunsafe != back_N_unsafe[i]){ 526 log_err("ERROR: backward_N_unsafe offset expected:%d, Got:%d\n", back_N_unsafe[i], offunsafe); 527 } 528 } 529 530 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 531 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ 532 U16_BACK_N_UNSAFE(input, offunsafe, Nvalue[i]); 533 if(offunsafe != back_N_unsafe[i]){ 534 log_err("ERROR: U16_BACK_N_UNSAFE offset expected:%d, Got:%d\n", back_N_unsafe[i], offunsafe); 535 } 536 } 537 538 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 539 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 540 UTF16_BACK_N_SAFE(input, 0, offsafe, Nvalue[i]); 541 if(offsafe != back_N_safe[i]){ 542 log_err("ERROR: backward_N_safe offset expected:%d, Got:%d\n", back_N_safe[i], offsafe); 543 } 544 } 545 546 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 547 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 548 U16_BACK_N(input, 0, offsafe, Nvalue[i]); 549 if(offsafe != back_N_safe[i]){ 550 log_err("ERROR: U16_BACK_N offset expected:%d, Got:%d\n", back_N_safe[i], offsafe); 551 } 552 } 553 } 554 555 static void TestSetChar(){ 556 static UChar input[]={0x0061, 0xd800, 0xdc00, 0xdbff, 0xdfff, 0x0062, 0xd841, 0xd7ff, 0xd841, 0xdc41, 0xdc00, 0x0000}; 557 static uint16_t start_unsafe[]={0, 1, 1, 3, 3, 5, 6, 7, 8, 8, 9, 11}; 558 static uint16_t start_safe[] ={0, 1, 1, 3, 3, 5, 6, 7, 8, 8, 10, 11}; 559 static uint16_t limit_unsafe[]={0, 1, 3, 3, 5, 5, 6, 8, 8, 10, 10, 11}; 560 static uint16_t limit_safe[] ={0, 1, 3, 3, 5, 5, 6, 7, 8, 10, 10, 11}; 561 562 uint16_t i=0; 563 uint16_t offset=0, setOffset=0; 564 for(offset=0; offset<sizeof(input)/U_SIZEOF_UCHAR; offset++){ 565 setOffset=offset; 566 UTF16_SET_CHAR_START_UNSAFE(input, setOffset); 567 if(setOffset != start_unsafe[i]){ 568 log_err("ERROR: UTF16_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_unsafe[i], setOffset); 569 } 570 571 setOffset=offset; 572 U16_SET_CP_START_UNSAFE(input, setOffset); 573 if(setOffset != start_unsafe[i]){ 574 log_err("ERROR: U16_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_unsafe[i], setOffset); 575 } 576 577 setOffset=offset; 578 UTF16_SET_CHAR_START_SAFE(input, 0, setOffset); 579 if(setOffset != start_safe[i]){ 580 log_err("ERROR: UTF16_SET_CHAR_START_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_safe[i], setOffset); 581 } 582 583 setOffset=offset; 584 U16_SET_CP_START(input, 0, setOffset); 585 if(setOffset != start_safe[i]){ 586 log_err("ERROR: U16_SET_CHAR_START failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_safe[i], setOffset); 587 } 588 589 if (offset > 0) { 590 setOffset=offset; 591 UTF16_SET_CHAR_LIMIT_UNSAFE(input, setOffset); 592 if(setOffset != limit_unsafe[i]){ 593 log_err("ERROR: UTF16_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, limit_unsafe[i], setOffset); 594 } 595 596 setOffset=offset; 597 U16_SET_CP_LIMIT_UNSAFE(input, setOffset); 598 if(setOffset != limit_unsafe[i]){ 599 log_err("ERROR: U16_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, limit_unsafe[i], setOffset); 600 } 601 } 602 603 setOffset=offset; 604 U16_SET_CP_LIMIT(input,0, setOffset, sizeof(input)/U_SIZEOF_UCHAR); 605 if(setOffset != limit_safe[i]){ 606 log_err("ERROR: U16_SET_CHAR_LIMIT failed for offset=%ld. Expected:%lx Got:%lx\n", offset, limit_safe[i], setOffset); 607 } 608 609 i++; 610 } 611 } 612 613 static void TestAppendChar(){ 614 static UChar s[5]={0x0061, 0x0062, 0x0063, 0x0064, 0x0000}; 615 static uint32_t test[]={ 616 /*append-position(unsafe), CHAR to be appended */ 617 0, 0x20441, 618 2, 0x0028, 619 2, 0xdc00, 620 3, 0xd800, 621 1, 0x20402, 622 623 /*append-position(safe), CHAR to be appended */ 624 0, 0x20441, 625 2, 0xdc00, 626 3, 0xd800, 627 1, 0x20402, 628 3, 0x20402, 629 3, 0x10402, 630 2, 0x10402, 631 632 }; 633 static uint16_t movedOffset[]={ 634 /*offset-moved-to(unsafe)*/ 635 2, /*for append-pos: 0 , CHAR 0x20441*/ 636 3, 637 3, 638 4, 639 3, 640 /*offse-moved-to(safe)*/ 641 2, /*for append-pos: 0, CHAR 0x20441*/ 642 3, 643 4, 644 3, 645 4, 646 4, 647 4 648 }; 649 650 static UChar result[][5]={ 651 /*unsafe*/ 652 {0xd841, 0xdc41, 0x0063, 0x0064, 0x0000}, 653 {0x0061, 0x0062, 0x0028, 0x0064, 0x0000}, 654 {0x0061, 0x0062, 0xdc00, 0x0064, 0x0000}, 655 {0x0061, 0x0062, 0x0063, 0xd800, 0x0000}, 656 {0x0061, 0xd841, 0xdc02, 0x0064, 0x0000}, 657 658 /*safe*/ 659 {0xd841, 0xdc41, 0x0063, 0x0064, 0x0000}, 660 {0x0061, 0x0062, 0xdc00, 0x0064, 0x0000}, 661 {0x0061, 0x0062, 0x0063, 0xd800, 0x0000}, 662 {0x0061, 0xd841, 0xdc02, 0x0064, 0x0000}, 663 {0x0061, 0x0062, 0x0063, UTF_ERROR_VALUE, 0x0000}, 664 {0x0061, 0x0062, 0x0063, UTF_ERROR_VALUE, 0x0000}, 665 {0x0061, 0x0062, 0xd801, 0xdc02, 0x0000}, 666 667 668 }; 669 uint16_t i, count=0; 670 UChar *str=(UChar*)malloc(sizeof(UChar) * (u_strlen(s)+1)); 671 uint16_t offset; 672 for(i=0; i<sizeof(test)/sizeof(test[0]); i=(uint16_t)(i+2)){ 673 if(count<5){ 674 u_strcpy(str, s); 675 offset=(uint16_t)test[i]; 676 UTF16_APPEND_CHAR_UNSAFE(str, offset, test[i+1]); 677 if(offset != movedOffset[count]){ 678 log_err("ERROR: UTF16_APPEND_CHAR_UNSAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d currentOffset=%d\n", 679 count, movedOffset[count], offset); 680 681 } 682 if(u_strcmp(str, result[count]) !=0){ 683 log_err("ERROR: UTF16_APPEND_CHAR_UNSAFE failed for count=%d. Expected:", count); 684 printUChars(result[count]); 685 printf("\nGot:"); 686 printUChars(str); 687 printf("\n"); 688 } 689 }else{ 690 u_strcpy(str, s); 691 offset=(uint16_t)test[i]; 692 UTF16_APPEND_CHAR_SAFE(str, offset, (uint16_t)u_strlen(str), test[i+1]); 693 if(offset != movedOffset[count]){ 694 log_err("ERROR: UTF16_APPEND_CHAR_SAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d currentOffset=%d\n", 695 count, movedOffset[count], offset); 696 697 } 698 if(u_strcmp(str, result[count]) !=0){ 699 log_err("ERROR: UTF16_APPEND_CHAR_SAFE failed for count=%d. Expected:", count); 700 printUChars(result[count]); 701 printf("\nGot:"); 702 printUChars(str); 703 printf("\n"); 704 } 705 } 706 count++; 707 } 708 free(str); 709 710 } 711 712 static void TestAppend() { 713 static const UChar32 codePoints[]={ 714 0x61, 0xdf, 0x901, 0x3040, 715 0xac00, 0xd800, 0xdbff, 0xdcde, 716 0xdffd, 0xe000, 0xffff, 0x10000, 717 0x12345, 0xe0021, 0x10ffff, 0x110000, 718 0x234567, 0x7fffffff, -1, -1000, 719 0, 0x400 720 }; 721 static const UChar expectUnsafe[]={ 722 0x61, 0xdf, 0x901, 0x3040, 723 0xac00, 0xd800, 0xdbff, 0xdcde, 724 0xdffd, 0xe000, 0xffff, 0xd800, 0xdc00, 725 0xd808, 0xdf45, 0xdb40, 0xdc21, 0xdbff, 0xdfff, /* not 0x110000 */ 726 /* none from this line */ 727 0, 0x400 728 }, expectSafe[]={ 729 0x61, 0xdf, 0x901, 0x3040, 730 0xac00, 0xd800, 0xdbff, 0xdcde, 731 0xdffd, 0xe000, 0xffff, 0xd800, 0xdc00, 732 0xd808, 0xdf45, 0xdb40, 0xdc21, 0xdbff, 0xdfff, /* not 0x110000 */ 733 /* none from this line */ 734 0, 0x400 735 }; 736 737 UChar buffer[100]; 738 UChar32 c; 739 int32_t i, length; 740 UBool isError, expectIsError, wrongIsError; 741 742 length=0; 743 for(i=0; i<UPRV_LENGTHOF(codePoints); ++i) { 744 c=codePoints[i]; 745 if(c<0 || 0x10ffff<c) { 746 continue; /* skip non-code points for U16_APPEND_UNSAFE */ 747 } 748 749 U16_APPEND_UNSAFE(buffer, length, c); 750 } 751 if(length!=UPRV_LENGTHOF(expectUnsafe) || 0!=memcmp(buffer, expectUnsafe, length*U_SIZEOF_UCHAR)) { 752 log_err("U16_APPEND_UNSAFE did not generate the expected output\n"); 753 } 754 755 length=0; 756 wrongIsError=FALSE; 757 for(i=0; i<UPRV_LENGTHOF(codePoints); ++i) { 758 c=codePoints[i]; 759 expectIsError= c<0 || 0x10ffff<c; /* || U_IS_SURROGATE(c); */ /* surrogates in UTF-32 shouldn't be used, but it's okay to pass them around internally. */ 760 isError=FALSE; 761 762 U16_APPEND(buffer, length, UPRV_LENGTHOF(buffer), c, isError); 763 wrongIsError|= isError!=expectIsError; 764 } 765 if(wrongIsError) { 766 log_err("U16_APPEND did not set isError correctly\n"); 767 } 768 if(length!=UPRV_LENGTHOF(expectSafe) || 0!=memcmp(buffer, expectSafe, length*U_SIZEOF_UCHAR)) { 769 log_err("U16_APPEND did not generate the expected output\n"); 770 } 771 } 772 773 static void TestSurrogate(){ 774 static UChar32 s[] = {0x10000, 0x10ffff, 0x50000, 0x100000, 0x1abcd}; 775 int i = 0; 776 while (i < 5) { 777 UChar first = UTF_FIRST_SURROGATE(s[i]); 778 UChar second = UTF_SECOND_SURROGATE(s[i]); 779 /* algorithm from the Unicode consortium */ 780 UChar firstresult = (UChar)(((s[i] - 0x10000) / 0x400) + 0xD800); 781 UChar secondresult = (UChar)(((s[i] - 0x10000) % 0x400) + 0xDC00); 782 783 if (first != UTF16_LEAD(s[i]) || first != U16_LEAD(s[i]) || first != firstresult) { 784 log_err("Failure in first surrogate in 0x%x expected to be 0x%x\n", 785 s[i], firstresult); 786 } 787 if (second != UTF16_TRAIL(s[i]) || second != U16_TRAIL(s[i]) || second != secondresult) { 788 log_err("Failure in second surrogate in 0x%x expected to be 0x%x\n", 789 s[i], secondresult); 790 } 791 i ++; 792 } 793 } 794 795 static void printUChars(const UChar *uchars){ 796 int16_t i=0; 797 for(i=0; i<u_strlen(uchars); i++){ 798 printf("%x ", *(uchars+i)); 799 } 800 } 801