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
addUTF16Test(TestNode ** root)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
TestCodeUnitValues()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
TestCharLength()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
TestGetChar()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
TestNextPrevChar()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() */
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
TestFwdBack()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
TestSetChar()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
TestAppendChar()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
TestAppend()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
TestSurrogate()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
printUChars(const UChar * uchars)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