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