/*
*******************************************************************************
*
*   Copyright (C) 2004-2006, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  ucase.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2004aug30
*   created by: Markus W. Scherer
*
*   Low-level Unicode character/string case mapping code.
*   Much code moved here (and modified) from uchar.c.
*/

#include "unicode/utypes.h"
#include "unicode/uset.h"
#include "unicode/udata.h" /* UDataInfo */
#include "ucmndata.h" /* DataHeader */
#include "udatamem.h"
#include "umutex.h"
#include "uassert.h"
#include "cmemory.h"
#include "utrie.h"
#include "ucase.h"
#include "ucln_cmn.h"

struct UCaseProps {
    UDataMemory *mem;
    const int32_t *indexes;
    const uint16_t *exceptions;
    const UChar *unfold;

    UTrie trie;
    uint8_t formatVersion[4];
};

/* data loading etc. -------------------------------------------------------- */

#define UCASE_HARDCODE_DATA 1

#if UCASE_HARDCODE_DATA

/* ucase_props_data.c is machine-generated by gencase --csource */
#include "ucase_props_data.c"

#else

static UBool U_CALLCONV
isAcceptable(void *context,
             const char *type, const char *name,
             const UDataInfo *pInfo) {
    if(
        pInfo->size>=20 &&
        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
        pInfo->charsetFamily==U_CHARSET_FAMILY &&
        pInfo->dataFormat[0]==UCASE_FMT_0 &&    /* dataFormat="cAsE" */
        pInfo->dataFormat[1]==UCASE_FMT_1 &&
        pInfo->dataFormat[2]==UCASE_FMT_2 &&
        pInfo->dataFormat[3]==UCASE_FMT_3 &&
        pInfo->formatVersion[0]==1 &&
        pInfo->formatVersion[2]==UTRIE_SHIFT &&
        pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT
    ) {
        UCaseProps *csp=(UCaseProps *)context;
        uprv_memcpy(csp->formatVersion, pInfo->formatVersion, 4);
        return TRUE;
    } else {
        return FALSE;
    }
}

static UCaseProps *
ucase_openData(UCaseProps *cspProto,
               const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
    UCaseProps *csp;
    int32_t size;

    cspProto->indexes=(const int32_t *)bin;
    if( (length>=0 && length<16*4) ||
        cspProto->indexes[UCASE_IX_INDEX_TOP]<16
    ) {
        /* length or indexes[] too short for minimum indexes[] length of 16 */
        *pErrorCode=U_INVALID_FORMAT_ERROR;
        return NULL;
    }
    size=cspProto->indexes[UCASE_IX_INDEX_TOP]*4;
    if(length>=0) {
        if(length>=size && length>=cspProto->indexes[UCASE_IX_LENGTH]) {
            length-=size;
        } else {
            /* length too short for indexes[] or for the whole data length */
            *pErrorCode=U_INVALID_FORMAT_ERROR;
            return NULL;
        }
    }
    bin+=size;
    /* from here on, assume that the sizes of the items fit into the total length */

    /* unserialize the trie, after indexes[] */
    size=cspProto->indexes[UCASE_IX_TRIE_SIZE];
    utrie_unserialize(&cspProto->trie, bin, size, pErrorCode);
    if(U_FAILURE(*pErrorCode)) {
        return NULL;
    }
    bin+=size;

    /* get exceptions[] */
    size=2*cspProto->indexes[UCASE_IX_EXC_LENGTH];
    cspProto->exceptions=(const uint16_t *)bin;
    bin+=size;

    /* get unfold[] */
    size=2*cspProto->indexes[UCASE_IX_UNFOLD_LENGTH];
    if(size!=0) {
        cspProto->unfold=(const UChar *)bin;
        bin+=size;
    } else {
        cspProto->unfold=NULL;
    }

    /* allocate, copy, and return the new UCaseProps */
    csp=(UCaseProps *)uprv_malloc(sizeof(UCaseProps));
    if(csp==NULL) {
        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    } else {
        uprv_memcpy(csp, cspProto, sizeof(UCaseProps));
        return csp;
    }
}

U_CAPI UCaseProps * U_EXPORT2
ucase_open(UErrorCode *pErrorCode) {
    UCaseProps cspProto={ NULL }, *csp;

    cspProto.mem=udata_openChoice(NULL, UCASE_DATA_TYPE, UCASE_DATA_NAME, isAcceptable, &cspProto, pErrorCode);
    if(U_FAILURE(*pErrorCode)) {
        return NULL;
    }

    csp=ucase_openData(
            &cspProto,
            udata_getMemory(cspProto.mem),
            udata_getLength(cspProto.mem),
            pErrorCode);
    if(U_FAILURE(*pErrorCode)) {
        udata_close(cspProto.mem);
        return NULL;
    } else {
        return csp;
    }
}

U_CAPI UCaseProps * U_EXPORT2
ucase_openBinary(const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
    UCaseProps cspProto={ NULL };
    const DataHeader *hdr;

    if(U_FAILURE(*pErrorCode)) {
        return NULL;
    }
    if(bin==NULL) {
        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return NULL;
    }

    /* check the header */
    if(length>=0 && length<20) {
        *pErrorCode=U_INVALID_FORMAT_ERROR;
        return NULL;
    }
    hdr=(const DataHeader *)bin;
    if(
        !(hdr->dataHeader.magic1==0xda && hdr->dataHeader.magic2==0x27 &&
          hdr->info.isBigEndian==U_IS_BIG_ENDIAN &&
          isAcceptable(&cspProto, UCASE_DATA_TYPE, UCASE_DATA_NAME, &hdr->info))
    ) {
        *pErrorCode=U_INVALID_FORMAT_ERROR;
        return NULL;
    }

    bin+=hdr->dataHeader.headerSize;
    if(length>=0) {
        length-=hdr->dataHeader.headerSize;
    }
    return ucase_openData(&cspProto, bin, length, pErrorCode);
}

#endif

U_CAPI void U_EXPORT2
ucase_close(UCaseProps *csp) {
    if(csp!=NULL) {
#if !UCASE_HARDCODE_DATA
        udata_close(csp->mem);
#endif
        uprv_free(csp);
    }
}

