16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 2002-2012, International Business Machines
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Corporation and others.  All Rights Reserved.
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   file name:  uiter.cpp
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   encoding:   US-ASCII
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   tab size:   8 (not used)
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   indentation:4
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created on: 2002jan18
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created by: Markus W. Scherer
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/chariter.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/rep.h"
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uiter.h"
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf.h"
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf8.h"
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf16.h"
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h"
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_USE
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define IS_EVEN(n) (((n)&1)==0)
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define IS_POINTER_EVEN(p) IS_EVEN((size_t)p)
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* No-Op UCharIterator implementation for illegal input --------------------- */
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnoopGetIndex(UCharIterator * /*iter*/, UCharIteratorOrigin /*origin*/) {
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnoopMove(UCharIterator * /*iter*/, int32_t /*delta*/, UCharIteratorOrigin /*origin*/) {
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnoopHasNext(UCharIterator * /*iter*/) {
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnoopCurrent(UCharIterator * /*iter*/) {
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return U_SENTINEL;
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint32_t U_CALLCONV
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnoopGetState(const UCharIterator * /*iter*/) {
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return UITER_NO_STATE;
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnoopSetState(UCharIterator * /*iter*/, uint32_t /*state*/, UErrorCode *pErrorCode) {
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *pErrorCode=U_UNSUPPORTED_ERROR;
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UCharIterator noopIterator={
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0, 0, 0, 0, 0, 0,
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopGetIndex,
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopMove,
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopHasNext,
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopHasNext,
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopCurrent,
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopCurrent,
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopCurrent,
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopGetState,
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    noopSetState
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UCharIterator implementation for simple strings -------------------------- */
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is an implementation of a code unit (UChar) iterator
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for UChar * strings.
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The UCharIterator.context field holds a pointer to the string.
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorGetIndex(UCharIterator *iter, UCharIteratorOrigin origin) {
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(origin) {
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_ZERO:
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_START:
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->start;
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_CURRENT:
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->index;
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LIMIT:
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->limit;
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LENGTH:
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->length;
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* not a valid origin */
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Should never get here! */
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorMove(UCharIterator *iter, int32_t delta, UCharIteratorOrigin origin) {
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t pos;
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(origin) {
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_ZERO:
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=delta;
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_START:
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=iter->start+delta;
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_CURRENT:
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=iter->index+delta;
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LIMIT:
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=iter->limit+delta;
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LENGTH:
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=iter->length+delta;
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;  /* Error */
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pos<iter->start) {
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=iter->start;
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(pos>iter->limit) {
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=iter->limit;
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return iter->index=pos;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorHasNext(UCharIterator *iter) {
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return iter->index<iter->limit;
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorHasPrevious(UCharIterator *iter) {
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return iter->index>iter->start;
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorCurrent(UCharIterator *iter) {
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index<iter->limit) {
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((const UChar *)(iter->context))[iter->index];
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorNext(UCharIterator *iter) {
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index<iter->limit) {
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((const UChar *)(iter->context))[iter->index++];
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorPrevious(UCharIterator *iter) {
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index>iter->start) {
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((const UChar *)(iter->context))[--iter->index];
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint32_t U_CALLCONV
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorGetState(const UCharIterator *iter) {
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (uint32_t)iter->index;
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstringIteratorSetState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode) {
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* do nothing */
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter==NULL) {
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if((int32_t)state<iter->start || iter->limit<(int32_t)state) {
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->index=(int32_t)state;
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UCharIterator stringIterator={
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0, 0, 0, 0, 0, 0,
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorGetIndex,
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorMove,
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorHasNext,
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorHasPrevious,
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorCurrent,
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorNext,
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorPrevious,
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorGetState,
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorSetState
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_setString(UCharIterator *iter, const UChar *s, int32_t length) {
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter!=0) {
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(s!=0 && length>=-1) {
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=stringIterator;
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->context=s;
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(length>=0) {
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length=length;
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length=u_strlen(s);
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->limit=iter->length;
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=noopIterator;
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UCharIterator implementation for UTF-16BE strings ------------------------ */
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is an implementation of a code unit (UChar) iterator
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for UTF-16BE strings, i.e., strings in byte-vectors where
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * each UChar is stored as a big-endian pair of bytes.
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The UCharIterator.context field holds a pointer to the string.
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Everything works just like with a normal UChar iterator (uiter_setString),
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * except that UChars are assembled from byte pairs.
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* internal helper function */
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UChar32
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf16BEIteratorGet(UCharIterator *iter, int32_t index) {
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *p=(const uint8_t *)iter->context;
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((UChar)p[2*index]<<8)|(UChar)p[2*index+1];
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf16BEIteratorCurrent(UCharIterator *iter) {
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t index;
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if((index=iter->index)<iter->limit) {
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return utf16BEIteratorGet(iter, index);
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf16BEIteratorNext(UCharIterator *iter) {
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t index;
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if((index=iter->index)<iter->limit) {
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->index=index+1;
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return utf16BEIteratorGet(iter, index);
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf16BEIteratorPrevious(UCharIterator *iter) {
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t index;
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if((index=iter->index)>iter->start) {
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->index=--index;
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return utf16BEIteratorGet(iter, index);
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UCharIterator utf16BEIterator={
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0, 0, 0, 0, 0, 0,
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorGetIndex,
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorMove,
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorHasNext,
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorHasPrevious,
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf16BEIteratorCurrent,
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf16BEIteratorNext,
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf16BEIteratorPrevious,
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorGetState,
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorSetState
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Count the number of UChars in a UTF-16BE string before a terminating UChar NUL,
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * i.e., before a pair of 0 bytes where the first 0 byte is at an even
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * offset from s.
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf16BE_strlen(const char *s) {
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(IS_POINTER_EVEN(s)) {
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /*
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * even-aligned, call u_strlen(s)
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * we are probably on a little-endian machine, but searching for UChar NUL
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         * does not care about endianness
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         */
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return u_strlen((const UChar *)s);
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* odd-aligned, search for pair of 0 bytes */
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const char *p=s;
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while(!(*p==0 && p[1]==0)) {
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            p+=2;
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return (int32_t)((p-s)/2);
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_setUTF16BE(UCharIterator *iter, const char *s, int32_t length) {
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter!=NULL) {
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* allow only even-length strings (the input length counts bytes) */
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(s!=NULL && (length==-1 || (length>=0 && IS_EVEN(length)))) {
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* length/=2, except that >>=1 also works for -1 (-1/2==0, -1>>1==-1) */
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            length>>=1;
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(U_IS_BIG_ENDIAN && IS_POINTER_EVEN(s)) {
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* big-endian machine and 2-aligned UTF-16BE string: use normal UChar iterator */
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                uiter_setString(iter, (const UChar *)s, length);
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return;
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=utf16BEIterator;
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->context=s;
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(length>=0) {
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length=length;
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length=utf16BE_strlen(s);
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->limit=iter->length;
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=noopIterator;
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UCharIterator wrapper around CharacterIterator --------------------------- */
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is wrapper code around a C++ CharacterIterator to
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * look like a C UCharIterator.
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The UCharIterator.context field holds a pointer to the CharacterIterator.
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorGetIndex(UCharIterator *iter, UCharIteratorOrigin origin) {
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(origin) {
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_ZERO:
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_START:
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->startIndex();
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_CURRENT:
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->getIndex();
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LIMIT:
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->endIndex();
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LENGTH:
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->getLength();
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* not a valid origin */
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Should never get here! */
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorMove(UCharIterator *iter, int32_t delta, UCharIteratorOrigin origin) {
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(origin) {
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_ZERO:
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((CharacterIterator *)(iter->context))->setIndex(delta);
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->getIndex();
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_START:
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_CURRENT:
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LIMIT:
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->move(delta, (CharacterIterator::EOrigin)origin);
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LENGTH:
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((CharacterIterator *)(iter->context))->setIndex(((CharacterIterator *)(iter->context))->getLength()+delta);
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->getIndex();
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* not a valid origin */
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Should never get here! */
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorHasNext(UCharIterator *iter) {
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((CharacterIterator *)(iter->context))->hasNext();
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorHasPrevious(UCharIterator *iter) {
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((CharacterIterator *)(iter->context))->hasPrevious();
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorCurrent(UCharIterator *iter) {
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c;
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    c=((CharacterIterator *)(iter->context))->current();
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(c!=0xffff || ((CharacterIterator *)(iter->context))->hasNext()) {
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return c;
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorNext(UCharIterator *iter) {
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(((CharacterIterator *)(iter->context))->hasNext()) {
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->nextPostInc();
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorPrevious(UCharIterator *iter) {
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(((CharacterIterator *)(iter->context))->hasPrevious()) {
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((CharacterIterator *)(iter->context))->previous();
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint32_t U_CALLCONV
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorGetState(const UCharIterator *iter) {
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ((CharacterIterator *)(iter->context))->getIndex();
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcharacterIteratorSetState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode) {
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* do nothing */
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter==NULL || iter->context==NULL) {
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if((int32_t)state<((CharacterIterator *)(iter->context))->startIndex() || ((CharacterIterator *)(iter->context))->endIndex()<(int32_t)state) {
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ((CharacterIterator *)(iter->context))->setIndex((int32_t)state);
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UCharIterator characterIteratorWrapper={
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0, 0, 0, 0, 0, 0,
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorGetIndex,
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorMove,
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorHasNext,
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorHasPrevious,
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorCurrent,
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorNext,
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorPrevious,
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorGetState,
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    characterIteratorSetState
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_setCharacterIterator(UCharIterator *iter, CharacterIterator *charIter) {
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter!=0) {
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(charIter!=0) {
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=characterIteratorWrapper;
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->context=charIter;
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=noopIterator;
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UCharIterator wrapper around Replaceable --------------------------------- */
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is an implementation of a code unit (UChar) iterator
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * based on a Replaceable object.
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The UCharIterator.context field holds a pointer to the Replaceable.
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * UCharIterator.length and UCharIterator.index hold Replaceable.length()
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and the iteration index.
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgreplaceableIteratorCurrent(UCharIterator *iter) {
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index<iter->limit) {
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((Replaceable *)(iter->context))->charAt(iter->index);
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgreplaceableIteratorNext(UCharIterator *iter) {
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index<iter->limit) {
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((Replaceable *)(iter->context))->charAt(iter->index++);
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgreplaceableIteratorPrevious(UCharIterator *iter) {
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index>iter->start) {
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return ((Replaceable *)(iter->context))->charAt(--iter->index);
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UCharIterator replaceableIterator={
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0, 0, 0, 0, 0, 0,
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorGetIndex,
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorMove,
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorHasNext,
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorHasPrevious,
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    replaceableIteratorCurrent,
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    replaceableIteratorNext,
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    replaceableIteratorPrevious,
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorGetState,
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    stringIteratorSetState
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_setReplaceable(UCharIterator *iter, const Replaceable *rep) {
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter!=0) {
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(rep!=0) {
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=replaceableIterator;
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->context=rep;
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->limit=iter->length=rep->length();
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=noopIterator;
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* UCharIterator implementation for UTF-8 strings --------------------------- */
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Possible, probably necessary only for an implementation for arbitrary
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * converters:
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Maintain a buffer (ring buffer?) for a piece of converted 16-bit text.
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This would require to turn reservedFn into a close function and
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to introduce a uiter_close(iter).
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UITER_CNV_CAPACITY 16
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Minimal implementation:
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Maintain a single-UChar buffer for an additional surrogate.
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The caller must not modify start and limit because they are used internally.
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Use UCharIterator fields as follows:
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   context        pointer to UTF-8 string
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   length         UTF-16 length of the string; -1 until lazy evaluation
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   start          current UTF-8 index
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   index          current UTF-16 index; may be -1="unknown" after setState()
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   limit          UTF-8 length of the string
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *   reservedField  supplementary code point
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Since UCharIterator delivers 16-bit code units, the iteration can be
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * currently in the middle of the byte sequence for a supplementary code point.
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In this case, reservedField will contain that code point and start will
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * point to after the corresponding byte sequence. The UTF-16 index will be
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * one less than what it would otherwise be corresponding to the UTF-8 index.
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Otherwise, reservedField will be 0.
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Possible optimization for NUL-terminated UTF-8 and UTF-16 strings:
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Add implementations that do not call strlen() for iteration but check for NUL.
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorGetIndex(UCharIterator *iter, UCharIteratorOrigin origin) {
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(origin) {
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_ZERO:
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_START:
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_CURRENT:
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->index<0) {
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* the current UTF-16 index is unknown after setState(), count from the beginning */
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const uint8_t *s;
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UChar32 c;
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t i, limit, index;
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            s=(const uint8_t *)iter->context;
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            i=index=0;
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            limit=iter->start; /* count up to the UTF-8 index */
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while(i<limit) {
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                U8_NEXT_OR_FFFD(s, i, limit, c);
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                index+=U16_LENGTH(c);
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start=i; /* just in case setState() did not get us to a code point boundary */
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(i==iter->limit) {
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length=index; /* in case it was <0 or wrong */
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(iter->reservedField!=0) {
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                --index; /* we are in the middle of a supplementary code point */
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=index;
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->index;
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LIMIT:
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LENGTH:
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->length<0) {
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const uint8_t *s;
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UChar32 c;
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t i, limit, length;
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            s=(const uint8_t *)iter->context;
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(iter->index<0) {
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /*
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 * the current UTF-16 index is unknown after setState(),
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 * we must first count from the beginning to here
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                 */
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                i=length=0;
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                limit=iter->start;
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* count from the beginning to the current index */
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                while(i<limit) {
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    U8_NEXT_OR_FFFD(s, i, limit, c);
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    length+=U16_LENGTH(c);
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* assume i==limit==iter->start, set the UTF-16 index */
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->start=i; /* just in case setState() did not get us to a code point boundary */
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->index= iter->reservedField!=0 ? length-1 : length;
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                i=iter->start;
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                length=iter->index;
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(iter->reservedField!=0) {
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    ++length;
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* count from the current index to the end */
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            limit=iter->limit;
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while(i<limit) {
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                U8_NEXT_OR_FFFD(s, i, limit, c);
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                length+=U16_LENGTH(c);
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->length=length;
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->length;
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* not a valid origin */
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Should never get here! */
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorMove(UCharIterator *iter, int32_t delta, UCharIteratorOrigin origin) {
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const uint8_t *s;
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c;
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t pos; /* requested UTF-16 index */
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i; /* UTF-8 index */
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool havePos;
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* calculate the requested UTF-16 index */
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    switch(origin) {
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_ZERO:
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_START:
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pos=delta;
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        havePos=TRUE;
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* iter->index<0 (unknown) is possible */
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_CURRENT:
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->index>=0) {
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pos=iter->index+delta;
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            havePos=TRUE;
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* the current UTF-16 index is unknown after setState(), use only delta */
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pos=0;
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            havePos=FALSE;
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LIMIT:
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    case UITER_LENGTH:
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->length>=0) {
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            pos=iter->length+delta;
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            havePos=TRUE;
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* pin to the end, avoid counting the length */
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=-1;
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start=iter->limit;
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=0;
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(delta>=0) {
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                return UITER_UNKNOWN_INDEX;
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* the current UTF-16 index is unknown, use only delta */
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                pos=0;
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                havePos=FALSE;
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    default:
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return -1;  /* Error */
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(havePos) {
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* shortcuts: pinning to the edges of the string */
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(pos<=0) {
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=iter->start=iter->reservedField=0;
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(iter->length>=0 && pos>=iter->length) {
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=iter->length;
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start=iter->limit;
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=0;
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return iter->index;
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* minimize the number of U8_NEXT/PREV operations */
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->index<0 || pos<iter->index/2) {
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* go forward from the start instead of backward from the current index */
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=iter->start=iter->reservedField=0;
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(iter->length>=0 && (iter->length-pos)<(pos-iter->index)) {
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /*
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             * if we have the UTF-16 index and length and the new position is
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             * closer to the end than the current index,
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             * then go backward from the end instead of forward from the current index
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             */
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=iter->length;
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start=iter->limit;
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=0;
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delta=pos-iter->index;
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(delta==0) {
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return iter->index; /* nothing to do */
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* move relative to unknown UTF-16 index */
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(delta==0) {
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UITER_UNKNOWN_INDEX; /* nothing to do */
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(-delta>=iter->start) {
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* moving backwards by more UChars than there are UTF-8 bytes, pin to 0 */
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=iter->start=iter->reservedField=0;
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 0;
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(delta>=(iter->limit-iter->start)) {
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* moving forward by more UChars than the remaining UTF-8 bytes, pin to the end */
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=iter->length; /* may or may not be <0 (unknown) */
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start=iter->limit;
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=0;
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return iter->index>=0 ? iter->index : (int32_t)UITER_UNKNOWN_INDEX;
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* delta!=0 */
7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* move towards the requested position, pin to the edges of the string */
7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    s=(const uint8_t *)iter->context;
7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pos=iter->index; /* could be <0 (unknown) */
7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    i=iter->start;
7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(delta>0) {
7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* go forward */
7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t limit=iter->limit;
7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->reservedField!=0) {
7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=0;
7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ++pos;
7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            --delta;
7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while(delta>0 && i<limit) {
7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_NEXT_OR_FFFD(s, i, limit, c);
7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c<=0xffff) {
7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++pos;
7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                --delta;
7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else if(delta>=2) {
7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                pos+=2;
7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delta-=2;
7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else /* delta==1 */ {
7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* stop in the middle of a supplementary code point */
7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->reservedField=c;
7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++pos;
7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break; /* delta=0; */
7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(i==limit) {
7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(iter->length<0 && iter->index>=0) {
7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length= iter->reservedField==0 ? pos : pos+1;
7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else if(iter->index<0 && iter->length>=0) {
7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->index= iter->reservedField==0 ? iter->length : iter->length-1;
7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else /* delta<0 */ {
8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* go backward */
8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(iter->reservedField!=0) {
8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=0;
8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            i-=4; /* we stayed behind the supplementary code point; go before it now */
8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            --pos;
8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ++delta;
8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while(delta<0 && i>0) {
8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            U8_PREV_OR_FFFD(s, 0, i, c);
8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c<=0xffff) {
8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                --pos;
8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++delta;
8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else if(delta<=-2) {
8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                pos-=2;
8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                delta+=2;
8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else /* delta==-1 */ {
8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* stop in the middle of a supplementary code point */
8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                i+=4; /* back to behind this supplementary code point for consistent state */
8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->reservedField=c;
8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                --pos;
8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break; /* delta=0; */
8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    iter->start=i;
8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->index>=0) {
8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->index=pos;
8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* we started with index<0 (unknown) so pos is bogus */
8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(i<=1) {
8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return iter->index=i; /* reached the beginning */
8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* we still don't know the UTF-16 index */
8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UITER_UNKNOWN_INDEX;
8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorHasNext(UCharIterator *iter) {
8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return iter->start<iter->limit || iter->reservedField!=0;
8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV
8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorHasPrevious(UCharIterator *iter) {
8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return iter->start>0;
8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorCurrent(UCharIterator *iter) {
8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->reservedField!=0) {
8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U16_TRAIL(iter->reservedField);
8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter->start<iter->limit) {
8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const uint8_t *s=(const uint8_t *)iter->context;
8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar32 c;
8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t i=iter->start;
8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT_OR_FFFD(s, i, iter->limit, c);
8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c<=0xffff) {
8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return c;
8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return U16_LEAD(c);
8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorNext(UCharIterator *iter) {
8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t index;
8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->reservedField!=0) {
8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar trail=U16_TRAIL(iter->reservedField);
8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->reservedField=0;
8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((index=iter->index)>=0) {
8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=index+1;
8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return trail;
8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter->start<iter->limit) {
8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const uint8_t *s=(const uint8_t *)iter->context;
8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar32 c;
8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_NEXT_OR_FFFD(s, iter->start, iter->limit, c);
8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((index=iter->index)>=0) {
8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=++index;
8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(iter->length<0 && iter->start==iter->limit) {
8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->length= c<=0xffff ? index : index+1;
8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(iter->start==iter->limit && iter->length>=0) {
8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index= c<=0xffff ? iter->length : iter->length-1;
8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c<=0xffff) {
8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return c;
8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=c;
8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return U16_LEAD(c);
8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UChar32 U_CALLCONV
9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorPrevious(UCharIterator *iter) {
9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t index;
9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->reservedField!=0) {
9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar lead=U16_LEAD(iter->reservedField);
9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->reservedField=0;
9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->start-=4; /* we stayed behind the supplementary code point; go before it now */
9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((index=iter->index)>0) {
9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=index-1;
9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return lead;
9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter->start>0) {
9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const uint8_t *s=(const uint8_t *)iter->context;
9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar32 c;
9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U8_PREV_OR_FFFD(s, 0, iter->start, c);
9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((index=iter->index)>0) {
9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index=index-1;
9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(iter->start<=1) {
9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->index= c<=0xffff ? iter->start : iter->start+1;
9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(c<=0xffff) {
9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return c;
9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start+=4; /* back to behind this supplementary code point for consistent state */
9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->reservedField=c;
9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return U16_TRAIL(c);
9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_SENTINEL;
9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint32_t U_CALLCONV
9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorGetState(const UCharIterator *iter) {
9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t state=(uint32_t)(iter->start<<1);
9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter->reservedField!=0) {
9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        state|=1;
9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return state;
9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void U_CALLCONV
9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgutf8IteratorSetState(UCharIterator *iter,
9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     uint32_t state,
9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     UErrorCode *pErrorCode)
9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* do nothing */
9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter==NULL) {
9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(state==utf8IteratorGetState(iter)) {
9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* setting to the current state: no-op */
9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t index=(int32_t)(state>>1); /* UTF-8 index */
9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        state&=1; /* 1 if in surrogate pair, must be index>=4 */
9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if((state==0 ? index<0 : index<4) || iter->limit<index) {
9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->start=index; /* restore UTF-8 byte index */
9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(index<=1) {
9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->index=index;
9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->index=-1; /* unknown UTF-16 index */
9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(state==0) {
9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->reservedField=0;
9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* verified index>=4 above */
9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UChar32 c;
9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                U8_PREV_OR_FFFD((const uint8_t *)iter->context, 0, index, c);
9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(c<=0xffff) {
9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                } else {
9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    iter->reservedField=c;
9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UCharIterator utf8Iterator={
9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    0, 0, 0, 0, 0, 0,
9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorGetIndex,
9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorMove,
9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorHasNext,
9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorHasPrevious,
9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorCurrent,
9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorNext,
9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorPrevious,
9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    NULL,
9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorGetState,
9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    utf8IteratorSetState
9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2
10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_setUTF8(UCharIterator *iter, const char *s, int32_t length) {
10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter!=0) {
10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(s!=0 && length>=-1) {
10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=utf8Iterator;
10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->context=s;
10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(length>=0) {
10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->limit=length;
10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            } else {
10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->limit=(int32_t)uprv_strlen(s);
10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->length= iter->limit<=1 ? iter->limit : -1;
10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            *iter=noopIterator;
10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Helper functions --------------------------------------------------------- */
10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UChar32 U_EXPORT2
10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_current32(UCharIterator *iter) {
10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c, c2;
10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    c=iter->current(iter);
10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U16_IS_SURROGATE(c)) {
10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U16_IS_SURROGATE_LEAD(c)) {
10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /*
10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             * go to the next code unit
10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             * we know that we are not at the limit because c!=U_SENTINEL
10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org             */
10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->move(iter, 1, UITER_CURRENT);
10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(U16_IS_TRAIL(c2=iter->current(iter))) {
10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                c=U16_GET_SUPPLEMENTARY(c, c2);
10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* undo index movement */
10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->move(iter, -1, UITER_CURRENT);
10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(U16_IS_LEAD(c2=iter->previous(iter))) {
10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                c=U16_GET_SUPPLEMENTARY(c2, c);
10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(c2>=0) {
10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* undo index movement */
10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                iter->move(iter, 1, UITER_CURRENT);
10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return c;
10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UChar32 U_EXPORT2
10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_next32(UCharIterator *iter) {
10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c, c2;
10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    c=iter->next(iter);
10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U16_IS_LEAD(c)) {
10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U16_IS_TRAIL(c2=iter->next(iter))) {
10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            c=U16_GET_SUPPLEMENTARY(c, c2);
10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(c2>=0) {
10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* unmatched first surrogate, undo index movement */
10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->move(iter, -1, UITER_CURRENT);
10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return c;
10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UChar32 U_EXPORT2
10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_previous32(UCharIterator *iter) {
10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar32 c, c2;
10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    c=iter->previous(iter);
10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U16_IS_TRAIL(c)) {
10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(U16_IS_LEAD(c2=iter->previous(iter))) {
10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            c=U16_GET_SUPPLEMENTARY(c2, c);
10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(c2>=0) {
10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* unmatched second surrogate, undo index movement */
10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            iter->move(iter, 1, UITER_CURRENT);
10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return c;
10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI uint32_t U_EXPORT2
10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_getState(const UCharIterator *iter) {
10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(iter==NULL || iter->getState==NULL) {
10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return UITER_NO_STATE;
10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return iter->getState(iter);
10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2
10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguiter_setState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode) {
10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* do nothing */
10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter==NULL) {
10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(iter->setState==NULL) {
11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_UNSUPPORTED_ERROR;
11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        iter->setState(iter, state, pErrorCode);
11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END
1107