• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
addUTF16Test(TestNode ** root)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 
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 
TestFwdBack()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 
TestSetChar()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 
TestAppendChar()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 
TestAppend()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 
TestSurrogate()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 
printUChars(const UChar * uchars)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