/* UCaseProps singleton ----------------------------------------------------- */

static UCaseProps *gCsp=NULL, *gCspDummy=NULL;
#if !UCASE_HARDCODE_DATA
static UErrorCode gErrorCode=U_ZERO_ERROR;
static int8_t gHaveData=0;
#endif

static UBool U_CALLCONV ucase_cleanup(void) {
    ucase_close(gCsp);
    gCsp=NULL;
    ucase_close(gCspDummy);
    gCspDummy=NULL;
#if !UCASE_HARDCODE_DATA
    gErrorCode=U_ZERO_ERROR;
    gHaveData=0;
#endif
    return TRUE;
}

U_CAPI const UCaseProps * U_EXPORT2
ucase_getSingleton(UErrorCode *pErrorCode) {
#if UCASE_HARDCODE_DATA
    if(U_FAILURE(*pErrorCode)) {
        return NULL;
    }
    return &ucase_props_singleton;
#else
    int8_t haveData;

    if(U_FAILURE(*pErrorCode)) {
        return NULL;
    }

    UMTX_CHECK(NULL, gHaveData, haveData);

    if(haveData>0) {
        /* data was loaded */
        return gCsp;
    } else if(haveData<0) {
        /* data loading failed */
        *pErrorCode=gErrorCode;
        return NULL;
    } else /* haveData==0 */ {
        /* load the data */
        UCaseProps *csp=ucase_open(pErrorCode);
        if(U_FAILURE(*pErrorCode)) {
            gHaveData=-1;
            gErrorCode=*pErrorCode;
            return NULL;
        }

        /* set the static variables */
        umtx_lock(NULL);
        if(gCsp==NULL) {
            gCsp=csp;
            csp=NULL;
            gHaveData=1;
            ucln_common_registerCleanup(UCLN_COMMON_UCASE, ucase_cleanup);
        }
        umtx_unlock(NULL);

        ucase_close(csp);
        return gCsp;
    }
#endif
}

U_CAPI const UCaseProps * U_EXPORT2
ucase_getDummy(UErrorCode *pErrorCode) {
    UCaseProps *csp;

    if(U_FAILURE(*pErrorCode)) {
        return NULL;
    }

    UMTX_CHECK(NULL, gCspDummy, csp);

    if(csp!=NULL) {
        /* the dummy object was already created */
        return csp;
    } else /* csp==NULL */ {
        /* create the dummy object */
        int32_t *indexes;
        
        csp=(UCaseProps *)uprv_malloc(sizeof(UCaseProps)+UCASE_IX_TOP*4+UTRIE_DUMMY_SIZE);
        if(csp==NULL) {
            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        uprv_memset(csp, 0, sizeof(UCaseProps)+UCASE_IX_TOP*4);

        csp->indexes=indexes=(int32_t *)(csp+1);
        indexes[UCASE_IX_INDEX_TOP]=UCASE_IX_TOP;

        indexes[UCASE_IX_TRIE_SIZE]=
            utrie_unserializeDummy(&csp->trie, indexes+UCASE_IX_TOP, UTRIE_DUMMY_SIZE, 0, 0, TRUE, pErrorCode);
        if(U_FAILURE(*pErrorCode)) {
            uprv_free(csp);
            return NULL;
        }

        csp->formatVersion[0]=1;
        csp->formatVersion[2]=UTRIE_SHIFT;
        csp->formatVersion[3]=UTRIE_INDEX_SHIFT;

        /* set the static variables */
        umtx_lock(NULL);
        if(gCspDummy==NULL) {
            gCspDummy=csp;
            csp=NULL;
            ucln_common_registerCleanup(UCLN_COMMON_UCASE, ucase_cleanup);
        }
        umtx_unlock(NULL);

        uprv_free(csp);
        return gCspDummy;
    }
}

/* set of property starts for UnicodeSet ------------------------------------ */

static UBool U_CALLCONV
_enumPropertyStartsRange(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
    /* add the start code point to the USet */
    const USetAdder *sa=(const USetAdder *)context;
    sa->add(sa->set, start);
    return TRUE;
}

U_CAPI void U_EXPORT2
ucase_addPropertyStarts(const UCaseProps *csp, const USetAdder *sa, UErrorCode *pErrorCode) {
    if(U_FAILURE(*pErrorCode)) {
        return;
    }

    /* add the start code point of each same-value range of the trie */
    utrie_enum(&csp->trie, NULL, _enumPropertyStartsRange, sa);

    /* add code points with hardcoded properties, plus the ones following them */

    /* (none right now, see comment below) */

    /*
     * Omit code points with hardcoded specialcasing properties
     * because we do not build property UnicodeSets for them right now.
     */
}

/* data access primitives --------------------------------------------------- */

/* UTRIE_GET16() itself validates c */
#define GET_PROPS(csp, c, result) \
    UTRIE_GET16(&(csp)->trie, c, result);

#define GET_EXCEPTIONS(csp, props) ((csp)->exceptions+((props)>>UCASE_EXC_SHIFT))

#define PROPS_HAS_EXCEPTION(props) ((props)&UCASE_EXCEPTION)

/* number of bits in an 8-bit integer value */
static const uint8_t flagsOffset[256]={
    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};

#define HAS_SLOT(flags, index) ((flags)&(1<<(index)))
#define SLOT_OFFSET(flags, index) flagsOffset[(flags)&((1<<(index))-1)]

/*
 * Get the value of an optional-value slot where HAS_SLOT(excWord, index).
 *
 * @param excWord (in) initial exceptions word
 * @param index (in) desired slot index
 * @param pExc16 (in/out) const uint16_t * after excWord=*pExc16++;
 *               moved to the last uint16_t of the value, use +1 for beginning of next slot
 * @param value (out) int32_t or uint32_t output if hasSlot, otherwise not modified
 */
#define GET_SLOT_VALUE(excWord, index, pExc16, value) \
    if(((excWord)&UCASE_EXC_DOUBLE_SLOTS)==0) { \
        (pExc16)+=SLOT_OFFSET(excWord, index); \
        (value)=*pExc16; \
    } else { \
        (pExc16)+=2*SLOT_OFFSET(excWord, index); \
        (value)=*pExc16++; \
        (value)=((value)<<16)|*pExc16; \
    }

/* simple case mappings ----------------------------------------------------- */

U_CAPI UChar32 U_EXPORT2
ucase_tolower(const UCaseProps *csp, UChar32 c) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
            c+=UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
        uint16_t excWord=*pe++;
        if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
            GET_SLOT_VALUE(excWord, UCASE_EXC_LOWER, pe, c);
        }
    }
    return c;
}

