16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/********************************************************************
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * COPYRIGHT:
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (c) 1998-2012, International Business Machines Corporation and
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * others. All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ********************************************************************/
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File utf8tst.c
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History:
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Date          Name        Description
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   07/24/2000    Madhu       Creation
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf8.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cintltst.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* lenient UTF-8 ------------------------------------------------------------ */
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Lenient UTF-8 differs from conformant UTF-8 in that it allows surrogate
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * code points with their "natural" encoding.
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Effectively, this allows a mix of UTF-8 and CESU-8 as well as encodings of
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * single surrogates.
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is not conformant with UTF-8.
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Supplementary code points may be encoded as pairs of 3-byte sequences, but
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the macros below do not attempt to assemble such pairs.
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define L8_NEXT(s, i, length, c) { \
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    (c)=(uint8_t)(s)[(i)++]; \
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if((c)>=0x80) { \
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U8_IS_LEAD(c)) { \
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (int32_t)(length), c, -2); \
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else { \
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (c)=U_SENTINEL; \
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } \
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } \
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define L8_PREV(s, start, i, c) { \
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    (c)=(uint8_t)(s)[--(i)]; \
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if((c)>=0x80) { \
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((c)<=0xbf) { \
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -2); \
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else { \
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            (c)=U_SENTINEL; \
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } \
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } \
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* -------------------------------------------------------------------------- */
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void printUChars(const uint8_t *uchars, int16_t len);
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestCodeUnitValues(void);
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestCharLength(void);
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestGetChar(void);
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNextPrevChar(void);
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNulTerminated(void);
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNextPrevNonCharacters(void);
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNextPrevCharUnsafe(void);
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestFwdBack(void);
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestFwdBackUnsafe(void);
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestSetChar(void);
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestSetCharUnsafe(void);
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestAppendChar(void);
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestAppend(void);
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestSurrogates(void);
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid addUTF8Test(TestNode** root);
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgaddUTF8Test(TestNode** root)
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestCodeUnitValues,          "utf8tst/TestCodeUnitValues");
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestCharLength,              "utf8tst/TestCharLength");
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestGetChar,                 "utf8tst/TestGetChar");
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestNextPrevChar,            "utf8tst/TestNextPrevChar");
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestNulTerminated,           "utf8tst/TestNulTerminated");
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestNextPrevNonCharacters,   "utf8tst/TestNextPrevNonCharacters");
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestNextPrevCharUnsafe,      "utf8tst/TestNextPrevCharUnsafe");
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestFwdBack,                 "utf8tst/TestFwdBack");
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestFwdBackUnsafe,           "utf8tst/TestFwdBackUnsafe");
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestSetChar,                 "utf8tst/TestSetChar");
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestSetCharUnsafe,           "utf8tst/TestSetCharUnsafe");
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestAppendChar,              "utf8tst/TestAppendChar");
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestAppend,                  "utf8tst/TestAppend");
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    addTest(root, &TestSurrogates,              "utf8tst/TestSurrogates");
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestCodeUnitValues()
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t codeunit[]={0x00, 0x65, 0x7e, 0x7f, 0xc0, 0xc4, 0xf0, 0xfd, 0x80, 0x81, 0xbc, 0xbe,};
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int16_t i;
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(codeunit); i++){
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uint8_t c=codeunit[i];
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        log_verbose("Testing code unit value of %x\n", c);
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(i<4){
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(!UTF8_IS_SINGLE(c) || UTF8_IS_LEAD(c) || UTF8_IS_TRAIL(c) || !U8_IS_SINGLE(c) || U8_IS_LEAD(c) || U8_IS_TRAIL(c)){
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: 0x%02x is a single byte but results in single: %c lead: %c trail: %c\n",
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(i< 8){
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(!UTF8_IS_LEAD(c) || UTF8_IS_SINGLE(c) || UTF8_IS_TRAIL(c) || !U8_IS_LEAD(c) || U8_IS_SINGLE(c) || U8_IS_TRAIL(c)){
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: 0x%02x is a lead byte but results in single: %c lead: %c trail: %c\n",
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(i< 12){
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(!UTF8_IS_TRAIL(c) || UTF8_IS_SINGLE(c) || UTF8_IS_LEAD(c) || !U8_IS_TRAIL(c) || U8_IS_SINGLE(c) || U8_IS_LEAD(c)){
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: 0x%02x is a trail byte but results in single: %c lead: %c trail: %c\n",
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    c, UTF8_IS_SINGLE(c) ? 'y' : 'n', UTF8_IS_LEAD(c) ? 'y' : 'n', UTF8_IS_TRAIL(c) ? 'y' : 'n');
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestCharLength()
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint32_t codepoint[]={
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        1, 0x0061,
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        1, 0x007f,
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        2, 0x016f,
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        2, 0x07ff,
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3, 0x0865,
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3, 0x20ac,
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        4, 0x20402,
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        4, 0x23456,
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        4, 0x24506,
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        4, 0x20402,
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        4, 0x10402,
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3, 0xd7ff,
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3, 0xe000,
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int16_t i;
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool multiple;
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(codepoint); i=(int16_t)(i+2)){
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar32 c=codepoint[i+1];
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UTF8_CHAR_LENGTH(c) != (uint16_t)codepoint[i] || U8_LENGTH(c) != (uint16_t)codepoint[i]){
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org              log_err("The no: of code units for %lx:- Expected: %d Got: %d\n", c, codepoint[i], UTF8_CHAR_LENGTH(c));
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }else{
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org              log_verbose("The no: of code units for %lx is %d\n",c, UTF8_CHAR_LENGTH(c));
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        multiple=(UBool)(codepoint[i] == 1 ? FALSE : TRUE);
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UTF8_NEED_MULTIPLE_UCHAR(c) != multiple){
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org              log_err("ERROR: UTF8_NEED_MULTIPLE_UCHAR failed for %lx\n", c);
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestGetChar()
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]={
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*  code unit,*/
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x7f,
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xe4,
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xba,
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x8c,
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xF0,
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x90,
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x90,
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x81,
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc0,
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x65,
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x31,
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x9a,
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc9
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const UChar32 result[]={
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*  codepoint-unsafe, codepoint-safe(not strict)  codepoint-safe(strict) */
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,             0x61,                       0x61,
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x7f,             0x7f,                       0x7f,
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x4e8c,           0x4e8c,                     0x4e8c,
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x4e8c,           0x4e8c,                     0x4e8c ,
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x4e8c,           0x4e8c,                     0x4e8c,
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,          0x10401,                    0x10401 ,
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,          0x10401,                    0x10401 ,
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,          0x10401,                    0x10401 ,
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,          0x10401,                    0x10401,
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x25,             UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1,
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x65,             0x65,                       0x65,
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x31,             0x31,                       0x31,
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x31,             UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1,
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x240,            UTF8_ERROR_VALUE_1,         UTF8_ERROR_VALUE_1
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint16_t i=0;
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c, expected;
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t offset=0;
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(offset=0; offset<sizeof(input); offset++) {
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (offset < sizeof(input) - 1) {
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UTF8_GET_CHAR_UNSAFE(input, offset, c);
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c != result[i]){
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_GET_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_GET_UNSAFE(input, offset, c);
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c != result[i]){
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: U8_GET_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i], c);
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_GET_CHAR_SAFE(input, 0, offset, sizeof(input), c, FALSE);
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        expected=result[i+1];
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_GET_CHAR_SAFE failed for offset=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_GET(input, 0, offset, sizeof(input), c);
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UTF_IS_ERROR(expected)) { expected=U_SENTINEL; }
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_GET failed for offset=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_GET_OR_FFFD(input, 0, offset, sizeof(input), c);
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(expected<0) { expected=0xfffd; }
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_GET_OR_FFFD failed for offset=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_GET_CHAR_SAFE(input, 0, offset, sizeof(input), c, TRUE);
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != result[i+2]){
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_GET_CHAR_SAFE(strict) failed for offset=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c);
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i=(uint16_t)(i+3);
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNextPrevChar() {
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]={0x61, 0xf0, 0x90, 0x90, 0x81, 0xc0, 0x80, 0xfd, 0xbe, 0xc2, 0x61, 0x81, 0x90, 0x90, 0xf0, 0x00};
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const UChar32 result[]={
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*  next_unsafe    next_safe_ns        next_safe_s          prev_unsafe   prev_safe_ns        prev_safe_s */
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x0061,        0x0061,             0x0061,              0x0000,       0x0000,             0x0000,
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,       0x10401,            0x10401,             0xf0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x2841410,    UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xa1050,      UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x81,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x2841,       UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x00,          UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,  0x61,         0x61,               0x61,
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x80,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xc2,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xfd,          UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,  0x77e,        UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xbe,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xfd,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xa1,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x00,         UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,          0x61,               0x61,                0xc0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x81,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x10401,      0x10401,            0x10401,
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x410,        UTF_ERROR_VALUE,    UTF_ERROR_VALUE,
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x90,          UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0x410,        UTF8_ERROR_VALUE_2, UTF8_ERROR_VALUE_2,
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x0840,        UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,  0xf0,         UTF8_ERROR_VALUE_1, UTF8_ERROR_VALUE_1,
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x0000,        0x0000,             0x0000,              0x0061,       0x0061,             0x0061
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const int32_t movedOffset[]={
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*  next_unsafe   next_safe_ns next_safe_s       prev_unsafe   prev_safe_ns      prev_safe_s */
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        1,            1,           1,                15,           15,               15,
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,            5,           5,                14,           14 ,              14,
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3,            3,           3,                9,            13,               13,
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        4,            4,           4,                9,            12,               12,
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,            5,           5,                9,            11,               11,
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        7,            7,           7,                10,           10,               10,
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        7,            7,           7,                9,            9,                9,
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        8,            9,           9,                7,            7,                7,
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        9,            9,           9,                7,            7,                7,
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        11,           10,          10,               5,            5,                5,
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        11,           11,          11,               5,            5,                5,
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        12,           12,          12,               1,            1,                1,
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        13,           13,          13,               1,            1,                1,
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        14,           14,          14,               1,            1,                1,
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        14,           15,          15,               1,            1,                1,
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        14,           16,          16,               0,            0,                0,
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* TODO: remove unused columns for next_unsafe & prev_unsafe, and adjust the test code */
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c, expected;
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t i=0;
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t offset=0;
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t setOffset=0;
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(offset=0; offset<sizeof(input); offset++){
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         setOffset=offset;
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UTF8_NEXT_CHAR_SAFE(input, setOffset, sizeof(input), c, FALSE);
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(setOffset != movedOffset[i+1]){
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_NEXT_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 offset, movedOffset[i+1], setOffset);
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        expected=result[i+1];
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_NEXT_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         setOffset=offset;
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         U8_NEXT(input, setOffset, sizeof(input), c);
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(setOffset != movedOffset[i+1]){
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: U8_NEXT failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 offset, movedOffset[i+1], setOffset);
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UTF_IS_ERROR(expected)) { expected=U_SENTINEL; }
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_NEXT failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setOffset=offset;
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT_OR_FFFD(input, setOffset, sizeof(input), c);
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(setOffset != movedOffset[i+1]){
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_NEXT_OR_FFFD failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                offset, movedOffset[i+1], setOffset);
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(expected<0) { expected=0xfffd; }
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_NEXT_OR_FFFD failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         setOffset=offset;
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UTF8_NEXT_CHAR_SAFE(input, setOffset, sizeof(input), c, TRUE);
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(setOffset != movedOffset[i+1]){
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_NEXT_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 offset, movedOffset[i+2], setOffset);
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(c != result[i+2]){
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_NEXT_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+2], c);
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         i=i+6;
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    i=0;
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(offset=sizeof(input); offset > 0; --offset){
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         setOffset=offset;
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UTF8_PREV_CHAR_SAFE(input, 0, setOffset, c, FALSE);
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(setOffset != movedOffset[i+4]){
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_PREV_CHAR_SAFE failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 offset, movedOffset[i+4], setOffset);
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        expected=result[i+4];
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_PREV_CHAR_SAFE failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         setOffset=offset;
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         U8_PREV(input, 0, setOffset, c);
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(setOffset != movedOffset[i+4]){
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: U8_PREV failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 offset, movedOffset[i+4], setOffset);
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UTF_IS_ERROR(expected)) { expected=U_SENTINEL; }
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_PREV failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setOffset=offset;
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_PREV_OR_FFFD(input, 0, setOffset, c);
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(setOffset != movedOffset[i+4]){
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_PREV_OR_FFFD failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                offset, movedOffset[i+4], setOffset);
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(expected<0) { expected=0xfffd; }
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != expected){
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_PREV_OR_FFFD failed for input=%ld. Expected:%lx Got:%lx\n", offset, expected, c);
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         setOffset=offset;
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UTF8_PREV_CHAR_SAFE(input, 0,  setOffset, c, TRUE);
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(setOffset != movedOffset[i+5]){
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_PREV_CHAR_SAFE(strict) failed to move the offset correctly at %d\n ExpectedOffset:%d Got %d\n",
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 offset, movedOffset[i+5], setOffset);
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(c != result[i+5]){
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_PREV_CHAR_SAFE(strict) failed for input=%ld. Expected:%lx Got:%lx\n", offset, result[i+5], c);
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         i=i+6;
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* keep this in sync with utf16tst.c's TestNulTerminated() */
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNulTerminated() {
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]={
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*  0 */  0x61,
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*  1 */  0xf0, 0x90, 0x90, 0x81,
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*  5 */  0xc0, 0x80,
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*  7 */  0xdf, 0x80,
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*  9 */  0xc2,
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 10 */  0x62,
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 11 */  0xfd, 0xbe,
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 13 */  0xe0, 0xa0, 0x80,
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 16 */  0xe2, 0x82, 0xac,
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 19 */  0xf0, 0x90, 0x90,
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 22 */  0x00
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* 23 */
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const UChar32 result[]={
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_SENTINEL,
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x7c0,
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_SENTINEL,
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x62,
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_SENTINEL,
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x800,
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x20ac,
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_SENTINEL,
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c, c2, expected;
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i0, i=0, j, k, expectedIndex;
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t cpIndex=0;
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    do {
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i0=i;
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT(input, i, -1, c);
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        expected=result[cpIndex];
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c!=expected) {
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT(from %d)=U+%04x != U+%04x\n", i0, c, expected);
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i0;
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT_OR_FFFD(input, j, -1, c);
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(expected<0) { expected=0xfffd; }
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c!=expected) {
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT_OR_FFFD(from %d)=U+%04x != U+%04x\n", i0, c, expected);
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(j!=i) {
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT_OR_FFFD() moved to index %d but U8_NEXT() moved to %d\n", j, i);
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i0;
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_FWD_1(input, j, -1);
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(j!=i) {
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_FWD_1() moved to index %d but U8_NEXT() moved to %d\n", j, i);
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ++cpIndex;
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * Move by this many code points from the start.
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * U8_FWD_N() stops at the end of the string, that is, at the NUL if necessary.
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        expectedIndex= (c==0) ? i-1 : i;
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        k=0;
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_FWD_N(input, k, -1, cpIndex);
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(k!=expectedIndex) {
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_FWD_N(code points from 0) moved to index %d but expected %d\n", k, expectedIndex);
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } while(c!=0);
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    i=0;
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    do {
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i0=i;
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT(input, i, -1, c);
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        do {
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_GET(input, 0, j, -1, c2);
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c2!=c) {
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("U8_NEXT(from %d)=U+%04x != U+%04x=U8_GET(at %d)\n", i0, c, c2, j);
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_GET_OR_FFFD(input, 0, j, -1, c2);
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            expected= (c>=0) ? c : 0xfffd;
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c2!=expected) {
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("U8_NEXT_OR_FFFD(from %d)=U+%04x != U+%04x=U8_GET_OR_FFFD(at %d)\n", i0, expected, c2, j);
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* U8_SET_CP_LIMIT moves from a non-lead byte to the limit of the code point */
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            k=j+1;
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_SET_CP_LIMIT(input, 0, k, -1);
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(k!=i) {
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("U8_NEXT() moved to %d but U8_SET_CP_LIMIT(%d) moved to %d\n", i, j+1, k);
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } while(++j<i);
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } while(c!=0);
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNextPrevNonCharacters() {
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* test non-characters */
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t nonChars[]={
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xef, 0xb7, 0x90,       /* U+fdd0 */
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xef, 0xbf, 0xbf,       /* U+feff */
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0x9f, 0xbf, 0xbe, /* U+1fffe */
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0xbf, 0xbf, 0xbf, /* U+3ffff */
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf4, 0x8f, 0xbf, 0xbe  /* U+10fffe */
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 ch;
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t idx;
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(idx=0; idx<(int32_t)sizeof(nonChars);) {
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT(nonChars, idx, sizeof(nonChars), ch);
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(!U_IS_UNICODE_NONCHAR(ch)) {
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT(before %d) failed to read a non-character\n", idx);
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(idx=(int32_t)sizeof(nonChars); idx>0;) {
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_PREV(nonChars, 0, idx, ch);
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(!U_IS_UNICODE_NONCHAR(ch)) {
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_PREV(at %d) failed to read a non-character\n", idx);
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestNextPrevCharUnsafe() {
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Use a (mostly) well-formed UTF-8 string and test at code point boundaries.
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * The behavior of _UNSAFE macros for ill-formed strings is undefined.
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]={
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0x90, 0x90, 0x81,
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc0, 0x80,  /* non-shortest form */
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xe2, 0x82, 0xac,
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc2, 0xa1,
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf4, 0x8f, 0xbf, 0xbf,
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x00
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const UChar32 codePoints[]={
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10401,
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0,
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x20ac,
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xa1,
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x10ffff,
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c;
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t offset;
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0, offset=0; offset<sizeof(input); ++i) {
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_NEXT_CHAR_UNSAFE(input, offset, c);
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != codePoints[i]){
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_NEXT_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    offset, codePoints[i], c);
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0, offset=0; offset<sizeof(input); ++i) {
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT_UNSAFE(input, offset, c);
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c != codePoints[i]){
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_NEXT_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    offset, codePoints[i], c);
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=LENGTHOF(codePoints)-1, offset=sizeof(input); offset > 0; --i){
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UTF8_PREV_CHAR_UNSAFE(input, offset, c);
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(c != codePoints[i]){
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: UTF8_PREV_CHAR_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     offset, codePoints[i], c);
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=LENGTHOF(codePoints)-1, offset=sizeof(input); offset > 0; --i){
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         U8_PREV_UNSAFE(input, offset, c);
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         if(c != codePoints[i]){
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             log_err("ERROR: U8_PREV_UNSAFE failed for offset=%ld. Expected:%lx Got:%lx\n",
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     offset, codePoints[i], c);
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         }
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestFwdBack() {
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]={0x61, 0xF0, 0x90, 0x90, 0x81, 0xff, 0x62, 0xc0, 0x80, 0x7f, 0x8f, 0xc0, 0x63, 0x81, 0x90, 0x90, 0xF0, 0x00};
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint16_t fwd_safe[]   ={1, 5, 6, 7, 9, 10, 11,  12, 13, 14, 15, 16, 17, 18};
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint16_t back_safe[]  ={17, 16, 15, 14, 13, 12, 11, 10, 9, 7, 6, 5, 1, 0};
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint16_t Nvalue[]= {0, 1, 2, 3, 1, 2, 1, 5};
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint16_t fwd_N_safe[]   ={0, 1, 6, 10, 11, 13, 14, 18}; /*safe macro keeps it at the end of the string */
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint16_t back_N_safe[]  ={18, 17, 15, 12, 11, 9, 7, 0};
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t offsafe=0;
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t i=0;
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while(offsafe < sizeof(input)){
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_FWD_1_SAFE(input, offsafe, sizeof(input));
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != fwd_safe[i]){
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: Forward_safe offset expected:%d, Got:%d\n", fwd_safe[i], offsafe);
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i++;
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    i=0;
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while(offsafe < sizeof(input)){
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_FWD_1(input, offsafe, sizeof(input));
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != fwd_safe[i]){
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_FWD_1 offset expected:%d, Got:%d\n", fwd_safe[i], offsafe);
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i++;
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    i=0;
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsafe=sizeof(input);
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while(offsafe > 0){
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_BACK_1_SAFE(input, 0,  offsafe);
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != back_safe[i]){
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: Backward_safe offset expected:%d, Got:%d\n", back_safe[i], offsafe);
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i++;
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    i=0;
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsafe=sizeof(input);
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while(offsafe > 0){
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_BACK_1(input, 0,  offsafe);
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != back_safe[i]){
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_BACK_1 offset expected:%d, Got:%d\n", back_safe[i], offsafe);
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i++;
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsafe=0;
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(Nvalue); i++){
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_FWD_N_SAFE(input, offsafe, sizeof(input), Nvalue[i]);
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != fwd_N_safe[i]){
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: Forward_N_safe offset=%d expected:%d, Got:%d\n", i, fwd_N_safe[i], offsafe);
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsafe=0;
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(Nvalue); i++){
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_FWD_N(input, offsafe, sizeof(input), Nvalue[i]);
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != fwd_N_safe[i]){
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_FWD_N offset=%d expected:%d, Got:%d\n", i, fwd_N_safe[i], offsafe);
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsafe=sizeof(input);
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(Nvalue); i++){
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_BACK_N_SAFE(input, 0, offsafe, Nvalue[i]);
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != back_N_safe[i]){
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: backward_N_safe offset=%d expected:%d, Got:%ld\n", i, back_N_safe[i], offsafe);
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    offsafe=sizeof(input);
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(Nvalue); i++){
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_BACK_N(input, 0, offsafe, Nvalue[i]);
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offsafe != back_N_safe[i]){
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_BACK_N offset=%d expected:%d, Got:%ld\n", i, back_N_safe[i], offsafe);
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestFwdBackUnsafe() {
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Use a (mostly) well-formed UTF-8 string and test at code point boundaries.
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * The behavior of _UNSAFE macros for ill-formed strings is undefined.
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]={
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0x90, 0x90, 0x81,
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc0, 0x80,  /* non-shortest form */
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xe2, 0x82, 0xac,
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc2, 0xa1,
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf4, 0x8f, 0xbf, 0xbf,
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x00
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const int8_t boundaries[]={ 0, 1, 5, 7, 10, 12, 16, 17 };
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offset;
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=1, offset=0; offset<LENGTHOF(input); ++i) {
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_FWD_1_UNSAFE(input, offset);
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[i]){
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_FWD_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=1, offset=0; offset<LENGTHOF(input); ++i) {
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_FWD_1_UNSAFE(input, offset);
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[i]){
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_FWD_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=LENGTHOF(boundaries)-2, offset=LENGTHOF(input); offset>0; --i) {
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_BACK_1_UNSAFE(input, offset);
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[i]){
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_BACK_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=LENGTHOF(boundaries)-2, offset=LENGTHOF(input); offset>0; --i) {
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_BACK_1_UNSAFE(input, offset);
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[i]){
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_BACK_1_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(boundaries); ++i) {
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=0;
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_FWD_N_UNSAFE(input, offset, i);
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[i]) {
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_FWD_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(boundaries); ++i) {
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=0;
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_FWD_N_UNSAFE(input, offset, i);
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[i]) {
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_FWD_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[i], offset);
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(boundaries); ++i) {
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t j=LENGTHOF(boundaries)-1-i;
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=LENGTHOF(input);
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_BACK_N_UNSAFE(input, offset, i);
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[j]) {
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_BACK_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[j], offset);
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(boundaries); ++i) {
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t j=LENGTHOF(boundaries)-1-i;
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=LENGTHOF(input);
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_BACK_N_UNSAFE(input, offset, i);
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(offset != boundaries[j]) {
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_BACK_N_UNSAFE offset expected:%d, Got:%d\n", boundaries[j], offset);
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestSetChar() {
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        = {0x61, 0xe4, 0xba, 0x8c, 0x7f, 0xfe, 0x62, 0xc5, 0x7f, 0x61, 0x80, 0x80, 0xe0, 0x00 };
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const int16_t start_safe[]
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        = {0,    1,    1,    1,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,  14 };
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const int16_t limit_safe[]
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        = {0,    1,    4,    4,    4,    5,    6,    7,    8,    9,    10,   11,   12,   13,  14 };
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t i=0;
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offset=0, setOffset=0;
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(offset=0; offset<=LENGTHOF(input); offset++){
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (offset<LENGTHOF(input)){
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setOffset=offset;
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UTF8_SET_CHAR_START_SAFE(input, 0, setOffset);
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(setOffset != start_safe[i]){
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_SET_CHAR_START_SAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_safe[i], setOffset);
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setOffset=offset;
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_SET_CP_START(input, 0, setOffset);
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(setOffset != start_safe[i]){
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: U8_SET_CP_START failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_safe[i], setOffset);
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setOffset=offset;
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UTF8_SET_CHAR_LIMIT_SAFE(input,0, setOffset, sizeof(input));
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(setOffset != limit_safe[i]){
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: UTF8_SET_CHAR_LIMIT_SAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_safe[i], setOffset);
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setOffset=offset;
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_SET_CP_LIMIT(input,0, setOffset, sizeof(input));
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(setOffset != limit_safe[i]){
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("ERROR: U8_SET_CP_LIMIT failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_safe[i], setOffset);
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i++;
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestSetCharUnsafe() {
7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t input[]
7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        = {0x61, 0xe4, 0xba, 0x8c, 0x7f, 0x2e, 0x62, 0xc5, 0x7f, 0x61, 0x80, 0x80, 0xe0, 0x80, 0x80, 0x00 };
7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const int16_t start_unsafe[]
7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        = {0,    1,    1,    1,    4,    5,    6,    7,    8,    9,    9,    9,    12,   12,   12,   15 };
7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const int16_t limit_unsafe[]
7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        = {0,    1,    4,    4,    4,    5,    6,    7,    9,    9,    10,   10,   10,   15,   15,   15,   16 };
7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t i=0;
7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t offset=0, setOffset=0;
7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(offset=0; offset<=LENGTHOF(input); offset++){
7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (offset<LENGTHOF(input)){
7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setOffset=offset;
7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UTF8_SET_CHAR_START_UNSAFE(input, setOffset);
7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(setOffset != start_unsafe[i]){
7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_SET_CHAR_START_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_unsafe[i], setOffset);
7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setOffset=offset;
7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_SET_CP_START_UNSAFE(input, setOffset);
7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(setOffset != start_unsafe[i]){
7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: U8_SET_CP_START_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, start_unsafe[i], setOffset);
7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (offset != 0) { /* Can't have it go off the end of the array */
7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setOffset=offset;
7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UTF8_SET_CHAR_LIMIT_UNSAFE(input, setOffset);
7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(setOffset != limit_unsafe[i]){
7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_SET_CHAR_LIMIT_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_unsafe[i], setOffset);
7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            setOffset=offset;
7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_SET_CP_LIMIT_UNSAFE(input, setOffset);
7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(setOffset != limit_unsafe[i]){
7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: U8_SET_CP_LIMIT_UNSAFE failed for offset=%ld. Expected:%ld Got:%ld\n", offset, limit_unsafe[i], setOffset);
7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i++;
8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestAppendChar(){
8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t s[11]={0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00};
8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint32_t test[]={
8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*  append-position(unsafe),  CHAR to be appended */
8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0,                        0x10401,
8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        2,                        0x0028,
8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        2,                        0x007f,
8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3,                        0xd801,
8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        1,                        0x20402,
8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        8,                        0x10401,
8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,                        0xc0,
8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,                        0xc1,
8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,                        0xfd,
8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        6,                        0x80,
8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        6,                        0x81,
8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        6,                        0xbf,
8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        7,                        0xfe,
8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*  append-position(safe),    CHAR to be appended */
8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0,                        0x10401,
8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        2,                        0x0028,
8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3,                        0x7f,
8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        3,                        0xd801,   /* illegal for UTF-8 starting with Unicode 3.2 */
8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        1,                        0x20402,
8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        9,                        0x10401,
8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,                        0xc0,
8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,                        0xc1,
8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        5,                        0xfd,
8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        6,                        0x80,
8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        6,                        0x81,
8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        6,                        0xbf,
8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        7,                        0xfe,
8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint16_t movedOffset[]={
8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* offset-moved-to(unsafe) */
8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          4,              /*for append-pos: 0 , CHAR 0x10401*/
8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          3,
8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          3,
8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          6,
8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          5,
8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          12,
8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          7,
8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          7,
8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          7,
8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          8,
8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          8,
8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          8,
8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          9,
8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* offset-moved-to(safe) */
8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          4,              /*for append-pos: 0, CHAR  0x10401*/
8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          3,
8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          4,
8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          6,
8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          5,
8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          11,
8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          7,
8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          7,
8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          7,
8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          8,
8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          8,
8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          8,
8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org          9,
8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t result[][11]={
8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*unsafe*/
8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0xF0, 0x90, 0x90, 0x81, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x28, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x7f, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0xed, 0xa0, 0x81, 0x67, 0x68, 0x69, 0x6a, 0x00},
8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0xF0, 0xa0, 0x90, 0x82, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0xF0, 0x90, 0x90},
8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x80, 0x68, 0x69, 0x6a, 0x00},
8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x81, 0x68, 0x69, 0x6a, 0x00},
8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0xbd, 0x68, 0x69, 0x6a, 0x00},
8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x80, 0x69, 0x6a, 0x00},
8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x81, 0x69, 0x6a, 0x00},
8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0xbf, 0x69, 0x6a, 0x00},
8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0xc3, 0xbe, 0x6a, 0x00},
8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*safe*/
8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0xF0, 0x90, 0x90, 0x81, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x28, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x7f, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0xef, 0xbf, 0xbf, 0x67, 0x68, 0x69, 0x6a, 0x00},
8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0xF0, 0xa0, 0x90, 0x82, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x00},
8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xc2, 0x9f}, /*gets UTF8_ERROR_VALUE_2 which takes 2 bytes 0xc0, 0x9f*/
8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x80, 0x68, 0x69, 0x6a, 0x00},
9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0x81, 0x68, 0x69, 0x6a, 0x00},
9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0xc3, 0xbd, 0x68, 0x69, 0x6a, 0x00},
9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x80, 0x69, 0x6a, 0x00},
9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0x81, 0x69, 0x6a, 0x00},
9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xc2, 0xbf, 0x69, 0x6a, 0x00},
9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0xc3, 0xbe, 0x6a, 0x00},
9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint16_t i, count=0;
9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t str[12];
9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t offset;
9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*    UChar32 c=0;*/
9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint16_t size=LENGTHOF(s);
9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(test); i=(uint16_t)(i+2)){
9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_memcpy(str, s, size);
9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offset=test[i];
9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(count<13){
9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UTF8_APPEND_CHAR_UNSAFE(str, offset, test[i+1]);
9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(offset != movedOffset[count]){
9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_APPEND_CHAR_UNSAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    count, movedOffset[count], offset);
9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(uprv_memcmp(str, result[count], size) !=0){
9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_APPEND_CHAR_UNSAFE failed for count=%d. \nExpected:", count);
9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUChars(result[count], size);
9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("\nGot:      ");
9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUChars(str, size);
9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("\n");
9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }else{
9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UTF8_APPEND_CHAR_SAFE(str, offset, size, test[i+1]);
9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(offset != movedOffset[count]){
9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_APPEND_CHAR_SAFE failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    count, movedOffset[count], offset);
9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(uprv_memcmp(str, result[count], size) !=0){
9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: UTF8_APPEND_CHAR_SAFE failed for count=%d. \nExpected:", count);
9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUChars(result[count], size);
9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("\nGot:     ");
9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUChars(str, size);
9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("\n");
9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /*call the API instead of MACRO
9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_memcpy(str, s, size);
9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            offset=test[i];
9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            c=test[i+1];
9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if((uint32_t)(c)<=0x7f) {
9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                  (str)[(offset)++]=(uint8_t)(c);
9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 (offset)=utf8_appendCharSafeBody(str, (int32_t)(offset), (int32_t)(size), c);
9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(offset != movedOffset[count]){
9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: utf8_appendCharSafeBody() failed to move the offset correctly for count=%d.\nExpectedOffset=%d  currentOffset=%d\n",
9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    count, movedOffset[count], offset);
9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(uprv_memcmp(str, result[count], size) !=0){
9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                log_err("ERROR: utf8_appendCharSafeBody() failed for count=%d. \nExpected:", count);
9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUChars(result[count], size);
9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printf("\nGot:     ");
9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUChars(str, size);
9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printf("\n");
9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            */
9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count++;
9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void TestAppend() {
9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const UChar32 codePoints[]={
9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61, 0xdf, 0x901, 0x3040,
9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xac00, 0xd800, 0xdbff, 0xdcde,
9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xdffd, 0xe000, 0xffff, 0x10000,
9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x12345, 0xe0021, 0x10ffff, 0x110000,
9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x234567, 0x7fffffff, -1, -1000,
9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0, 0x400
9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t expectUnsafe[]={
9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,  0xc3, 0x9f,  0xe0, 0xa4, 0x81,  0xe3, 0x81, 0x80,
9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xea, 0xb0, 0x80,  0xed, 0xa0, 0x80,  0xed, 0xaf, 0xbf,  0xed, 0xb3, 0x9e,
9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xed, 0xbf, 0xbd,  0xee, 0x80, 0x80,  0xef, 0xbf, 0xbf,  0xf0, 0x90, 0x80, 0x80,
9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0x92, 0x8d, 0x85,  0xf3, 0xa0, 0x80, 0xa1,  0xf4, 0x8f, 0xbf, 0xbf,  /* not 0x110000 */
9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* none from this line */
9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0,  0xd0, 0x80
9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }, expectSafe[]={
9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0x61,  0xc3, 0x9f,  0xe0, 0xa4, 0x81,  0xe3, 0x81, 0x80,
9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xea, 0xb0, 0x80,  /* no surrogates */
9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* no surrogates */  0xee, 0x80, 0x80,  0xef, 0xbf, 0xbf,  0xf0, 0x90, 0x80, 0x80,
9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0x92, 0x8d, 0x85,  0xf3, 0xa0, 0x80, 0xa1,  0xf4, 0x8f, 0xbf, 0xbf,  /* not 0x110000 */
9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* none from this line */
9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0,  0xd0, 0x80
9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint8_t buffer[100];
10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c;
10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, length;
10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool isError, expectIsError, wrongIsError;
10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    length=0;
10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(codePoints); ++i) {
10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        c=codePoints[i];
10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c<0 || 0x10ffff<c) {
10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            continue; /* skip non-code points for U8_APPEND_UNSAFE */
10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_APPEND_UNSAFE(buffer, length, c);
10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length!=LENGTHOF(expectUnsafe) || 0!=memcmp(buffer, expectUnsafe, length)) {
10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        log_err("U8_APPEND_UNSAFE did not generate the expected output\n");
10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    length=0;
10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    wrongIsError=FALSE;
10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<LENGTHOF(codePoints); ++i) {
10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        c=codePoints[i];
10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        expectIsError= c<0 || 0x10ffff<c || U_IS_SURROGATE(c);
10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        isError=FALSE;
10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_APPEND(buffer, length, LENGTHOF(buffer), c, isError);
10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        wrongIsError|= isError!=expectIsError;
10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(wrongIsError) {
10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        log_err("U8_APPEND did not set isError correctly\n");
10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(length!=LENGTHOF(expectSafe) || 0!=memcmp(buffer, expectSafe, length)) {
10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        log_err("U8_APPEND did not generate the expected output\n");
10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTestSurrogates() {
10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const uint8_t b[]={
10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xc3, 0x9f,             /*  00DF */
10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xed, 0x9f, 0xbf,       /*  D7FF */
10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xed, 0xa0, 0x81,       /*  D801 */
10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xed, 0xbf, 0xbe,       /*  DFFE */
10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xee, 0x80, 0x80,       /*  E000 */
10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xf0, 0x97, 0xbf, 0xbe  /* 17FFE */
10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    static const UChar32 cp[]={
10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        0xdf, 0xd7ff, 0xd801, 0xdffe, 0xe000, 0x17ffe
10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    };
10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 cu, cs, cl;
10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i, j, k, iu, is, il, length;
10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    k=0; /* index into cp[] */
10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    length=LENGTHOF(b);
10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<length;) {
10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i;
10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT_UNSAFE(b, j, cu);
10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iu=j;
10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i;
10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT(b, j, length, cs);
10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        is=j;
10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i;
10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        L8_NEXT(b, j, length, cl);
10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        il=j;
10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(cu!=cp[k]) {
10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT_UNSAFE(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cu, (long)cp[k]);
10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* U8_NEXT() returns <0 for surrogate code points */
10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U_IS_SURROGATE(cu) ? cs>=0 : cs!=cu) {
10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cs, (long)cu);
10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* L8_NEXT() returns surrogate code points like U8_NEXT_UNSAFE() */
10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(cl!=cu) {
10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("L8_NEXT(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cl, (long)cu);
10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(is!=iu || il!=iu) {
10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_NEXT(b[%ld]) or L8_NEXT(b[%ld]) did not advance the index correctly\n", (long)i, (long)i);
10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ++k;    /* next code point */
10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i=iu;   /* advance by one UTF-8 sequence */
10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    while(i>0) {
10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        --k; /* previous code point */
10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i;
10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_PREV_UNSAFE(b, j, cu);
10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iu=j;
10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i;
10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_PREV(b, 0, j, cs);
10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        is=j;
11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        j=i;
11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        L8_PREV(b, 0, j, cl);
11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        il=j;
11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(cu!=cp[k]) {
11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_PREV_UNSAFE(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cu, (long)cp[k]);
11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* U8_PREV() returns <0 for surrogate code points */
11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U_IS_SURROGATE(cu) ? cs>=0 : cs!=cu) {
11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_PREV(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cs, (long)cu);
11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* L8_PREV() returns surrogate code points like U8_PREV_UNSAFE() */
11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(cl!=cu) {
11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("L8_PREV(b[%ld])=U+%04lX != U+%04lX\n", (long)i, (long)cl, (long)cu);
11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(is!=iu || il !=iu) {
11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            log_err("U8_PREV(b[%ld]) or L8_PREV(b[%ld]) did not advance the index correctly\n", (long)i, (long)i);
11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        i=iu;   /* go back by one UTF-8 sequence */
11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void printUChars(const uint8_t *uchars, int16_t len){
11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int16_t i=0;
11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i=0; i<len; i++){
11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        log_err("0x%02x ", *(uchars+i));
11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1133