1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1998-2001, 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 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0])) 25 26 static void printUChars(const UChar *uchars); 27 28 static void TestCodeUnitValues(void); 29 static void TestCharLength(void); 30 static void TestGetChar(void); 31 static void TestNextPrevChar(void); 32 static void TestFwdBack(void); 33 static void TestSetChar(void); 34 static void TestAppendChar(void); 35 static void TestAppend(void); 36 static void TestSurrogate(void); 37 38 void addUTF16Test(TestNode** root); 39 40 void 41 addUTF16Test(TestNode** root) 42 { 43 addTest(root, &TestCodeUnitValues, "utf16tst/TestCodeUnitValues"); 44 addTest(root, &TestCharLength, "utf16tst/TestCharLength" ); 45 addTest(root, &TestGetChar, "utf16tst/TestGetChar" ); 46 addTest(root, &TestNextPrevChar, "utf16tst/TestNextPrevChar" ); 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 static void TestFwdBack(){ 331 static UChar input[]={0x0061, 0xd800, 0xdc00, 0xdbff, 0xdfff, 0x0062, 0xd841, 0xd7ff, 0xd841, 0xdc41, 0xdc00, 0x0000}; 332 static uint16_t fwd_unsafe[] ={1, 3, 5, 6, 8, 10, 11, 12}; 333 static uint16_t fwd_safe[] ={1, 3, 5, 6, 7, 8, 10, 11, 12}; 334 static uint16_t back_unsafe[]={11, 9, 8, 7, 6, 5, 3, 1, 0}; 335 static uint16_t back_safe[] ={11, 10, 8, 7, 6, 5, 3, 1, 0}; 336 337 static uint16_t Nvalue[]= {0, 1, 2, 3, 1, 2, 1}; 338 static uint16_t fwd_N_unsafe[] ={0, 1, 5, 10, 11}; 339 static uint16_t fwd_N_safe[] ={0, 1, 5, 8, 10, 12, 12}; /*safe macro keeps it at the end of the string */ 340 static uint16_t back_N_unsafe[]={12, 11, 8, 5, 3}; 341 static uint16_t back_N_safe[] ={12, 11, 8, 5, 3, 0, 0}; 342 343 uint16_t offunsafe=0, offsafe=0; 344 uint16_t i=0; 345 while(offunsafe < sizeof(input)/U_SIZEOF_UCHAR){ 346 UTF16_FWD_1_UNSAFE(input, offunsafe); 347 if(offunsafe != fwd_unsafe[i]){ 348 log_err("ERROR: Forward_unsafe offset expected:%d, Got:%d\n", fwd_unsafe[i], offunsafe); 349 } 350 i++; 351 } 352 353 offunsafe=0, offsafe=0; 354 i=0; 355 while(offunsafe < sizeof(input)/U_SIZEOF_UCHAR){ 356 U16_FWD_1_UNSAFE(input, offunsafe); 357 if(offunsafe != fwd_unsafe[i]){ 358 log_err("ERROR: U16_FWD_1_UNSAFE offset expected:%d, Got:%d\n", fwd_unsafe[i], offunsafe); 359 } 360 i++; 361 } 362 363 i=0; 364 while(offsafe < sizeof(input)/U_SIZEOF_UCHAR){ 365 UTF16_FWD_1_SAFE(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR); 366 if(offsafe != fwd_safe[i]){ 367 log_err("ERROR: Forward_safe offset expected:%d, Got:%d\n", fwd_safe[i], offsafe); 368 } 369 i++; 370 } 371 372 i=0; 373 while(offsafe < sizeof(input)/U_SIZEOF_UCHAR){ 374 U16_FWD_1(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR); 375 if(offsafe != fwd_safe[i]){ 376 log_err("ERROR: U16_FWD_1 offset expected:%d, Got:%d\n", fwd_safe[i], offsafe); 377 } 378 i++; 379 } 380 381 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 382 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 383 i=0; 384 while(offunsafe > 0){ 385 UTF16_BACK_1_UNSAFE(input, offunsafe); 386 if(offunsafe != back_unsafe[i]){ 387 log_err("ERROR: Backward_unsafe offset expected:%d, Got:%d\n", back_unsafe[i], offunsafe); 388 } 389 i++; 390 } 391 392 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 393 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 394 i=0; 395 while(offunsafe > 0){ 396 U16_BACK_1_UNSAFE(input, offunsafe); 397 if(offunsafe != back_unsafe[i]){ 398 log_err("ERROR: U16_BACK_1_UNSAFE offset expected:%d, Got:%d\n", back_unsafe[i], offunsafe); 399 } 400 i++; 401 } 402 403 i=0; 404 while(offsafe > 0){ 405 UTF16_BACK_1_SAFE(input,0, offsafe); 406 if(offsafe != back_safe[i]){ 407 log_err("ERROR: Backward_safe offset expected:%d, Got:%d\n", back_unsafe[i], offsafe); 408 } 409 i++; 410 } 411 412 i=0; 413 while(offsafe > 0){ 414 U16_BACK_1(input,0, offsafe); 415 if(offsafe != back_safe[i]){ 416 log_err("ERROR: U16_BACK_1 offset expected:%d, Got:%d\n", back_unsafe[i], offsafe); 417 } 418 i++; 419 } 420 421 offunsafe=0; 422 offsafe=0; 423 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ /*didn't want it to fail(we assume 0<i<length)*/ 424 UTF16_FWD_N_UNSAFE(input, offunsafe, Nvalue[i]); 425 if(offunsafe != fwd_N_unsafe[i]){ 426 log_err("ERROR: Forward_N_unsafe offset expected:%d, Got:%d\n", fwd_N_unsafe[i], offunsafe); 427 } 428 } 429 430 offunsafe=0; 431 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ /*didn't want it to fail(we assume 0<i<length)*/ 432 U16_FWD_N_UNSAFE(input, offunsafe, Nvalue[i]); 433 if(offunsafe != fwd_N_unsafe[i]){ 434 log_err("ERROR: U16_FWD_N_UNSAFE offset expected:%d, Got:%d\n", fwd_N_unsafe[i], offunsafe); 435 } 436 } 437 438 offsafe=0; 439 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 440 UTF16_FWD_N_SAFE(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR, Nvalue[i]); 441 if(offsafe != fwd_N_safe[i]){ 442 log_err("ERROR: Forward_N_safe offset expected:%d, Got:%d\n", fwd_N_safe[i], offsafe); 443 } 444 445 } 446 447 offsafe=0; 448 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 449 U16_FWD_N(input, offsafe, sizeof(input)/U_SIZEOF_UCHAR, Nvalue[i]); 450 if(offsafe != fwd_N_safe[i]){ 451 log_err("ERROR: U16_FWD_N offset expected:%d, Got:%d\n", fwd_N_safe[i], offsafe); 452 } 453 454 } 455 456 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 457 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ 458 UTF16_BACK_N_UNSAFE(input, offunsafe, Nvalue[i]); 459 if(offunsafe != back_N_unsafe[i]){ 460 log_err("ERROR: backward_N_unsafe offset expected:%d, Got:%d\n", back_N_unsafe[i], offunsafe); 461 } 462 } 463 464 offunsafe=sizeof(input)/U_SIZEOF_UCHAR; 465 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0])-2; i++){ 466 U16_BACK_N_UNSAFE(input, offunsafe, Nvalue[i]); 467 if(offunsafe != back_N_unsafe[i]){ 468 log_err("ERROR: U16_BACK_N_UNSAFE offset expected:%d, Got:%d\n", back_N_unsafe[i], offunsafe); 469 } 470 } 471 472 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 473 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 474 UTF16_BACK_N_SAFE(input, 0, offsafe, Nvalue[i]); 475 if(offsafe != back_N_safe[i]){ 476 log_err("ERROR: backward_N_safe offset expected:%d, Got:%d\n", back_N_safe[i], offsafe); 477 } 478 } 479 480 offsafe=sizeof(input)/U_SIZEOF_UCHAR; 481 for(i=0; i<sizeof(Nvalue)/sizeof(Nvalue[0]); i++){ 482 U16_BACK_N(input, 0, offsafe, Nvalue[i]); 483 if(offsafe != back_N_safe[i]){ 484 log_err("ERROR: U16_BACK_N offset expected:%d, Got:%d\n", back_N_safe[i], offsafe); 485 } 486 } 487 } 488 489 static void TestSetChar(){ 490 static UChar input[]={0x0061, 0xd800, 0xdc00, 0xdbff, 0xdfff, 0x0062, 0xd841, 0xd7ff, 0xd841, 0xdc41, 0xdc00, 0x0000}; 491 static uint16_t start_unsafe[]={0, 1, 1, 3, 3, 5, 6, 7, 8, 8, 9, 11}; 492 static uint16_t start_safe[] ={0, 1, 1, 3, 3, 5, 6, 7, 8, 8, 10, 11}; 493 static uint16_t limit_unsafe[]={0, 1, 3, 3, 5, 5, 6, 8, 8, 10, 10, 11}; 494 static uint16_t limit_safe[] ={0, 1, 3, 3, 5, 5, 6, 7, 8, 10, 10, 11}; 495 496 uint16_t i=0; 497 uint16_t offset=0, setOffset=0; 498 for(offset=0; offset<sizeof(input)/U_SIZEOF_UCHAR; offset++){ 499 setOffset=offset; 500 UTF16_SET_CHAR_START_UNSAFE(input, setOffset); 501 if(setOffset != start_unsafe[i]){ 502 log_err("ERROR: UTF16_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_unsafe[i], setOffset); 503 } 504 505 setOffset=offset; 506 U16_SET_CP_START_UNSAFE(input, setOffset); 507 if(setOffset != start_unsafe[i]){ 508 log_err("ERROR: U16_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_unsafe[i], setOffset); 509 } 510 511 setOffset=offset; 512 UTF16_SET_CHAR_START_SAFE(input, 0, setOffset); 513 if(setOffset != start_safe[i]){ 514 log_err("ERROR: UTF16_SET_CHAR_START_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_safe[i], setOffset); 515 } 516 517 setOffset=offset; 518 U16_SET_CP_START(input, 0, setOffset); 519 if(setOffset != start_safe[i]){ 520 log_err("ERROR: U16_SET_CHAR_START failed for offset=%ld. Expected:%lx Got:%lx\n", offset, start_safe[i], setOffset); 521 } 522 523 if (offset > 0) { 524 setOffset=offset; 525 UTF16_SET_CHAR_LIMIT_UNSAFE(input, setOffset); 526 if(setOffset != limit_unsafe[i]){ 527 log_err("ERROR: UTF16_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, limit_unsafe[i], setOffset); 528 } 529 530 setOffset=offset; 531 U16_SET_CP_LIMIT_UNSAFE(input, setOffset); 532 if(setOffset != limit_unsafe[i]){ 533 log_err("ERROR: U16_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, limit_unsafe[i], setOffset); 534 } 535 } 536 537 setOffset=offset; 538 U16_SET_CP_LIMIT(input,0, setOffset, sizeof(input)/U_SIZEOF_UCHAR); 539 if(setOffset != limit_safe[i]){ 540 log_err("ERROR: U16_SET_CHAR_LIMIT failed for offset=%ld. Expected:%lx Got:%lx\n", offset, limit_safe[i], setOffset); 541 } 542 543 i++; 544 } 545 } 546 547 static void TestAppendChar(){ 548 static UChar s[5]={0x0061, 0x0062, 0x0063, 0x0064, 0x0000}; 549 static uint32_t test[]={ 550 /*append-position(unsafe), CHAR to be appended */ 551 0, 0x20441, 552 2, 0x0028, 553 2, 0xdc00, 554 3, 0xd800, 555 1, 0x20402, 556 557 /*append-position(safe), CHAR to be appended */ 558 0, 0x20441, 559 2, 0xdc00, 560 3, 0xd800, 561 1, 0x20402, 562 3, 0x20402, 563 3, 0x10402, 564 2, 0x10402, 565 566 }; 567 static uint16_t movedOffset[]={ 568 /*offset-moved-to(unsafe)*/ 569 2, /*for append-pos: 0 , CHAR 0x20441*/ 570 3, 571 3, 572 4, 573 3, 574 /*offse-moved-to(safe)*/ 575 2, /*for append-pos: 0, CHAR 0x20441*/ 576 3, 577 4, 578 3, 579 4, 580 4, 581 4 582 }; 583 584 static UChar result[][5]={ 585 /*unsafe*/ 586 {0xd841, 0xdc41, 0x0063, 0x0064, 0x0000}, 587 {0x0061, 0x0062, 0x0028, 0x0064, 0x0000}, 588 {0x0061, 0x0062, 0xdc00, 0x0064, 0x0000}, 589 {0x0061, 0x0062, 0x0063, 0xd800, 0x0000}, 590 {0x0061, 0xd841, 0xdc02, 0x0064, 0x0000}, 591 592 /*safe*/ 593 {0xd841, 0xdc41, 0x0063, 0x0064, 0x0000}, 594 {0x0061, 0x0062, 0xdc00, 0x0064, 0x0000}, 595 {0x0061, 0x0062, 0x0063, 0xd800, 0x0000}, 596 {0x0061, 0xd841, 0xdc02, 0x0064, 0x0000}, 597 {0x0061, 0x0062, 0x0063, UTF_ERROR_VALUE, 0x0000}, 598 {0x0061, 0x0062, 0x0063, UTF_ERROR_VALUE, 0x0000}, 599 {0x0061, 0x0062, 0xd801, 0xdc02, 0x0000}, 600 601 602 }; 603 uint16_t i, count=0; 604 UChar *str=(UChar*)malloc(sizeof(UChar) * (u_strlen(s)+1)); 605 uint16_t offset; 606 for(i=0; i<sizeof(test)/sizeof(test[0]); i=(uint16_t)(i+2)){ 607 if(count<5){ 608 u_strcpy(str, s); 609 offset=(uint16_t)test[i]; 610 UTF16_APPEND_CHAR_UNSAFE(str, offset, test[i+1]); 611 if(offset != movedOffset[count]){ 612 log_err("ERROR: UTF16_APPEND_CHAR_UNSAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d currentOffset=%d\n", 613 count, movedOffset[count], offset); 614 615 } 616 if(u_strcmp(str, result[count]) !=0){ 617 log_err("ERROR: UTF16_APPEND_CHAR_UNSAFE failed for count=%d. Expected:", count); 618 printUChars(result[count]); 619 printf("\nGot:"); 620 printUChars(str); 621 printf("\n"); 622 } 623 }else{ 624 u_strcpy(str, s); 625 offset=(uint16_t)test[i]; 626 UTF16_APPEND_CHAR_SAFE(str, offset, (uint16_t)u_strlen(str), test[i+1]); 627 if(offset != movedOffset[count]){ 628 log_err("ERROR: UTF16_APPEND_CHAR_SAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d currentOffset=%d\n", 629 count, movedOffset[count], offset); 630 631 } 632 if(u_strcmp(str, result[count]) !=0){ 633 log_err("ERROR: UTF16_APPEND_CHAR_SAFE failed for count=%d. Expected:", count); 634 printUChars(result[count]); 635 printf("\nGot:"); 636 printUChars(str); 637 printf("\n"); 638 } 639 } 640 count++; 641 } 642 free(str); 643 644 } 645 646 static void TestAppend() { 647 static const UChar32 codePoints[]={ 648 0x61, 0xdf, 0x901, 0x3040, 649 0xac00, 0xd800, 0xdbff, 0xdcde, 650 0xdffd, 0xe000, 0xffff, 0x10000, 651 0x12345, 0xe0021, 0x10ffff, 0x110000, 652 0x234567, 0x7fffffff, -1, -1000, 653 0, 0x400 654 }; 655 static const UChar expectUnsafe[]={ 656 0x61, 0xdf, 0x901, 0x3040, 657 0xac00, 0xd800, 0xdbff, 0xdcde, 658 0xdffd, 0xe000, 0xffff, 0xd800, 0xdc00, 659 0xd808, 0xdf45, 0xdb40, 0xdc21, 0xdbff, 0xdfff, /* not 0x110000 */ 660 /* none from this line */ 661 0, 0x400 662 }, expectSafe[]={ 663 0x61, 0xdf, 0x901, 0x3040, 664 0xac00, 0xd800, 0xdbff, 0xdcde, 665 0xdffd, 0xe000, 0xffff, 0xd800, 0xdc00, 666 0xd808, 0xdf45, 0xdb40, 0xdc21, 0xdbff, 0xdfff, /* not 0x110000 */ 667 /* none from this line */ 668 0, 0x400 669 }; 670 671 UChar buffer[100]; 672 UChar32 c; 673 int32_t i, length; 674 UBool isError, expectIsError, wrongIsError; 675 676 length=0; 677 for(i=0; i<LENGTHOF(codePoints); ++i) { 678 c=codePoints[i]; 679 if(c<0 || 0x10ffff<c) { 680 continue; /* skip non-code points for U16_APPEND_UNSAFE */ 681 } 682 683 U16_APPEND_UNSAFE(buffer, length, c); 684 } 685 if(length!=LENGTHOF(expectUnsafe) || 0!=memcmp(buffer, expectUnsafe, length*U_SIZEOF_UCHAR)) { 686 log_err("U16_APPEND_UNSAFE did not generate the expected output\n"); 687 } 688 689 length=0; 690 wrongIsError=FALSE; 691 for(i=0; i<LENGTHOF(codePoints); ++i) { 692 c=codePoints[i]; 693 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. */ 694 isError=FALSE; 695 696 U16_APPEND(buffer, length, LENGTHOF(buffer), c, isError); 697 wrongIsError|= isError!=expectIsError; 698 } 699 if(wrongIsError) { 700 log_err("U16_APPEND did not set isError correctly\n"); 701 } 702 if(length!=LENGTHOF(expectSafe) || 0!=memcmp(buffer, expectSafe, length*U_SIZEOF_UCHAR)) { 703 log_err("U16_APPEND did not generate the expected output\n"); 704 } 705 } 706 707 static void TestSurrogate(){ 708 static UChar32 s[] = {0x10000, 0x10ffff, 0x50000, 0x100000, 0x1abcd}; 709 int i = 0; 710 while (i < 5) { 711 UChar first = UTF_FIRST_SURROGATE(s[i]); 712 UChar second = UTF_SECOND_SURROGATE(s[i]); 713 /* algorithm from the Unicode consortium */ 714 UChar firstresult = (UChar)(((s[i] - 0x10000) / 0x400) + 0xD800); 715 UChar secondresult = (UChar)(((s[i] - 0x10000) % 0x400) + 0xDC00); 716 717 if (first != UTF16_LEAD(s[i]) || first != U16_LEAD(s[i]) || first != firstresult) { 718 log_err("Failure in first surrogate in 0x%x expected to be 0x%x\n", 719 s[i], firstresult); 720 } 721 if (second != UTF16_TRAIL(s[i]) || second != U16_TRAIL(s[i]) || second != secondresult) { 722 log_err("Failure in second surrogate in 0x%x expected to be 0x%x\n", 723 s[i], secondresult); 724 } 725 i ++; 726 } 727 } 728 729 static void printUChars(const UChar *uchars){ 730 int16_t i=0; 731 for(i=0; i<u_strlen(uchars); i++){ 732 printf("%x ", *(uchars+i)); 733 } 734 } 735