U_CAPI UChar32 U_EXPORT2
ucase_toupper(const UCaseProps *csp, UChar32 c) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
            c+=UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
        uint16_t excWord=*pe++;
        if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
            GET_SLOT_VALUE(excWord, UCASE_EXC_UPPER, pe, c);
        }
    }
    return c;
}

U_CAPI UChar32 U_EXPORT2
ucase_totitle(const UCaseProps *csp, UChar32 c) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
            c+=UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
        uint16_t excWord=*pe++;
        int32_t index;
        if(HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
            index=UCASE_EXC_TITLE;
        } else if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
            index=UCASE_EXC_UPPER;
        } else {
            return c;
        }
        GET_SLOT_VALUE(excWord, index, pe, c);
    }
    return c;
}

U_CAPI void U_EXPORT2
ucase_addCaseClosure(const UCaseProps *csp, UChar32 c, const USetAdder *sa) {
    uint16_t props;

    /*
     * Hardcode the case closure of i and its relatives and ignore the
     * data file data for these characters.
     * The Turkic dotless i and dotted I with their case mapping conditions
     * and case folding option make the related characters behave specially.
     * This code matches their closure behavior to their case folding behavior.
     */
    static const UChar
        iDot[2]=        { 0x69, 0x307 };

    switch(c) {
    case 0x49:
        /* regular i and I are in one equivalence class */
        sa->add(sa->set, 0x69);
        return;
    case 0x69:
        sa->add(sa->set, 0x49);
        return;
    case 0x130:
        /* dotted I is in a class with <0069 0307> (for canonical equivalence with <0049 0307>) */
        sa->addString(sa->set, iDot, 2);
        return;
    case 0x131:
        /* dotless i is in a class by itself */
        return;
    default:
        /* otherwise use the data file data */
        break;
    }

    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)!=UCASE_NONE) {
            /* add the one simple case mapping, no matter what type it is */
            int32_t delta=UCASE_GET_DELTA(props);
            if(delta!=0) {
                sa->add(sa->set, c+delta);
            }
        }
    } else {
        /*
         * c has exceptions, so there may be multiple simple and/or
         * full case mappings. Add them all.
         */
        const uint16_t *pe0, *pe=GET_EXCEPTIONS(csp, props);
        const UChar *closure;
        uint16_t excWord=*pe++;
        int32_t index, closureLength, fullLength, length;

        pe0=pe;

        /* add all simple case mappings */
        for(index=UCASE_EXC_LOWER; index<=UCASE_EXC_TITLE; ++index) {
            if(HAS_SLOT(excWord, index)) {
                pe=pe0;
                GET_SLOT_VALUE(excWord, index, pe, c);
                sa->add(sa->set, c);
            }
        }

        /* get the closure string pointer & length */
        if(HAS_SLOT(excWord, UCASE_EXC_CLOSURE)) {
            pe=pe0;
            GET_SLOT_VALUE(excWord, UCASE_EXC_CLOSURE, pe, closureLength);
            closureLength&=UCASE_CLOSURE_MAX_LENGTH; /* higher bits are reserved */
            closure=(const UChar *)pe+1; /* behind this slot, unless there are full case mappings */
        } else {
            closureLength=0;
            closure=NULL;
        }

        /* add the full case folding */
        if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
            pe=pe0;
            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, fullLength);

            /* start of full case mapping strings */
            ++pe;

            fullLength&=0xffff; /* bits 16 and higher are reserved */

            /* skip the lowercase result string */
            pe+=fullLength&UCASE_FULL_LOWER;
            fullLength>>=4;

            /* add the full case folding string */
            length=fullLength&0xf;
            if(length!=0) {
                sa->addString(sa->set, (const UChar *)pe, length);
                pe+=length;
            }

            /* skip the uppercase and titlecase strings */
            fullLength>>=4;
            pe+=fullLength&0xf;
            fullLength>>=4;
            pe+=fullLength;

            closure=(const UChar *)pe; /* behind full case mappings */
        }

        /* add each code point in the closure string */
        for(index=0; index<closureLength;) {
            U16_NEXT_UNSAFE(closure, index, c);
            sa->add(sa->set, c);
        }
    }
}

/*
 * compare s, which has a length, with t, which has a maximum length or is NUL-terminated
 * must be length>0 and max>0 and length<=max
 */
static U_INLINE int32_t
strcmpMax(const UChar *s, int32_t length, const UChar *t, int32_t max) {
    int32_t c1, c2;

    max-=length; /* we require length<=max, so no need to decrement max in the loop */
    do {
        c1=*s++;
        c2=*t++;
        if(c2==0) {
            return 1; /* reached the end of t but not of s */
        }
        c1-=c2;
        if(c1!=0) {
            return c1; /* return difference result */
        }
    } while(--length>0);
    /* ends with length==0 */

    if(max==0 || *t==0) {
        return 0; /* equal to length of both strings */
    } else {
        return -max; /* return lengh difference */
    }
}

U_CAPI UBool U_EXPORT2
ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length, const USetAdder *sa) {
    const UChar *unfold, *p;
    int32_t i, start, limit, result, unfoldRows, unfoldRowWidth, unfoldStringWidth;

    if(csp->unfold==NULL || s==NULL) {
        return FALSE; /* no reverse case folding data, or no string */
    }
    if(length<=1) {
        /* the string is too short to find any match */
        /*
         * more precise would be:
         * if(!u_strHasMoreChar32Than(s, length, 1))
         * but this does not make much practical difference because
         * a single supplementary code point would just not be found
         */
        return FALSE;
    }

    unfold=csp->unfold;
    unfoldRows=unfold[UCASE_UNFOLD_ROWS];
    unfoldRowWidth=unfold[UCASE_UNFOLD_ROW_WIDTH];
    unfoldStringWidth=unfold[UCASE_UNFOLD_STRING_WIDTH];
    unfold+=unfoldRowWidth;

    if(length>unfoldStringWidth) {
        /* the string is too long to find any match */
        return FALSE;
    }

    /* do a binary search for the string */
    start=0;
    limit=unfoldRows;
    while(start<limit) {
        i=(start+limit)/2;
        p=unfold+(i*unfoldRowWidth);
        result=strcmpMax(s, length, p, unfoldStringWidth);

        if(result==0) {
            /* found the string: add each code point, and its case closure */
            UChar32 c;

            for(i=unfoldStringWidth; i<unfoldRowWidth && p[i]!=0;) {
                U16_NEXT_UNSAFE(p, i, c);
                sa->add(sa->set, c);
                ucase_addCaseClosure(csp, c, sa);
            }
            return TRUE;
        } else if(result<0) {
            limit=i;
        } else /* result>0 */ {
            start=i+1;
        }
    }

    return FALSE; /* string not found */
}

/** @return UCASE_NONE, UCASE_LOWER, UCASE_UPPER, UCASE_TITLE */
U_CAPI int32_t U_EXPORT2
ucase_getType(const UCaseProps *csp, UChar32 c) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    return UCASE_GET_TYPE(props);
}

/** @return same as ucase_getType(), or <0 if c is case-ignorable */
U_CAPI int32_t U_EXPORT2
ucase_getTypeOrIgnorable(const UCaseProps *csp, UChar32 c) {
    int32_t type;
    uint16_t props;
    GET_PROPS(csp, c, props);
    type=UCASE_GET_TYPE(props);
    if(type!=UCASE_NONE) {
        return type;
    } else if(
        c==0x307 ||
        (props&(UCASE_EXCEPTION|UCASE_CASE_IGNORABLE))==UCASE_CASE_IGNORABLE
    ) {
        return -1; /* case-ignorable */
    } else {
        return 0; /* c is neither cased nor case-ignorable */
    }
}

/** @return UCASE_NO_DOT, UCASE_SOFT_DOTTED, UCASE_ABOVE, UCASE_OTHER_ACCENT */
static U_INLINE int32_t
getDotType(const UCaseProps *csp, UChar32 c) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        return props&UCASE_DOT_MASK;
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
        return (*pe>>UCASE_EXC_DOT_SHIFT)&UCASE_DOT_MASK;
    }
}

U_CAPI UBool U_EXPORT2
ucase_isSoftDotted(const UCaseProps *csp, UChar32 c) {
    return (UBool)(getDotType(csp, c)==UCASE_SOFT_DOTTED);
}

U_CAPI UBool U_EXPORT2
ucase_isCaseSensitive(const UCaseProps *csp, UChar32 c) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    return (UBool)((props&UCASE_SENSITIVE)!=0);
}

/* string casing ------------------------------------------------------------ */

/*
 * These internal functions form the core of string case mappings.
 * They map single code points to result code points or strings and take
 * all necessary conditions (context, locale ID, options) into account.
 *
 * They do not iterate over the source or write to the destination
 * so that the same functions are useful for non-standard string storage,
 * such as in a Replaceable (for Transliterator) or UTF-8/32 strings etc.
 * For the same reason, the "surrounding text" context is passed in as a
 * UCaseContextIterator which does not make any assumptions about
 * the underlying storage.
 *
 * This section contains helper functions that check for conditions
 * in the input text surrounding the current code point
 * according to SpecialCasing.txt.
 *
 * Each helper function gets the index
 * - after the current code point if it looks at following text
 * - before the current code point if it looks at preceding text
 *
 * Unicode 3.2 UAX 21 "Case Mappings" defines the conditions as follows:
 *
 * Final_Sigma
 *   C is preceded by a sequence consisting of
 *     a cased letter and a case-ignorable sequence,
 *   and C is not followed by a sequence consisting of
 *     an ignorable sequence and then a cased letter.
 *
 * More_Above
 *   C is followed by one or more characters of combining class 230 (ABOVE)
 *   in the combining character sequence.
 *
 * After_Soft_Dotted
 *   The last preceding character with combining class of zero before C
 *   was Soft_Dotted,
 *   and there is no intervening combining character class 230 (ABOVE).
 *
 * Before_Dot
 *   C is followed by combining dot above (U+0307).
 *   Any sequence of characters with a combining class that is neither 0 nor 230
 *   may intervene between the current character and the combining dot above.
 *
 * The erratum from 2002-10-31 adds the condition
 *
 * After_I
 *   The last preceding base character was an uppercase I, and there is no
 *   intervening combining character class 230 (ABOVE).
 *
 *   (See Jitterbug 2344 and the comments on After_I below.)
 *
 * Helper definitions in Unicode 3.2 UAX 21:
 *
 * D1. A character C is defined to be cased
 *     if it meets any of the following criteria:
 *
 *   - The general category of C is Titlecase Letter (Lt)
 *   - In [CoreProps], C has one of the properties Uppercase, or Lowercase
 *   - Given D = NFD(C), then it is not the case that:
 *     D = UCD_lower(D) = UCD_upper(D) = UCD_title(D)
 *     (This third criterium does not add any characters to the list
 *      for Unicode 3.2. Ignored.)
 *
 * D2. A character C is defined to be case-ignorable
 *     if it meets either of the following criteria:
 *
 *   - The general category of C is
 *     Nonspacing Mark (Mn), or Enclosing Mark (Me), or Format Control (Cf), or
 *     Letter Modifier (Lm), or Symbol Modifier (Sk)
 *   - C is one of the following characters 
 *     U+0027 APOSTROPHE
 *     U+00AD SOFT HYPHEN (SHY)
 *     U+2019 RIGHT SINGLE QUOTATION MARK
 *            (the preferred character for apostrophe)
 *
 * D3. A case-ignorable sequence is a sequence of
 *     zero or more case-ignorable characters.
 */

enum {
    LOC_UNKNOWN,
    LOC_ROOT,
    LOC_TURKISH,
    LOC_LITHUANIAN
};

#define is_a(c) ((c)=='a' || (c)=='A')
#define is_e(c) ((c)=='e' || (c)=='E')
#define is_i(c) ((c)=='i' || (c)=='I')
#define is_l(c) ((c)=='l' || (c)=='L')
#define is_r(c) ((c)=='r' || (c)=='R')
#define is_t(c) ((c)=='t' || (c)=='T')
#define is_u(c) ((c)=='u' || (c)=='U')
#define is_z(c) ((c)=='z' || (c)=='Z')

/* separator? */
#define is_sep(c) ((c)=='_' || (c)=='-' || (c)==0)

/**
 * Requires non-NULL locale ID but otherwise does the equivalent of
 * checking for language codes as if uloc_getLanguage() were called:
 * Accepts both 2- and 3-letter codes and accepts case variants.
 */
U_CFUNC int32_t
ucase_getCaseLocale(const char *locale, int32_t *locCache) {
    int32_t result;
    char c;

    if(locCache!=NULL && (result=*locCache)!=LOC_UNKNOWN) {
        return result;
    }

    result=LOC_ROOT;

    /*
     * This function used to use uloc_getLanguage(), but the current code
     * removes the dependency of this low-level code on uloc implementation code
     * and is faster because not the whole locale ID has to be
     * examined and copied/transformed.
     *
     * Because this code does not want to depend on uloc, the caller must
     * pass in a non-NULL locale, i.e., may need to call uloc_getDefault().
     */
    c=*locale++;
    if(is_t(c)) {
        /* tr or tur? */
        c=*locale++;
        if(is_u(c)) {
            c=*locale++;
        }
        if(is_r(c)) {
            c=*locale;
            if(is_sep(c)) {
                result=LOC_TURKISH;
            }
        }
    } else if(is_a(c)) {
        /* az or aze? */
        c=*locale++;
        if(is_z(c)) {
            c=*locale++;
            if(is_e(c)) {
                c=*locale;
            }
            if(is_sep(c)) {
                result=LOC_TURKISH;
            }
        }
    } else if(is_l(c)) {
        /* lt or lit? */
        c=*locale++;
        if(is_i(c)) {
            c=*locale++;
        }
        if(is_t(c)) {
            c=*locale;
            if(is_sep(c)) {
                result=LOC_LITHUANIAN;
            }
        }
    }

    if(locCache!=NULL) {
        *locCache=result;
    }
    return result;
}

/* Is followed by {case-ignorable}* cased  ? (dir determines looking forward/backward) */
static UBool
isFollowedByCasedLetter(const UCaseProps *csp, UCaseContextIterator *iter, void *context, int8_t dir) {
    UChar32 c;
    uint16_t props;

    if(iter==NULL) {
        return FALSE;
    }

    for(/* dir!=0 sets direction */; (c=iter(context, dir))>=0; dir=0) {
        GET_PROPS(csp, c, props);
        if(UCASE_GET_TYPE(props)!=UCASE_NONE) {
            return TRUE; /* followed by cased letter */
        } else if(c==0x307 || (props&(UCASE_EXCEPTION|UCASE_CASE_IGNORABLE))==UCASE_CASE_IGNORABLE) {
            /* case-ignorable, continue with the loop */
        } else {
            return FALSE; /* not ignorable */
        }
    }

    return FALSE; /* not followed by cased letter */
}

/* Is preceded by Soft_Dotted character with no intervening cc=230 ? */
static UBool
isPrecededBySoftDotted(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
    UChar32 c;
    int32_t dotType;
    int8_t dir;

    if(iter==NULL) {
        return FALSE;
    }

    for(dir=-1; (c=iter(context, dir))>=0; dir=0) {
        dotType=getDotType(csp, c);
        if(dotType==UCASE_SOFT_DOTTED) {
            return TRUE; /* preceded by TYPE_i */
        } else if(dotType!=UCASE_OTHER_ACCENT) {
            return FALSE; /* preceded by different base character (not TYPE_i), or intervening cc==230 */
        }
    }

    return FALSE; /* not preceded by TYPE_i */
}

/*
 * See Jitterbug 2344:
 * The condition After_I for Turkic-lowercasing of U+0307 combining dot above
 * is checked in ICU 2.0, 2.1, 2.6 but was not in 2.2 & 2.4 because
 * we made those releases compatible with Unicode 3.2 which had not fixed
 * a related bug in SpecialCasing.txt.
 *
 * From the Jitterbug 2344 text:
 * ... this bug is listed as a Unicode erratum
 * from 2002-10-31 at http://www.unicode.org/uni2errata/UnicodeErrata.html
 * <quote>
 * There are two errors in SpecialCasing.txt.
 * 1. Missing semicolons on two lines. ... [irrelevant for ICU]
 * 2. An incorrect context definition. Correct as follows:
 * < 0307; ; 0307; 0307; tr After_Soft_Dotted; # COMBINING DOT ABOVE
 * < 0307; ; 0307; 0307; az After_Soft_Dotted; # COMBINING DOT ABOVE
 * ---
 * > 0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
 * > 0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
 * where the context After_I is defined as:
 * The last preceding base character was an uppercase I, and there is no
 * intervening combining character class 230 (ABOVE).
 * </quote>
 *
 * Note that SpecialCasing.txt even in Unicode 3.2 described the condition as:
 *
 * # When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
 * # This matches the behavior of the canonically equivalent I-dot_above
 *
 * See also the description in this place in older versions of uchar.c (revision 1.100).
 *
 * Markus W. Scherer 2003-feb-15
 */

/* Is preceded by base character 'I' with no intervening cc=230 ? */
static UBool
isPrecededBy_I(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
    UChar32 c;
    int32_t dotType;
    int8_t dir;

    if(iter==NULL) {
        return FALSE;
    }

    for(dir=-1; (c=iter(context, dir))>=0; dir=0) {
        if(c==0x49) {
            return TRUE; /* preceded by I */
        }
        dotType=getDotType(csp, c);
        if(dotType!=UCASE_OTHER_ACCENT) {
            return FALSE; /* preceded by different base character (not I), or intervening cc==230 */
        }
    }

    return FALSE; /* not preceded by I */
}

/* Is followed by one or more cc==230 ? */
static UBool
isFollowedByMoreAbove(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
    UChar32 c;
    int32_t dotType;
    int8_t dir;

    if(iter==NULL) {
        return FALSE;
    }

    for(dir=1; (c=iter(context, dir))>=0; dir=0) {
        dotType=getDotType(csp, c);
        if(dotType==UCASE_ABOVE) {
            return TRUE; /* at least one cc==230 following */
        } else if(dotType!=UCASE_OTHER_ACCENT) {
            return FALSE; /* next base character, no more cc==230 following */
        }
    }

    return FALSE; /* no more cc==230 following */
}

/* Is followed by a dot above (without cc==230 in between) ? */
static UBool
isFollowedByDotAbove(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
    UChar32 c;
    int32_t dotType;
    int8_t dir;

    if(iter==NULL) {
        return FALSE;
    }

    for(dir=1; (c=iter(context, dir))>=0; dir=0) {
        if(c==0x307) {
            return TRUE;
        }
        dotType=getDotType(csp, c);
        if(dotType!=UCASE_OTHER_ACCENT) {
            return FALSE; /* next base character or cc==230 in between */
        }
    }

    return FALSE; /* no dot above following */
}

U_CAPI int32_t U_EXPORT2
ucase_toFullLower(const UCaseProps *csp, UChar32 c,
                  UCaseContextIterator *iter, void *context,
                  const UChar **pString,
                  const char *locale, int32_t *locCache) {
    static const UChar
        iDot[2]=        { 0x69, 0x307 },
        jDot[2]=        { 0x6a, 0x307 },
        iOgonekDot[3]= { 0x12f, 0x307 },
        iDotGrave[3]=   { 0x69, 0x307, 0x300 },
        iDotAcute[3]=   { 0x69, 0x307, 0x301 },
        iDotTilde[3]=   { 0x69, 0x307, 0x303 };

    UChar32 result;
    uint16_t props;

    result=c;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
            result=c+UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
        uint16_t excWord=*pe++;
        int32_t full;

        pe2=pe;

        if(excWord&UCASE_EXC_CONDITIONAL_SPECIAL) {
            /* use hardcoded conditions and mappings */
            int32_t loc=ucase_getCaseLocale(locale, locCache);

            /*
             * Test for conditional mappings first
             *   (otherwise the unconditional default mappings are always taken),
             * then test for characters that have unconditional mappings in SpecialCasing.txt,
             * then get the UnicodeData.txt mappings.
             */
            if( loc==LOC_LITHUANIAN &&
                    /* base characters, find accents above */
                    (((c==0x49 || c==0x4a || c==0x12e) &&
                        isFollowedByMoreAbove(csp, iter, context)) ||
                    /* precomposed with accent above, no need to find one */
                    (c==0xcc || c==0xcd || c==0x128))
            ) {
                /*
                    # Lithuanian

                    # Lithuanian retains the dot in a lowercase i when followed by accents.

                    # Introduce an explicit dot above when lowercasing capital I's and J's
                    # whenever there are more accents above.
                    # (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)

                    0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I
                    004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J
                    012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK
                    00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE
                    00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE
                    0128; 0069 0307 0303; 0128; 0128; lt; # LATIN CAPITAL LETTER I WITH TILDE
                 */
                switch(c) {
                case 0x49:  /* LATIN CAPITAL LETTER I */
                    *pString=iDot;
                    return 2;
                case 0x4a:  /* LATIN CAPITAL LETTER J */
                    *pString=jDot;
                    return 2;
                case 0x12e: /* LATIN CAPITAL LETTER I WITH OGONEK */
                    *pString=iOgonekDot;
                    return 2;
                case 0xcc:  /* LATIN CAPITAL LETTER I WITH GRAVE */
                    *pString=iDotGrave;
                    return 3;
                case 0xcd:  /* LATIN CAPITAL LETTER I WITH ACUTE */
                    *pString=iDotAcute;
                    return 3;
                case 0x128: /* LATIN CAPITAL LETTER I WITH TILDE */
                    *pString=iDotTilde;
                    return 3;
                default:
                    return 0; /* will not occur */
                }
            /* # Turkish and Azeri */
            } else if(loc==LOC_TURKISH && c==0x130) {
                /*
                    # I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
                    # The following rules handle those cases.

                    0130; 0069; 0130; 0130; tr # LATIN CAPITAL LETTER I WITH DOT ABOVE
                    0130; 0069; 0130; 0130; az # LATIN CAPITAL LETTER I WITH DOT ABOVE
                 */
                return 0x69;
            } else if(loc==LOC_TURKISH && c==0x307 && isPrecededBy_I(csp, iter, context)) {
                /*
                    # When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
                    # This matches the behavior of the canonically equivalent I-dot_above

                    0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
                    0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
                 */
                return 0; /* remove the dot (continue without output) */
            } else if(loc==LOC_TURKISH && c==0x49 && !isFollowedByDotAbove(csp, iter, context)) {
                /*
                    # When lowercasing, unless an I is before a dot_above, it turns into a dotless i.

                    0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I
                    0049; 0131; 0049; 0049; az Not_Before_Dot; # LATIN CAPITAL LETTER I
                 */
                return 0x131;
            } else if(c==0x130) {
                /*
                    # Preserve canonical equivalence for I with dot. Turkic is handled below.

                    0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE
                 */
                *pString=iDot;
                return 2;
            } else if(  c==0x3a3 &&
                        !isFollowedByCasedLetter(csp, iter, context, 1) &&
                        isFollowedByCasedLetter(csp, iter, context, -1) /* -1=preceded */
            ) {
                /* greek capital sigma maps depending on surrounding cased letters (see SpecialCasing.txt) */
                /*
                    # Special case for final form of sigma

                    03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
                 */
                return 0x3c2; /* greek small final sigma */
            } else {
                /* no known conditional special case mapping, use a normal mapping */
            }
        } else if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, full);
            full&=UCASE_FULL_LOWER;
            if(full!=0) {
                /* set the output pointer to the lowercase mapping */
                *pString=pe+1;

                /* return the string length */
                return full;
            }
        }

        if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
            GET_SLOT_VALUE(excWord, UCASE_EXC_LOWER, pe2, result);
        }
    }

    return (result==c) ? ~result : result;
}

/* internal */
static int32_t
toUpperOrTitle(const UCaseProps *csp, UChar32 c,
               UCaseContextIterator *iter, void *context,
               const UChar **pString,
               const char *locale, int32_t *locCache,
               UBool upperNotTitle) {
    UChar32 result;
    uint16_t props;

    result=c;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
            result=c+UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
        uint16_t excWord=*pe++;
        int32_t full, index;

        pe2=pe;

        if(excWord&UCASE_EXC_CONDITIONAL_SPECIAL) {
            /* use hardcoded conditions and mappings */
            int32_t loc=ucase_getCaseLocale(locale, locCache);

            if(loc==LOC_TURKISH && c==0x69) {
                /*
                    # Turkish and Azeri

                    # I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
                    # The following rules handle those cases.

                    # When uppercasing, i turns into a dotted capital I

                    0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I
                    0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I
                */
                return 0x130;
            } else if(loc==LOC_LITHUANIAN && c==0x307 && isPrecededBySoftDotted(csp, iter, context)) {
                /*
                    # Lithuanian

                    # Lithuanian retains the dot in a lowercase i when followed by accents.

                    # Remove DOT ABOVE after "i" with upper or titlecase

                    0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
                 */
                return 0; /* remove the dot (continue without output) */
            } else {
                /* no known conditional special case mapping, use a normal mapping */
            }
        } else if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, full);

            /* start of full case mapping strings */
            ++pe;

            /* skip the lowercase and case-folding result strings */
            pe+=full&UCASE_FULL_LOWER;
            full>>=4;
            pe+=full&0xf;
            full>>=4;

            if(upperNotTitle) {
                full&=0xf;
            } else {
                /* skip the uppercase result string */
                pe+=full&0xf;
                full=(full>>4)&0xf;
            }

            if(full!=0) {
                /* set the output pointer to the result string */
                *pString=pe;

                /* return the string length */
                return full;
            }
        }

        if(!upperNotTitle && HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
            index=UCASE_EXC_TITLE;
        } else if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
            /* here, titlecase is same as uppercase */
            index=UCASE_EXC_UPPER;
        } else {
            return ~c;
        }
        GET_SLOT_VALUE(excWord, index, pe2, result);
    }

    return (result==c) ? ~result : result;
}

U_CAPI int32_t U_EXPORT2
ucase_toFullUpper(const UCaseProps *csp, UChar32 c,
                  UCaseContextIterator *iter, void *context,
                  const UChar **pString,
                  const char *locale, int32_t *locCache) {
    return toUpperOrTitle(csp, c, iter, context, pString, locale, locCache, TRUE);
}

U_CAPI int32_t U_EXPORT2
ucase_toFullTitle(const UCaseProps *csp, UChar32 c,
                  UCaseContextIterator *iter, void *context,
                  const UChar **pString,
                  const char *locale, int32_t *locCache) {
    return toUpperOrTitle(csp, c, iter, context, pString, locale, locCache, FALSE);
}

/* case folding ------------------------------------------------------------- */

/*
 * Case folding is similar to lowercasing.
 * The result may be a simple mapping, i.e., a single code point, or
 * a full mapping, i.e., a string.
 * If the case folding for a code point is the same as its simple (1:1) lowercase mapping,
 * then only the lowercase mapping is stored.
 *
 * Some special cases are hardcoded because their conditions cannot be
 * parsed and processed from CaseFolding.txt.
 *
 * Unicode 3.2 CaseFolding.txt specifies for its status field:

# C: common case folding, common mappings shared by both simple and full mappings.
# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
# S: simple case folding, mappings to single characters where different from F.
# T: special case for uppercase I and dotted uppercase I
#    - For non-Turkic languages, this mapping is normally not used.
#    - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
#
# Usage:
#  A. To do a simple case folding, use the mappings with status C + S.
#  B. To do a full case folding, use the mappings with status C + F.
#
#    The mappings with status T can be used or omitted depending on the desired case-folding
#    behavior. (The default option is to exclude them.)

 * Unicode 3.2 has 'T' mappings as follows:

0049; T; 0131; # LATIN CAPITAL LETTER I
0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE

 * while the default mappings for these code points are:

0049; C; 0069; # LATIN CAPITAL LETTER I
0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE

 * U+0130 has no simple case folding (simple-case-folds to itself).
 */

/* return the simple case folding mapping for c */
U_CAPI UChar32 U_EXPORT2
ucase_fold(const UCaseProps *csp, UChar32 c, uint32_t options) {
    uint16_t props;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
            c+=UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
        uint16_t excWord=*pe++;
        int32_t index;
        if(excWord&UCASE_EXC_CONDITIONAL_FOLD) {
            /* special case folding mappings, hardcoded */
            if((options&_FOLD_CASE_OPTIONS_MASK)==U_FOLD_CASE_DEFAULT) {
                /* default mappings */
                if(c==0x49) {
                    /* 0049; C; 0069; # LATIN CAPITAL LETTER I */
                    return 0x69;
                } else if(c==0x130) {
                    /* no simple case folding for U+0130 */
                    return c;
                }
            } else {
                /* Turkic mappings */
                if(c==0x49) {
                    /* 0049; T; 0131; # LATIN CAPITAL LETTER I */
                    return 0x131;
                } else if(c==0x130) {
                    /* 0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE */
                    return 0x69;
                }
            }
        }
        if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
            index=UCASE_EXC_FOLD;
        } else if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
            index=UCASE_EXC_LOWER;
        } else {
            return c;
        }
        GET_SLOT_VALUE(excWord, index, pe, c);
    }
    return c;
}

/*
 * Issue for canonical caseless match (UAX #21):
 * Turkic casefolding (using "T" mappings in CaseFolding.txt) does not preserve
 * canonical equivalence, unlike default-option casefolding.
 * For example, I-grave and I + grave fold to strings that are not canonically
 * equivalent.
 * For more details, see the comment in unorm_compare() in unorm.cpp
 * and the intermediate prototype changes for Jitterbug 2021.
 * (For example, revision 1.104 of uchar.c and 1.4 of CaseFolding.txt.)
 *
 * This did not get fixed because it appears that it is not possible to fix
 * it for uppercase and lowercase characters (I-grave vs. i-grave)
 * together in a way that they still fold to common result strings.
 */

U_CAPI int32_t U_EXPORT2
ucase_toFullFolding(const UCaseProps *csp, UChar32 c,
                    const UChar **pString,
                    uint32_t options) {
    static const UChar
        iDot[2]=        { 0x69, 0x307 };

    UChar32 result;
    uint16_t props;

    result=c;
    GET_PROPS(csp, c, props);
    if(!PROPS_HAS_EXCEPTION(props)) {
        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
            result=c+UCASE_GET_DELTA(props);
        }
    } else {
        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
        uint16_t excWord=*pe++;
        int32_t full, index;

        pe2=pe;

        if(excWord&UCASE_EXC_CONDITIONAL_FOLD) {
            /* use hardcoded conditions and mappings */
            if((options&_FOLD_CASE_OPTIONS_MASK)==U_FOLD_CASE_DEFAULT) {
                /* default mappings */
                if(c==0x49) {
                    /* 0049; C; 0069; # LATIN CAPITAL LETTER I */
                    return 0x69;
                } else if(c==0x130) {
                    /* 0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE */
                    *pString=iDot;
                    return 2;
                }
            } else {
                /* Turkic mappings */
                if(c==0x49) {
                    /* 0049; T; 0131; # LATIN CAPITAL LETTER I */
                    return 0x131;
                } else if(c==0x130) {
                    /* 0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE */
                    return 0x69;
                }
            }
        } else if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, full);

            /* start of full case mapping strings */
            ++pe;

            /* skip the lowercase result string */
            pe+=full&UCASE_FULL_LOWER;
            full=(full>>4)&0xf;

            if(full!=0) {
                /* set the output pointer to the result string */
                *pString=pe;

                /* return the string length */
                return full;
            }
        }

        if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
            index=UCASE_EXC_FOLD;
        } else if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
            index=UCASE_EXC_LOWER;
        } else {
            return ~c;
        }
        GET_SLOT_VALUE(excWord, index, pe2, result);
    }

    return (result==c) ? ~result : result;
}

/* case mapping properties API ---------------------------------------------- */

/* get the UCaseProps singleton, or else its dummy, once and for all */
static const UCaseProps *
getCaseProps() {
    /*
     * This lazy intialization with double-checked locking (without mutex protection for
     * the initial check) is transiently unsafe under certain circumstances.
     * Check the readme and use u_init() if necessary.
     */

    /* the initial check is performed by the GET_CASE_PROPS() macro */
    const UCaseProps *csp;
    UErrorCode errorCode=U_ZERO_ERROR;

    csp=ucase_getSingleton(&errorCode);
    if(U_FAILURE(errorCode)) {
        errorCode=U_ZERO_ERROR;
        csp=ucase_getDummy(&errorCode);
        if(U_FAILURE(errorCode)) {
            return NULL;
        }
    }

    return csp;
}

/*
 * In ICU 3.0, most Unicode properties were loaded from uprops.icu.
 * ICU 3.2 adds ucase.icu for case mapping properties.
 * ICU 3.4 adds ubidi.icu for bidi/shaping properties and
 * removes case/bidi/shaping properties from uprops.icu.
 *
 * Loading of uprops.icu was never mutex-protected and required u_init()
 * for thread safety.
 * In order to maintain performance for all such properties,
 * ucase.icu and ubidi.icu are loaded lazily, without mutexing.
 * u_init() will try to load them for thread safety,
 * but u_init() will not fail if they are missing.
 *
 * uchar.c maintains a tri-state flag for (not loaded/loaded/failed to load)
 * and an error code for load failure.
 * Instead, here we try to load at most once.
 * If it works, we use the resulting singleton object.
 * If it fails, then we get a dummy object, which always works unless
 * we are seriously out of memory.
 * After the first try, we have a never-changing pointer to either the
 * real singleton or the dummy.
 *
 * This method is used in Unicode properties APIs (uchar.h) that
 * do not have a service object and also do not have an error code parameter.
 * Other API implementations get the singleton themselves
 * (with mutexing), store it in the service object, and report errors.
 */
#define GET_CASE_PROPS() (gCsp!=NULL ? gCsp : getCaseProps())

/* public API (see uchar.h) */

U_CAPI UBool U_EXPORT2
u_isULowercase(UChar32 c) {
    return (UBool)(UCASE_LOWER==ucase_getType(GET_CASE_PROPS(), c));
}

U_CAPI UBool U_EXPORT2
u_isUUppercase(UChar32 c) {
    return (UBool)(UCASE_UPPER==ucase_getType(GET_CASE_PROPS(), c));
}

/* Transforms the Unicode character to its lower case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_tolower(UChar32 c) {
    return ucase_tolower(GET_CASE_PROPS(), c);
}
    
/* Transforms the Unicode character to its upper case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_toupper(UChar32 c) {
    return ucase_toupper(GET_CASE_PROPS(), c);
}

/* Transforms the Unicode character to its title case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_totitle(UChar32 c) {
    return ucase_totitle(GET_CASE_PROPS(), c);
}

/* return the simple case folding mapping for c */
U_CAPI UChar32 U_EXPORT2
u_foldCase(UChar32 c, uint32_t options) {
    return ucase_fold(GET_CASE_PROPS(), c, options);
}

U_CFUNC int32_t U_EXPORT2
ucase_hasBinaryProperty(UChar32 c, UProperty which) {
    /* case mapping properties */
    const UCaseProps *csp=GET_CASE_PROPS();
    if(csp==NULL) {
        return FALSE;
    }
    switch(which) {
    case UCHAR_LOWERCASE:
        return (UBool)(UCASE_LOWER==ucase_getType(csp, c));
    case UCHAR_UPPERCASE:
        return (UBool)(UCASE_UPPER==ucase_getType(csp, c));
    case UCHAR_SOFT_DOTTED:
        return ucase_isSoftDotted(csp, c);
    case UCHAR_CASE_SENSITIVE:
        return ucase_isCaseSensitive(csp, c);
    default:
        return FALSE;
    }
}
