/*
********************************************************************************
*   Copyright (C) 1996-2000, International Business Machines
*   Corporation and others.  All Rights Reserved.
********************************************************************************
*
* File UCHAR.C
*
* Modification History:
*
*   Date        Name        Description
*   04/02/97    aliu        Creation.
*
*   4/15/99     Madhu       Updated all the function definitions for C Implementation
*   5/20/99     Madhu		Added the function u_getVersion()
*   8/19/1999   srl         Upgraded scripts to Unicode3.0 
*   11/11/1999  weiv        added u_isalnum(), cleaned comments
*   01/11/2000  helena      Renamed u_getVersion to u_getUnicodeVersion.
*   06/20/2000  helena      OS/400 port changes; mostly typecast.
********************************************************************************************
*/

#include "unicode/utypes.h"
#include "unicode/uchar.h"
#include "unicode/udata.h"
#include "unicode/uloc.h"
#include "umutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "ustr_imp.h"

/* dynamically loaded Unicode character properties -------------------------- */

/* fallback properties for the ASCII range if the data cannot be loaded */
/* these are printed by genprops in verbose mode */
static uint32_t staticProps32Table[]={
    /* 0x00 */ 0x48f,
    /* 0x01 */ 0x48f,
    /* 0x02 */ 0x48f,
    /* 0x03 */ 0x48f,
    /* 0x04 */ 0x48f,
    /* 0x05 */ 0x48f,
    /* 0x06 */ 0x48f,
    /* 0x07 */ 0x48f,
    /* 0x08 */ 0x48f,
    /* 0x09 */ 0x20c,
    /* 0x0a */ 0x1ce,
    /* 0x0b */ 0x20c,
    /* 0x0c */ 0x24d,
    /* 0x0d */ 0x1ce,
    /* 0x0e */ 0x48f,
    /* 0x0f */ 0x48f,
    /* 0x10 */ 0x48f,
    /* 0x11 */ 0x48f,
    /* 0x12 */ 0x48f,
    /* 0x13 */ 0x48f,
    /* 0x14 */ 0x48f,
    /* 0x15 */ 0x48f,
    /* 0x16 */ 0x48f,
    /* 0x17 */ 0x48f,
    /* 0x18 */ 0x48f,
    /* 0x19 */ 0x48f,
    /* 0x1a */ 0x48f,
    /* 0x1b */ 0x48f,
    /* 0x1c */ 0x1ce,
    /* 0x1d */ 0x1ce,
    /* 0x1e */ 0x1ce,
    /* 0x1f */ 0x20c,
    /* 0x20 */ 0x24c,
    /* 0x21 */ 0x297,
    /* 0x22 */ 0x297,
    /* 0x23 */ 0x117,
    /* 0x24 */ 0x119,
    /* 0x25 */ 0x117,
    /* 0x26 */ 0x297,
    /* 0x27 */ 0x297,
    /* 0x28 */ 0x100a94,
    /* 0x29 */ 0xfff00a95,
    /* 0x2a */ 0x297,
    /* 0x2b */ 0x118,
    /* 0x2c */ 0x197,
    /* 0x2d */ 0x113,
    /* 0x2e */ 0x197,
    /* 0x2f */ 0xd7,
    /* 0x30 */ 0x89,
    /* 0x31 */ 0x100089,
    /* 0x32 */ 0x200089,
    /* 0x33 */ 0x300089,
    /* 0x34 */ 0x400089,
    /* 0x35 */ 0x500089,
    /* 0x36 */ 0x600089,
    /* 0x37 */ 0x700089,
    /* 0x38 */ 0x800089,
    /* 0x39 */ 0x900089,
    /* 0x3a */ 0x197,
    /* 0x3b */ 0x297,
    /* 0x3c */ 0x200a98,
    /* 0x3d */ 0x298,
    /* 0x3e */ 0xffe00a98,
    /* 0x3f */ 0x297,
    /* 0x40 */ 0x297,
    /* 0x41 */ 0x2000001,
    /* 0x42 */ 0x2000001,
    /* 0x43 */ 0x2000001,
    /* 0x44 */ 0x2000001,
    /* 0x45 */ 0x2000001,
    /* 0x46 */ 0x2000001,
    /* 0x47 */ 0x2000001,
    /* 0x48 */ 0x2000001,
    /* 0x49 */ 0x2000001,
    /* 0x4a */ 0x2000001,
    /* 0x4b */ 0x2000001,
    /* 0x4c */ 0x2000001,
    /* 0x4d */ 0x2000001,
    /* 0x4e */ 0x2000001,
    /* 0x4f */ 0x2000001,
    /* 0x50 */ 0x2000001,
    /* 0x51 */ 0x2000001,
    /* 0x52 */ 0x2000001,
    /* 0x53 */ 0x2000001,
    /* 0x54 */ 0x2000001,
    /* 0x55 */ 0x2000001,
    /* 0x56 */ 0x2000001,
    /* 0x57 */ 0x2000001,
    /* 0x58 */ 0x2000001,
    /* 0x59 */ 0x2000001,
    /* 0x5a */ 0x2000001,
    /* 0x5b */ 0x200a94,
    /* 0x5c */ 0x297,
    /* 0x5d */ 0xffe00a95,
    /* 0x5e */ 0x29a,
    /* 0x5f */ 0x296,
    /* 0x60 */ 0x29a,
    /* 0x61 */ 0x2000002,
    /* 0x62 */ 0x2000002,
    /* 0x63 */ 0x2000002,
    /* 0x64 */ 0x2000002,
    /* 0x65 */ 0x2000002,
    /* 0x66 */ 0x2000002,
    /* 0x67 */ 0x2000002,
    /* 0x68 */ 0x2000002,
    /* 0x69 */ 0x2000002,
    /* 0x6a */ 0x2000002,
    /* 0x6b */ 0x2000002,
    /* 0x6c */ 0x2000002,
    /* 0x6d */ 0x2000002,
    /* 0x6e */ 0x2000002,
    /* 0x6f */ 0x2000002,
    /* 0x70 */ 0x2000002,
    /* 0x71 */ 0x2000002,
    /* 0x72 */ 0x2000002,
    /* 0x73 */ 0x2000002,
    /* 0x74 */ 0x2000002,
    /* 0x75 */ 0x2000002,
    /* 0x76 */ 0x2000002,
    /* 0x77 */ 0x2000002,
    /* 0x78 */ 0x2000002,
    /* 0x79 */ 0x2000002,
    /* 0x7a */ 0x2000002,
    /* 0x7b */ 0x200a94,
    /* 0x7c */ 0x298,
    /* 0x7d */ 0xffe00a95,
    /* 0x7e */ 0x298,
    /* 0x7f */ 0x48f,
    /* 0x80 */ 0x48f,
    /* 0x81 */ 0x48f,
    /* 0x82 */ 0x48f,
    /* 0x83 */ 0x48f,
    /* 0x84 */ 0x48f,
    /* 0x85 */ 0x1ce,
    /* 0x86 */ 0x48f,
    /* 0x87 */ 0x48f,
    /* 0x88 */ 0x48f,
    /* 0x89 */ 0x48f,
    /* 0x8a */ 0x48f,
    /* 0x8b */ 0x48f,
    /* 0x8c */ 0x48f,
    /* 0x8d */ 0x48f,
    /* 0x8e */ 0x48f,
    /* 0x8f */ 0x48f,
    /* 0x90 */ 0x48f,
    /* 0x91 */ 0x48f,
    /* 0x92 */ 0x48f,
    /* 0x93 */ 0x48f,
    /* 0x94 */ 0x48f,
    /* 0x95 */ 0x48f,
    /* 0x96 */ 0x48f,
    /* 0x97 */ 0x48f,
    /* 0x98 */ 0x48f,
    /* 0x99 */ 0x48f,
    /* 0x9a */ 0x48f,
    /* 0x9b */ 0x48f,
    /* 0x9c */ 0x48f,
    /* 0x9d */ 0x48f,
    /* 0x9e */ 0x48f,
    /* 0x9f */ 0x48f
};

/*
 * loaded uprops.dat -
 * for a description of the file format, see icu/source/tools/genprops/store.c
 */
#define DATA_NAME "uprops"
#define DATA_TYPE "dat"

static UDataMemory *propsData=NULL;

static uint8_t formatVersion[4]={ 0, 0, 0, 0 };
static UVersionInfo dataVersion={ 3, 0, 0, 0 };

static const uint16_t *propsTable=NULL;
#define props32Table ((uint32_t *)propsTable)

static const UChar *ucharsTable=NULL;

static int8_t havePropsData=0;

/* index values loaded from uprops.dat */
static uint16_t indexes[8];

enum {
    INDEX_STAGE_2_BITS,
    INDEX_STAGE_3_BITS,
    INDEX_EXCEPTIONS,
    INDEX_STAGE_3_INDEX,
    INDEX_PROPS,
    INDEX_UCHARS
};

/* access values calculated from indexes */
static uint16_t stage23Bits, stage2Mask, stage3Mask;

static UBool
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]==0x55 &&   /* dataFormat="UPro" */
        pInfo->dataFormat[1]==0x50 &&
        pInfo->dataFormat[2]==0x72 &&
        pInfo->dataFormat[3]==0x6f &&
        pInfo->formatVersion[0]==1
    ) {
        uprv_memcpy(formatVersion, pInfo->formatVersion, 4);
        uprv_memcpy(dataVersion, pInfo->dataVersion, 4);
        return TRUE;
    } else {
        return FALSE;
    }
}

static int8_t
loadPropsData() {
    /* load Unicode character properties data from file if necessary */
    if(havePropsData==0) {
        UErrorCode errorCode=U_ZERO_ERROR;
        UDataMemory *data;
        const uint16_t *p=NULL;

        /* open the data outside the mutex block */
        data=udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &errorCode);
        if(U_FAILURE(errorCode)) {
            return havePropsData=-1;
        }

        p=(const uint16_t *)udata_getMemory(data);

        /* in the mutex block, set the data for this process */
        umtx_lock(NULL);
        if(propsData==NULL) {
            propsData=data;
            data=NULL;
            propsTable=p;
            p=NULL;
        }
        umtx_unlock(NULL);

        /* initialize some variables */
        uprv_memcpy(indexes, propsTable, 16);
        stage23Bits=(uint16_t)(indexes[INDEX_STAGE_2_BITS]+indexes[INDEX_STAGE_3_BITS]);
        stage2Mask=(uint16_t)((1<<indexes[INDEX_STAGE_2_BITS])-1);
        stage3Mask=(uint16_t)((1<<indexes[INDEX_STAGE_3_BITS])-1);
        ucharsTable=(const UChar *)(props32Table+indexes[INDEX_UCHARS]);
        havePropsData=1;

        /* if a different thread set it first, then close the extra data */
        if(data!=NULL) {
            udata_close(data); /* NULL if it was set correctly */
        }
    }

    return havePropsData;
}

/* constants and macros for access to the data */
enum {
    EXC_UPPERCASE,
    EXC_LOWERCASE,
    EXC_TITLECASE,
    EXC_DIGIT_VALUE,
    EXC_NUMERIC_VALUE,
    EXC_DENOMINATOR_VALUE,
    EXC_MIRROR_MAPPING,
    EXC_SPECIAL_CASING,
    EXC_CASE_FOLDING
};

enum {
    EXCEPTION_SHIFT=5,
    BIDI_SHIFT,
    MIRROR_SHIFT=BIDI_SHIFT+5,
    VALUE_SHIFT=20,

    VALUE_BITS=32-VALUE_SHIFT
};

/* getting a uint32_t properties word from the data */
#define HAVE_DATA (havePropsData>0 || (havePropsData==0 && loadPropsData()>0))
#define VALIDATE(c) (((uint32_t)(c))<=0x10ffff && HAVE_DATA)
#define GET_PROPS_UNSAFE(c) \
    props32Table[ \
        propsTable[ \
            propsTable[ \
                propsTable[8+((c)>>stage23Bits)]+ \
                ((c)>>indexes[INDEX_STAGE_3_BITS]&stage2Mask)]+ \
            ((c)&stage3Mask) \
        ] \
    ]
#define GET_PROPS(c) \
    (((uint32_t)(c))<=0x10ffff ? \
        HAVE_DATA ? \
            GET_PROPS_UNSAFE(c) \
        : (c)<=0x9f ? \
            staticProps32Table[c] \
        : 0 \
    : 0)
#define PROPS_VALUE_IS_EXCEPTION(props) ((props)&(1UL<<EXCEPTION_SHIFT))
#define GET_CATEGORY(props) ((props)&0x1f)
#define GET_UNSIGNED_VALUE(props) ((props)>>VALUE_SHIFT)
#define GET_SIGNED_VALUE(props) ((int32_t)(props)>>VALUE_SHIFT)
#define GET_EXCEPTIONS(props) (props32Table+indexes[INDEX_EXCEPTIONS]+GET_UNSIGNED_VALUE(props))

/* finding an exception value */
#define HAVE_EXCEPTION_VALUE(flags, index) ((flags)&(1UL<<(index)))

/* number of bits in an 8-bit integer value */
#define EXC_GROUP 8
static 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 ADD_EXCEPTION_OFFSET(flags, index, offset) { \
    if((index)>=EXC_GROUP) { \
        (offset)+=flagsOffset[(flags)&((1<<EXC_GROUP)-1)]; \
        (flags)>>=EXC_GROUP; \
        (index)-=EXC_GROUP; \
    } \
    (offset)+=flagsOffset[(flags)&((1<<(index))-1)]; \
}

U_CFUNC UBool
uprv_haveProperties() {
    return HAVE_DATA;
}

/* API functions ------------------------------------------------------------ */

/* Gets the Unicode character's general category.*/
U_CAPI int8_t U_EXPORT2
u_charType(UChar32 c) {
    return (int8_t)GET_CATEGORY(GET_PROPS(c));
}

/* Checks if ch is a lower case letter.*/
U_CAPI UBool U_EXPORT2
u_islower(UChar32 c) {
    return (UBool)(GET_CATEGORY(GET_PROPS(c))==U_LOWERCASE_LETTER);
}

/* Checks if ch is an upper case letter.*/
U_CAPI UBool U_EXPORT2
u_isupper(UChar32 c) {
    return (UBool)(GET_CATEGORY(GET_PROPS(c))==U_UPPERCASE_LETTER);
}

/* Checks if ch is a title case letter; usually upper case letters.*/
U_CAPI UBool U_EXPORT2
u_istitle(UChar32 c) {
    return (UBool)(GET_CATEGORY(GET_PROPS(c))==U_TITLECASE_LETTER);
}

/* Checks if ch is a decimal digit. */
U_CAPI UBool U_EXPORT2
u_isdigit(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_DECIMAL_DIGIT_NUMBER|1UL<<U_OTHER_NUMBER|1UL<<U_LETTER_NUMBER)
           )!=0);
}

/* Checks if the Unicode character is a letter.*/
U_CAPI UBool U_EXPORT2
u_isalpha(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER)
           )!=0);
}

/* Checks if ch is a letter or a decimal digit */
U_CAPI UBool U_EXPORT2
u_isalnum(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_DECIMAL_DIGIT_NUMBER|1UL<<U_OTHER_NUMBER|1UL<<U_LETTER_NUMBER|
             1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER)
           )!=0);
}

/* Checks if ch is a unicode character with assigned character type.*/
U_CAPI UBool U_EXPORT2
u_isdefined(UChar32 c) {
    return (UBool)(GET_PROPS(c)!=0);
}

/* Checks if the Unicode character is a base form character that can take a diacritic.*/
U_CAPI UBool U_EXPORT2
u_isbase(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_DECIMAL_DIGIT_NUMBER|1UL<<U_OTHER_NUMBER|1UL<<U_LETTER_NUMBER|
             1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER|
             1UL<<U_NON_SPACING_MARK|1UL<<U_ENCLOSING_MARK|1UL<<U_COMBINING_SPACING_MARK)
           )!=0);
}

/* Checks if the Unicode character is a control character.*/
U_CAPI UBool U_EXPORT2
u_iscntrl(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_CONTROL_CHAR|1UL<<U_FORMAT_CHAR|1UL<<U_LINE_SEPARATOR|1UL<<U_PARAGRAPH_SEPARATOR)
           )!=0);
}

/* Checks if the Unicode character is a space character.*/
UBool
u_isspace(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_SPACE_SEPARATOR|1UL<<U_LINE_SEPARATOR|1UL<<U_PARAGRAPH_SEPARATOR)
           )!=0);
}

/* Checks if the Unicode character is a whitespace character.*/
U_CAPI UBool U_EXPORT2
u_isWhitespace(UChar32 c) {
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_SPACE_SEPARATOR|1UL<<U_LINE_SEPARATOR|1UL<<U_PARAGRAPH_SEPARATOR)
           )!=0 &&
           c!=0xa0 && c!=0x202f && c!=0xfeff); /* exclude no-break spaces */
}

/* Checks if the Unicode character is printable.*/
U_CAPI UBool U_EXPORT2
u_isprint(UChar32 c) {    
    return (UBool)(
            ((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_DECIMAL_DIGIT_NUMBER|1UL<<U_OTHER_NUMBER|1UL<<U_LETTER_NUMBER|
             1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER|
             1UL<<U_NON_SPACING_MARK|1UL<<U_ENCLOSING_MARK|1UL<<U_COMBINING_SPACING_MARK|
             1UL<<U_SPACE_SEPARATOR|1UL<<U_LINE_SEPARATOR|1UL<<U_PARAGRAPH_SEPARATOR|
             1UL<<U_DASH_PUNCTUATION|1UL<<U_START_PUNCTUATION|1UL<<U_END_PUNCTUATION|1UL<<U_CONNECTOR_PUNCTUATION|1UL<<U_OTHER_PUNCTUATION|
             1UL<<U_MATH_SYMBOL|1UL<<U_CURRENCY_SYMBOL|1UL<<U_MODIFIER_SYMBOL|1UL<<U_OTHER_SYMBOL)
           )!=0);
}

/* Checks if the Unicode character can start a Unicode identifier.*/
U_CAPI UBool U_EXPORT2
u_isIDStart(UChar32 c) {
    /* same as u_isalpha() */
    return (UBool)(((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER)
           )!=0);
}

/* Checks if the Unicode character can be a Unicode identifier part other than starting the
 identifier.*/
U_CAPI UBool U_EXPORT2
u_isIDPart(UChar32 c) {
    return (UBool)(
           ((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_DECIMAL_DIGIT_NUMBER|1UL<<U_LETTER_NUMBER|
             1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER|
             1UL<<U_CONNECTOR_PUNCTUATION|1UL<<U_COMBINING_SPACING_MARK|1UL<<U_NON_SPACING_MARK)
           )!=0 ||
           u_isIDIgnorable(c));
}

/*Checks if the Unicode character can be ignorable in a Java or Unicode identifier.*/
U_CAPI UBool U_EXPORT2
u_isIDIgnorable(UChar32 c) {
    return (UBool)((uint32_t)c<=8 ||
           (uint32_t)(c-0xe)<=(0x1b-0xe) ||
           (uint32_t)(c-0x7f)<=(0x9f-0x7f) ||
           (uint32_t)(c-0x200a)<=(0x200f-0x200a) ||
           (uint32_t)(c-0x206a)<=(0x206f-0x206a) ||
           c==0xfeff);
}

/*Checks if the Unicode character can start a Java identifier.*/
U_CAPI UBool U_EXPORT2
u_isJavaIDStart(UChar32 c) {
    return (UBool)(
           ((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER|
             1UL<<U_CURRENCY_SYMBOL|1UL<<U_CONNECTOR_PUNCTUATION)
           )!=0);
}

/*Checks if the Unicode character can be a Java identifier part other than starting the
 * identifier.
 */
U_CAPI UBool U_EXPORT2
u_isJavaIDPart(UChar32 c) {
    return (UBool)(
           ((1UL<<GET_CATEGORY(GET_PROPS(c)))&
            (1UL<<U_DECIMAL_DIGIT_NUMBER|1UL<<U_LETTER_NUMBER|
             1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER|
             1UL<<U_CURRENCY_SYMBOL|1UL<<U_CONNECTOR_PUNCTUATION|
             1UL<<U_COMBINING_SPACING_MARK|1UL<<U_NON_SPACING_MARK)
           )!=0 ||
           u_isIDIgnorable(c));
}

/* Transforms the Unicode character to its lower case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_tolower(UChar32 c) {
    uint32_t props=GET_PROPS(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if((1UL<<GET_CATEGORY(props))&(1UL<<U_UPPERCASE_LETTER|1UL<<U_TITLECASE_LETTER)) {
            return c+GET_SIGNED_VALUE(props);
        }
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_LOWERCASE)) {
            int i=EXC_LOWERCASE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            return (UChar32)*pe;
        }
    }
    return c; /* no mapping - return c itself */
}
    
/* Transforms the Unicode character to its upper case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_toupper(UChar32 c) {
    uint32_t props=GET_PROPS(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if(GET_CATEGORY(props)==U_LOWERCASE_LETTER) {
            return c-GET_SIGNED_VALUE(props);
        }
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_UPPERCASE)) {
            int i=EXC_UPPERCASE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            return (UChar32)*pe;
        }
    }
    return c; /* no mapping - return c itself */
}

/* Transforms the Unicode character to its title case equivalent.*/
U_CAPI UChar32 U_EXPORT2
u_totitle(UChar32 c) {
    uint32_t props=GET_PROPS(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if(GET_CATEGORY(props)==U_LOWERCASE_LETTER) {
            /* here, titlecase is same as uppercase */
            return c-GET_SIGNED_VALUE(props);
        }
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_TITLECASE)) {
            int i=EXC_TITLECASE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            return (UChar32)*pe;
        } else if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_UPPERCASE)) {
            /* here, titlecase is same as uppercase */
            int i=EXC_UPPERCASE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            return (UChar32)*pe;
        }
    }
    return c; /* no mapping - return c itself */
}

U_CAPI int32_t U_EXPORT2
u_charDigitValue(UChar32 c) {
    uint32_t props=GET_PROPS(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if(GET_CATEGORY(props)==U_DECIMAL_DIGIT_NUMBER) {
            return GET_SIGNED_VALUE(props);
        }
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_DIGIT_VALUE)) {
            int32_t value;
            int i=EXC_DIGIT_VALUE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            value=(int32_t)(int16_t)*pe; /* the digit value is in bits 15..0 */
            if(value!=-1) {
                return value;
            }
        }
    }

    /* if there is no value in the properties table, then check for some special characters */
    switch(c) {
    case 0x3007:    return 0; /* Han Zero*/
    case 0x4e00:    return 1; /* Han One*/
    case 0x4e8c:    return 2; /* Han Two*/
    case 0x4e09:    return 3; /* Han Three*/
    case 0x56d8:    return 4; /* Han Four*/
    case 0x4e94:    return 5; /* Han Five*/
    case 0x516d:    return 6; /* Han Six*/
    case 0x4e03:    return 7; /* Han Seven*/
    case 0x516b:    return 8; /* Han Eight*/
    case 0x4e5d:    return 9; /* Han Nine*/
    default:        return -1; /* no value */
    }
}

/* Gets the character's linguistic directionality.*/
U_CAPI UCharDirection U_EXPORT2
u_charDirection(UChar32 c) {   
    uint32_t props=GET_PROPS(c);
    if(props!=0) {
        return (UCharDirection)((props>>BIDI_SHIFT)&0x1f);
    } else {
        return U_BOUNDARY_NEUTRAL;
    }
}

U_CAPI UBool U_EXPORT2
u_isMirrored(UChar32 c) {
    return (UBool)(GET_PROPS(c)&(1UL<<MIRROR_SHIFT) ? TRUE : FALSE);
}

U_CAPI UChar32 U_EXPORT2
u_charMirror(UChar32 c) {
    uint32_t props=GET_PROPS(c);
    if((props&(1UL<<MIRROR_SHIFT))==0) {
        /* not mirrored - the value is not a mirror offset */
        return c;
    } else if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        return c+GET_SIGNED_VALUE(props);
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_MIRROR_MAPPING)) {
            int i=EXC_MIRROR_MAPPING;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            return (UChar32)*pe;
        } else {
            return c;
        }
    }
}

U_CFUNC uint8_t
u_internalGetCombiningClass(UChar32 c) {
    uint32_t props=GET_PROPS_UNSAFE(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if(GET_CATEGORY(props)==U_NON_SPACING_MARK) {
            return (uint8_t)GET_UNSIGNED_VALUE(props);
        } else {
            return 0;
        }
    } else {
        /* the combining class is in bits 23..16 of the first exception value */
        return (uint8_t)(*GET_EXCEPTIONS(props)>>16);
    }
}

U_CAPI uint8_t U_EXPORT2
u_getCombiningClass(UChar32 c) {
    uint32_t props=GET_PROPS(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if(GET_CATEGORY(props)==U_NON_SPACING_MARK) {
            return (uint8_t)GET_UNSIGNED_VALUE(props);
        } else {
            return 0;
        }
    } else {
        /* the combining class is in bits 23..16 of the first exception value */
        return (uint8_t)(*GET_EXCEPTIONS(props)>>16);
    }
}

/* static data tables ------------------------------------------------------- */

struct BlockScriptMap {
    UChar        fFirstCode;
    UChar        fLastCode;
};
typedef struct BlockScriptMap BlockScriptMap;

static const BlockScriptMap fScriptIndex[] = {
/* Generated from the Unicode-3.0-beta blocks.txt file */
  { 0x0000, 0x007F }, /*BASIC_LATIN */
  { 0x0080, 0x00FF }, /*LATIN_1_SUPPLEMENT */
  { 0x0100, 0x017F }, /*LATIN_EXTENDED_A */
  { 0x0180, 0x024F }, /*LATIN_EXTENDED_B */
  { 0x0250, 0x02AF }, /*IPA_EXTENSIONS */
  { 0x02B0, 0x02FF }, /*SPACING_MODIFIER_LETTERS */
  { 0x0300, 0x036F }, /*COMBINING_DIACRITICAL_MARKS */
  { 0x0370, 0x03FF }, /*GREEK */
  { 0x0400, 0x04FF }, /*CYRILLIC */
  { 0x0530, 0x058F }, /*ARMENIAN */
  { 0x0590, 0x05FF }, /*HEBREW */
  { 0x0600, 0x06FF }, /*ARABIC */
  { 0x0700, 0x074F }, /*SYRIAC */
  { 0x0780, 0x07BF }, /*THAANA */
  { 0x0900, 0x097F }, /*DEVANAGARI */
  { 0x0980, 0x09FF }, /*BENGALI */
  { 0x0A00, 0x0A7F }, /*GURMUKHI */
  { 0x0A80, 0x0AFF }, /*GUJARATI */
  { 0x0B00, 0x0B7F }, /*ORIYA */
  { 0x0B80, 0x0BFF }, /*TAMIL */
  { 0x0C00, 0x0C7F }, /*TELUGU */
  { 0x0C80, 0x0CFF }, /*KANNADA */
  { 0x0D00, 0x0D7F }, /*MALAYALAM */
  { 0x0D80, 0x0DFF }, /*SINHALA */
  { 0x0E00, 0x0E7F }, /*THAI */
  { 0x0E80, 0x0EFF }, /*LAO */
  { 0x0F00, 0x0FFF }, /*TIBETAN */
  { 0x1000, 0x109F }, /*MYANMAR */
  { 0x10A0, 0x10FF }, /*GEORGIAN */
  { 0x1100, 0x11FF }, /*HANGUL_JAMO */
  { 0x1200, 0x137F }, /*ETHIOPIC */
  { 0x13A0, 0x13FF }, /*CHEROKEE */
  { 0x1400, 0x167F }, /*UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS */
  { 0x1680, 0x169F }, /*OGHAM */
  { 0x16A0, 0x16FF }, /*RUNIC */
  { 0x1780, 0x17FF }, /*KHMER */
  { 0x1800, 0x18AF }, /*MONGOLIAN */
  { 0x1E00, 0x1EFF }, /*LATIN_EXTENDED_ADDITIONAL */
  { 0x1F00, 0x1FFF }, /*GREEK_EXTENDED */
  { 0x2000, 0x206F }, /*GENERAL_PUNCTUATION */
  { 0x2070, 0x209F }, /*SUPERSCRIPTS_AND_SUBSCRIPTS */
  { 0x20A0, 0x20CF }, /*CURRENCY_SYMBOLS */
  { 0x20D0, 0x20FF }, /*COMBINING_MARKS_FOR_SYMBOLS */
  { 0x2100, 0x214F }, /*LETTERLIKE_SYMBOLS */
  { 0x2150, 0x218F }, /*NUMBER_FORMS */
  { 0x2190, 0x21FF }, /*ARROWS */
  { 0x2200, 0x22FF }, /*MATHEMATICAL_OPERATORS */
  { 0x2300, 0x23FF }, /*MISCELLANEOUS_TECHNICAL */
  { 0x2400, 0x243F }, /*CONTROL_PICTURES */
  { 0x2440, 0x245F }, /*OPTICAL_CHARACTER_RECOGNITION */
  { 0x2460, 0x24FF }, /*ENCLOSED_ALPHANUMERICS */
  { 0x2500, 0x257F }, /*BOX_DRAWING */
  { 0x2580, 0x259F }, /*BLOCK_ELEMENTS */
  { 0x25A0, 0x25FF }, /*GEOMETRIC_SHAPES */
  { 0x2600, 0x26FF }, /*MISCELLANEOUS_SYMBOLS */
  { 0x2700, 0x27BF }, /*DINGBATS */
  { 0x2800, 0x28FF }, /*BRAILLE_PATTERNS */
  { 0x2E80, 0x2EFF }, /*CJK_RADICALS_SUPPLEMENT */
  { 0x2F00, 0x2FDF }, /*KANGXI_RADICALS */
  { 0x2FF0, 0x2FFF }, /*IDEOGRAPHIC_DESCRIPTION_CHARACTERS */
  { 0x3000, 0x303F }, /*CJK_SYMBOLS_AND_PUNCTUATION */
  { 0x3040, 0x309F }, /*HIRAGANA */
  { 0x30A0, 0x30FF }, /*KATAKANA */
  { 0x3100, 0x312F }, /*BOPOMOFO */
  { 0x3130, 0x318F }, /*HANGUL_COMPATIBILITY_JAMO */
  { 0x3190, 0x319F }, /*KANBUN */
  { 0x31A0, 0x31BF }, /*BOPOMOFO_EXTENDED */
  { 0x3200, 0x32FF }, /*ENCLOSED_CJK_LETTERS_AND_MONTHS */
  { 0x3300, 0x33FF }, /*CJK_COMPATIBILITY */
  { 0x3400, 0x4DB5 }, /*CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A */
  { 0x4E00, 0x9FFF }, /*CJK_UNIFIED_IDEOGRAPHS */
  { 0xA000, 0xA48F }, /*YI_SYLLABLES */
  { 0xA490, 0xA4CF }, /*YI_RADICALS */
  { 0xAC00, 0xD7A3 }, /*HANGUL_SYLLABLES */
  { 0xD800, 0xDB7F }, /*HIGH_SURROGATES */
  { 0xDB80, 0xDBFF }, /*HIGH_PRIVATE_USE_SURROGATES */
  { 0xDC00, 0xDFFF }, /*LOW_SURROGATES */
  { 0xE000, 0xF8FF }, /*PRIVATE_USE */
  { 0xF900, 0xFAFF }, /*CJK_COMPATIBILITY_IDEOGRAPHS */
  { 0xFB00, 0xFB4F }, /*ALPHABETIC_PRESENTATION_FORMS */
  { 0xFB50, 0xFDFF }, /*ARABIC_PRESENTATION_FORMS_A */
  { 0xFE20, 0xFE2F }, /*COMBINING_HALF_MARKS */
  { 0xFE30, 0xFE4F }, /*CJK_COMPATIBILITY_FORMS */
  { 0xFE50, 0xFE6F }, /*SMALL_FORM_VARIANTS */
  { 0xFE70, 0xFEFE }, /*ARABIC_PRESENTATION_FORMS_B */
  { 0xFEFF, 0xFEFF }, /*U_SPECIALS */
  { 0xFF00, 0xFFEF }, /*HALFWIDTH_AND_FULLWIDTH_FORMS */
  { 0xFFF0, 0xFFFD }, /*SPECIALS_2 = "U_CHAR_SCRIPT_COUNT" (really specials) */
  { 0xFFFF, 0xFFFF } /* END */
};

const UChar cellWidthRanges[] =
    {
        0x0000, /* general scripts area*/
        0x1100, /* combining Hangul choseong*/
        0x1160, /* combining Hangul jungseong and jongseong*/
        0x1e00, /* Latin Extended Additional, Greek Extended*/
        0x2000, /* symbols and punctuation*/
        0x3000, /* CJK phonetics & symbols, CJK ideographs, Hangul syllables*/
        0xd800, /* surrogates, private use*/
        0xf900, /* CJK compatibility ideographs*/
        0xfb00, /* alphabetic presentation forms, Arabic presentations forms A, combining half marks*/
        0xfe30, /* CJK compatibility forms, small form variants*/
        0xfe70, /* Arabic presentation forms B*/
        0xff00, /* fullwidth ASCII*/
        0xff60, /* halfwidth, CJK punctuation, Katakana, Hangul Jamo*/
        0xffe0, /* fullwidth punctuation and currency signs*/
        0xffe8, /* halfwidth forms, arrows, and shapes*/
        0xfff0  /* specials*/
    };

const UChar cellWidthValues[] =
    {
        U_HALF_WIDTH,    /* general scripts area*/
        U_FULL_WIDTH,    /* combining Hangul choseong*/
        U_ZERO_WIDTH,    /* combining Hangul jungseong and jongseong*/
        U_HALF_WIDTH,    /* Latin extended aAdditional, Greek extended*/
        U_NEUTRAL_WIDTH, /* symbols and punctuation*/
        U_FULL_WIDTH,    /* CJK phonetics & symbols, CJK ideographs, Hangul syllables*/
        U_NEUTRAL_WIDTH, /* surrogates, private use*/
        U_FULL_WIDTH,    /* CJK compatibility ideographs*/
        U_HALF_WIDTH,    /* alphabetic presentation forms, Arabic presentations forms A, combining half marks*/
        U_FULL_WIDTH,    /* CJK compatibility forms, small form variants*/
        U_HALF_WIDTH,    /* Arabic presentation forms B*/
        U_FULL_WIDTH,    /* fullwidth ASCII*/
        U_HALF_WIDTH,    /* halfwidth CJK punctuation, Katakana, Hangul Jamo*/
        U_FULL_WIDTH,    /* fullwidth punctuation and currency signs*/
        U_HALF_WIDTH,    /* halfwidth forms, arrows, and shapes*/
        U_ZERO_WIDTH     /* specials*/
    };

const int16_t numCellWidthValues = 16;

/* Get the script associated with the character*/
UCharScript
u_charScript(UChar32 ch)
{
    int32_t i, j;
    UCharScript returnValue = U_NO_SCRIPT;

    /* surrogate support is still incomplete */
    if((uint32_t)ch>0xffff) {
        return U_NO_SCRIPT;
    }

    /* ### a binary search would be faster; maybe this should go into a data file, too */
    i = -1;
    for( j = 0; i == -1 && fScriptIndex[j].fFirstCode != 0xFFFF; ++j )
        if( fScriptIndex[j].fFirstCode <= ch && ch <= fScriptIndex[j].fLastCode ) {
            i = j;
	    if(j == U_CHAR_SCRIPT_COUNT) /* "U_SPECIALS 2" */
	      i = U_SPECIALS;
        }
    if(i >= U_CHAR_SCRIPT_COUNT) {
        returnValue = U_NO_SCRIPT;
    }
    else if( i != -1 ) {
        returnValue = (UCharScript)i;
    } 

    return returnValue;
}

/* Gets table cell width of the Unicode character.*/
uint16_t
u_charCellWidth(UChar32 ch)
{
    int16_t i;
    int32_t type = u_charType(ch);

    /* surrogate support is still incomplete */
    if((uint32_t)ch>0xffff) {
        return U_ZERO_WIDTH;
    }

    /* these Unicode character types are scattered throughout the Unicode range, so
     special-case for them*/
    switch (type) {
        case U_UNASSIGNED:
        case U_NON_SPACING_MARK:
        case U_ENCLOSING_MARK:
        case U_LINE_SEPARATOR:
        case U_PARAGRAPH_SEPARATOR:
        case U_CONTROL_CHAR:
        case U_FORMAT_CHAR:
            return U_ZERO_WIDTH;

        default:
            /* for all remaining characters, find out which Unicode range they belong to using
               the table above, and then look up the appropriate return value in that table*/
            for (i = 0; i < numCellWidthValues; ++i)
                if (ch < cellWidthRanges[i])
                    break;
            --i;
            return cellWidthValues[i];
    }
}

void u_getUnicodeVersion(UVersionInfo versionArray) {
    if(versionArray!=NULL) {
        uprv_memcpy(versionArray, dataVersion, U_MAX_VERSION_LENGTH);
    }
}

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

/*
 * These internal string case mapping functions are here instead of ustring.c
 * because we need efficient access to the character properties.
 */

enum {
    LOC_ROOT,
    LOC_TURKISH,
    LOC_LITHUANIAN
};

static int32_t
getCaseLocale(const char *locale) {
    if(locale==NULL) {
        locale=uloc_getDefault();
        if(locale==NULL) {
            return LOC_ROOT;
        }
    }
    if( ((locale[0]=='t' && locale[1]=='r') ||
         (locale[0]=='a' && locale[1]=='z')) &&
        (locale[2]=='_' || locale[2]==0)
    ) {
        return LOC_TURKISH;
    } else if(locale[0]=='l' && locale[1]=='t' && (locale[2]=='_' || locale[2]==0)) {
        return LOC_LITHUANIAN;
    } else {
        return LOC_ROOT;
    }
}

U_CFUNC int32_t
u_internalStrToLower(UChar *dest, int32_t destCapacity,
                     const UChar *src, int32_t srcLength,
                     const char *locale,
                     GrowBuffer *growBuffer, void *context,
                     UErrorCode *pErrorCode) {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    uint32_t *pe;
    const UChar *u;
    uint32_t props, firstExceptionValue;
    int32_t srcIndex, destIndex, i, loc;
    UChar32 c;
    UBool canGrow;

    /* do not attempt to grow if there is no growBuffer function or if it has failed before */
    canGrow= growBuffer!=NULL;

    /* test early, once, if there is a data file */
    if(!HAVE_DATA) {
        /*
         * If we do not have real character properties data,
         * then we only do a fixed-length ASCII case mapping.
         */
        if(srcLength<=destCapacity ||
            /* attempt to grow the buffer */
            (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, srcLength, 0)))
        ) {
            destIndex=srcLength;
            *pErrorCode=U_USING_DEFAULT_ERROR;
        } else {
            destIndex=destCapacity;
            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
        }

        for(srcIndex=0; srcIndex<destIndex; ++srcIndex) {
            c=src[srcIndex];
            if((uint32_t)(c-0x41)<26) {
                dest[srcIndex]=(UChar)(c+0x20);
            } else {
                dest[srcIndex]=(UChar)c;
            }
        }

        return srcLength;
    }

    /* set up local variables */
    loc=getCaseLocale(locale);

    /* case mapping loop */
    srcIndex=destIndex=0;
    while(srcIndex<srcLength) {
        UTF_NEXT_CHAR(src, srcIndex, srcLength, c);
        props=GET_PROPS_UNSAFE(c);
        if(!PROPS_VALUE_IS_EXCEPTION(props)) {
            if((1UL<<GET_CATEGORY(props))&(1UL<<U_UPPERCASE_LETTER|1UL<<U_TITLECASE_LETTER)) {
                c+=GET_SIGNED_VALUE(props);
            }
        } else {
            pe=GET_EXCEPTIONS(props);
            firstExceptionValue=*pe;
            if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_SPECIAL_CASING)) {
                i=EXC_SPECIAL_CASING;
                ++pe;
                ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
                props=*pe;
                /* fill u and i with the case mapping result string */
                if(props&0x80000000) {
                    /* use hardcoded conditions and mappings */
                    u=buffer;
                    if(c==0x49) {
                        if(loc==LOC_TURKISH) {
                            /* turkish: I maps to dotless i */
                            buffer[0]=0x131;
                        } else {
                            /* other languages: I maps to i */
                            buffer[0]=0x69;
                        }
                        i=1;
                    } else if(c==0x3a3) {
                        /* greek capital sigma maps depending on whether the following character is a letter (L*) */
                        /* get the following character and check its general category */
                        if(srcIndex<srcLength) {
                            i=srcIndex;
                            UTF_NEXT_CHAR(src, i, srcLength, c);
                            if( /* is letter: is L* (Lu, Ll, Lt, Lm, or Lo) */
                                (1UL<<GET_CATEGORY(GET_PROPS_UNSAFE(c)))&
                                (1UL<<U_UPPERCASE_LETTER|1UL<<U_LOWERCASE_LETTER|1UL<<U_TITLECASE_LETTER|1UL<<U_MODIFIER_LETTER|1UL<<U_OTHER_LETTER)
                            ) {
                                /* NONFINAL: the following is a letter */
                                buffer[0]=0x3c3; /* greek small sigma */
                            } else {
                                /* FINAL: the following is not a letter */
                                buffer[0]=0x3c2; /* greek small final sigma */
                            }
                        } else {
                            /* FINAL: this is the last character in the string */
                            buffer[0]=0x3c2; /* greek small final sigma */
                        }
                        i=1;
                    } else {
                        /* no known conditional special case mapping, output the code point itself */
                        i=0;
                        UTF_APPEND_CHAR_UNSAFE(buffer, i, c);
                    }
                } else {
                    /* get the special case mapping string from the data file */
                    u=ucharsTable+(props&0xffff);
                    i=(int32_t)(*u++)&0x1f;
                }

                /* output this case mapping result string */
                if( (destIndex+i)<=destCapacity ||
                    /* attempt to grow the buffer */
                    (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+i)+20, destIndex)))
                ) {
                    /* copy the case mapping to the destination */
                    while(i>0) {
                        dest[destIndex++]=*u++;
                        --i;
                    }
                } else {
                    /* buffer overflow */
                    /* copy as much as possible */
                    while(destIndex<destCapacity) {
                        dest[destIndex++]=*u++;
                        --i;
                    }
                    /* keep incrementing the destIndex for preflighting */
                    destIndex+=i;
                }

                /* do not fall through to the output of c */
                continue;
            } else if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_LOWERCASE)) {
                i=EXC_LOWERCASE;
                ++pe;
                ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
                c=(UChar32)*pe;
            }
        }

        /* handle 1:1 code point mappings from UnicodeData.txt */
        if(c<=0xffff) {
            if( destIndex<destCapacity ||
                /* attempt to grow the buffer */
                (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+1)+20, destIndex)))
            ) {
                dest[destIndex++]=(UChar)c;
            } else {
                /* buffer overflow */
                /* keep incrementing the destIndex for preflighting */
                ++destIndex;
            }
        } else {
            if( (destIndex+2)<=destCapacity ||
                /* attempt to grow the buffer */
                (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+2)+20, destIndex)))
            ) {
                dest[destIndex++]=(UChar)(0xd7c0+(c>>10));
                dest[destIndex++]=(UChar)(0xdc00|(c&0x3ff));
            } else {
                /* buffer overflow */
                /* write the first surrogate if possible */
                if(destIndex<destCapacity) {
                    dest[destIndex]=(UChar)(0xd7c0+(c>>10));
                }
                /* keep incrementing the destIndex for preflighting */
                destIndex+=2;
            }
        }
    }

    if(destIndex>destCapacity) {
        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
    }
    return destIndex;
}

U_CFUNC int32_t
u_internalStrToUpper(UChar *dest, int32_t destCapacity,
                     const UChar *src, int32_t srcLength,
                     const char *locale,
                     GrowBuffer *growBuffer, void *context,
                     UErrorCode *pErrorCode) {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    uint32_t *pe;
    const UChar *u;
    uint32_t props, firstExceptionValue;
    int32_t srcIndex, destIndex, i, loc;
    UChar32 c;
    UBool canGrow;

    /* do not attempt to grow if there is no growBuffer function or if it has failed before */
    canGrow= growBuffer!=NULL;

    /* test early, once, if there is a data file */
    if(!HAVE_DATA) {
        /*
         * If we do not have real character properties data,
         * then we only do a fixed-length ASCII case mapping.
         */
        if(srcLength<=destCapacity ||
            /* attempt to grow the buffer */
            (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, srcLength, 0)))
        ) {
            destIndex=srcLength;
            *pErrorCode=U_USING_DEFAULT_ERROR;
        } else {
            destIndex=destCapacity;
            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
        }

        for(srcIndex=0; srcIndex<destIndex; ++srcIndex) {
            c=src[srcIndex];
            if((uint32_t)(c-0x61)<26) {
                dest[srcIndex]=(UChar)(c-0x20);
            } else {
                dest[srcIndex]=(UChar)c;
            }
        }

        return srcLength;
    }

    /* set up local variables */
    loc=getCaseLocale(locale);

    /* case mapping loop */
    srcIndex=destIndex=0;
    while(srcIndex<srcLength) {
        UTF_NEXT_CHAR(src, srcIndex, srcLength, c);
        props=GET_PROPS_UNSAFE(c);
        if(!PROPS_VALUE_IS_EXCEPTION(props)) {
            if(GET_CATEGORY(props)==U_LOWERCASE_LETTER) {
                c-=GET_SIGNED_VALUE(props);
            }
        } else {
            pe=GET_EXCEPTIONS(props);
            firstExceptionValue=*pe;
            if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_SPECIAL_CASING)) {
                i=EXC_SPECIAL_CASING;
                ++pe;
                ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
                props=*pe;
                /* fill u and i with the case mapping result string */
                if(props&0x80000000) {
                    /* use hardcoded conditions and mappings */
                    u=buffer;
                    if(c==0x69) {
                        if(loc==LOC_TURKISH) {
                            /* turkish: i maps to dotted I */
                            buffer[0]=0x130;
                        } else {
                            /* other languages: i maps to I */
                            buffer[0]=0x49;
                        }
                        i=1;
                    } else if(c==0x307) {
                        if(loc==LOC_LITHUANIAN) {
                            /* lithuanian: remove DOT ABOVE after U+0069 "i" with upper or titlecase */
                            /* ### TODO: test this with Unicode 3.1 SpecialCasing.txt */
                            /* search backwards for the base letter - this works only because src and dest do not overlap! */
                            i=srcIndex;
                            while(i>0) {
                                UTF_PREV_CHAR(src, 0, i, c);
                                props=GET_PROPS_UNSAFE(c);
                                if(GET_CATEGORY(props)!=U_NON_SPACING_MARK) { /* Mn */
                                    break;
                                }
                            }
                            /* is the base letter an 'i' (U+0069)? */
                            if(c==0x69) {
                                /* yes, remove the dot (continue without output) */
                                continue;
                            } else {
                                /* no, keep the dot */
                                buffer[0]=0x307;
                            }
                        } else {
                            /* other languages: keep the dot */
                            buffer[0]=0x307;
                        }
                        i=1;
                    } else {
                        /* no known conditional special case mapping, output the code point itself */
                        i=0;
                        UTF_APPEND_CHAR_UNSAFE(buffer, i, c);
                    }
                } else {
                    /* get the special case mapping string from the data file */
                    u=ucharsTable+(props&0xffff);
                    i=(int32_t)*u++;

                    /* skip the lowercase result string */
                    u+=i&0x1f;
                    i=(i>>5)&0x1f;
                }

                /* output this case mapping result string */
                if( (destIndex+i)<=destCapacity ||
                    /* attempt to grow the buffer */
                    (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+i)+20, destIndex)))
                ) {
                    /* copy the case mapping to the destination */
                    while(i>0) {
                        dest[destIndex++]=*u++;
                        --i;
                    }
                } else {
                    /* buffer overflow */
                    /* copy as much as possible */
                    while(destIndex<destCapacity) {
                        dest[destIndex++]=*u++;
                        --i;
                    }
                    /* keep incrementing the destIndex for preflighting */
                    destIndex+=i;
                }

                /* do not fall through to the output of c */
                continue;
            } else if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_UPPERCASE)) {
                i=EXC_UPPERCASE;
                ++pe;
                ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
                c=(UChar32)*pe;
            }
        }

        /* handle 1:1 code point mappings from UnicodeData.txt */
        if(c<=0xffff) {
            if( destIndex<destCapacity ||
                /* attempt to grow the buffer */
                (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+1)+20, destIndex)))
            ) {
                dest[destIndex++]=(UChar)c;
            } else {
                /* buffer overflow */
                /* keep incrementing the destIndex for preflighting */
                ++destIndex;
            }
        } else {
            if( (destIndex+2)<=destCapacity ||
                /* attempt to grow the buffer */
                (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+2)+20, destIndex)))
            ) {
                dest[destIndex++]=(UChar)(0xd7c0+(c>>10));
                dest[destIndex++]=(UChar)(0xdc00|(c&0x3ff));
            } else {
                /* buffer overflow */
                /* write the first surrogate if possible */
                if(destIndex<destCapacity) {
                    dest[destIndex]=(UChar)(0xd7c0+(c>>10));
                }
                /* keep incrementing the destIndex for preflighting */
                destIndex+=2;
            }
        }
    }

    if(destIndex>destCapacity) {
        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
    }
    return destIndex;
}

/* 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.
 */

/* return the simple case folding mapping for c */
U_CAPI UChar32 U_EXPORT2
u_foldCase(UChar32 c, uint32_t options) {
    uint32_t props=GET_PROPS(c);
    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if((1UL<<GET_CATEGORY(props))&(1UL<<U_UPPERCASE_LETTER|1UL<<U_TITLECASE_LETTER)) {
            return c+GET_SIGNED_VALUE(props);
        }
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_CASE_FOLDING)) {
            uint32_t *oldPE=pe;
            int i=EXC_CASE_FOLDING;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            props=*pe;
            if(props!=0) {
                /* return the simple mapping, if there is one */
                const UChar *uchars=ucharsTable+(props&0xffff);
                UChar32 simple;
                i=0;
                UTF_NEXT_CHAR_UNSAFE(uchars, i, simple);
                if(simple!=0) {
                    return simple;
                }
                /* fall through to use the lowercase exception value if there is no simple mapping */
                pe=oldPE;
            } else {
                /* special case folding mappings, hardcoded */
                if(options==U_FOLD_CASE_DEFAULT && (uint32_t)(c-0x130)<=1) {
                    /* map dotted I and dotless i to U+0069 small i */
                    return 0x69;
                }
                /* return c itself because it is excluded from case folding */
                return c;
            }
        }
        /* not else! - allow to fall through from above */
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_LOWERCASE)) {
            int i=EXC_LOWERCASE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            return (UChar32)*pe;
        }
    }
    return c; /* no mapping - return c itself */
}

/* internal, return the full case folding mapping for c, must be used only if uprv_haveProperties() is true */
U_CFUNC int32_t
u_internalFoldCase(UChar32 c, UChar dest[32], uint32_t options) {
    uint32_t props=GET_PROPS_UNSAFE(c);
    int32_t i;

    if(!PROPS_VALUE_IS_EXCEPTION(props)) {
        if((1UL<<GET_CATEGORY(props))&(1UL<<U_UPPERCASE_LETTER|1UL<<U_TITLECASE_LETTER)) {
            c+=GET_SIGNED_VALUE(props);
        }
    } else {
        uint32_t *pe=GET_EXCEPTIONS(props);
        uint32_t firstExceptionValue=*pe;
        if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_CASE_FOLDING)) {
            int i=EXC_CASE_FOLDING;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            props=*pe;
            if(props!=0) {
                /* return the full mapping */
                const UChar *uchars=ucharsTable+(props&0xffff)+2;
                props>>=24;

                /* copy the result string */
                i=0;
                while(i<(int32_t)props) {
                    dest[i++]=*uchars++;
                }
                return i;
            } else {
                /* special case folding mappings, hardcoded */
                if(options==U_FOLD_CASE_DEFAULT && (uint32_t)(c-0x130)<=1) {
                    /* map dotted I and dotless i to U+0069 small i */
                    dest[0]=0x69;
                    return 1;
                }
                /* return c itself because it is excluded from case folding */
            }
        } else if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_LOWERCASE)) {
            int i=EXC_LOWERCASE;
            ++pe;
            ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
            c=(UChar32)*pe;
        }
    }

    /* write c to dest */
    i=0;
    UTF_APPEND_CHAR_UNSAFE(dest, i, c);
    return i;
}

/* case-fold the source string using the full mappings */
U_CFUNC int32_t
u_internalStrFoldCase(UChar *dest, int32_t destCapacity,
                      const UChar *src, int32_t srcLength,
                      uint32_t options,
                      GrowBuffer *growBuffer, void *context,
                      UErrorCode *pErrorCode) {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    uint32_t *pe;
    const UChar *uchars, *u;
    uint32_t props, firstExceptionValue;
    int32_t srcIndex, destIndex, i;
    UChar32 c;
    UBool canGrow;

    /* do not attempt to grow if there is no growBuffer function or if it has failed before */
    canGrow= growBuffer!=NULL;

    /* test early, once, if there is a data file */
    if(!HAVE_DATA) {
        /*
         * If we do not have real character properties data,
         * then we only do a fixed-length ASCII case mapping.
         */
        if(srcLength<=destCapacity ||
            /* attempt to grow the buffer */
            (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, srcLength, 0)))
        ) {
            destIndex=srcLength;
            *pErrorCode=U_USING_DEFAULT_ERROR;
        } else {
            destIndex=destCapacity;
            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
        }

        for(srcIndex=0; srcIndex<destIndex; ++srcIndex) {
            c=src[srcIndex];
            if((uint32_t)(c-0x41)<26) {
                dest[srcIndex]=(UChar)(c+0x20);
            } else {
                dest[srcIndex]=(UChar)c;
            }
        }

        return srcLength;
    }

    /* set up local variables */
    /* add 2 because we always need to skip the 2 UChars for the simple mappings */
    uchars=ucharsTable+2;

    /* case mapping loop */
    srcIndex=destIndex=0;
    while(srcIndex<srcLength) {
        UTF_NEXT_CHAR(src, srcIndex, srcLength, c);
        props=GET_PROPS_UNSAFE(c);
        if(!PROPS_VALUE_IS_EXCEPTION(props)) {
            if((1UL<<GET_CATEGORY(props))&(1UL<<U_UPPERCASE_LETTER|1UL<<U_TITLECASE_LETTER)) {
                c+=GET_SIGNED_VALUE(props);
            }
        } else {
            pe=GET_EXCEPTIONS(props);
            firstExceptionValue=*pe;
            if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_CASE_FOLDING)) {
                i=EXC_CASE_FOLDING;
                ++pe;
                ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
                props=*pe;
                /* fill u and i with the case mapping result string */
                if(props!=0) {
                    /* get the case folding string from the data file */
                    u=uchars+(props&0xffff);
                    i=(int32_t)(props>>24);
                } else {
                    /* special case folding mappings, hardcoded */
                    u=buffer;
                    if(options==U_FOLD_CASE_DEFAULT && (uint32_t)(c-0x130)<=1) {
                        /* map dotted I and dotless i to U+0069 small i */
                        buffer[0]=0x69;
                        i=1;
                    } else {
                        /* output c itself because it is excluded from case folding */
                        i=0;
                        UTF_APPEND_CHAR_UNSAFE(buffer, i, c);
                    }
                }

                /* output this case mapping result string */
                if( (destIndex+i)<=destCapacity ||
                    /* attempt to grow the buffer */
                    (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+i)+20, destIndex)))
                ) {
                    /* copy the case mapping to the destination */
                    while(i>0) {
                        dest[destIndex++]=*u++;
                        --i;
                    }
                } else {
                    /* buffer overflow */
                    /* copy as much as possible */
                    while(destIndex<destCapacity) {
                        dest[destIndex++]=*u++;
                        --i;
                    }
                    /* keep incrementing the destIndex for preflighting */
                    destIndex+=i;
                }

                /* do not fall through to the output of c */
                continue;
            } else if(HAVE_EXCEPTION_VALUE(firstExceptionValue, EXC_LOWERCASE)) {
                i=EXC_LOWERCASE;
                ++pe;
                ADD_EXCEPTION_OFFSET(firstExceptionValue, i, pe);
                c=(UChar32)*pe;
            }
        }

        /* handle 1:1 code point mappings from UnicodeData.txt */
        if(c<=0xffff) {
            if( destIndex<destCapacity ||
                /* attempt to grow the buffer */
                (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+1)+20, destIndex)))
            ) {
                dest[destIndex++]=(UChar)c;
            } else {
                /* buffer overflow */
                /* keep incrementing the destIndex for preflighting */
                ++destIndex;
            }
        } else {
            if( (destIndex+2)<=destCapacity ||
                /* attempt to grow the buffer */
                (canGrow && (canGrow=growBuffer(context, &dest, &destCapacity, destCapacity+2*(srcLength-srcIndex+2)+20, destIndex)))
            ) {
                dest[destIndex++]=(UChar)(0xd7c0+(c>>10));
                dest[destIndex++]=(UChar)(0xdc00|(c&0x3ff));
            } else {
                /* buffer overflow */
                /* write the first surrogate if possible */
                if(destIndex<destCapacity) {
                    dest[destIndex]=(UChar)(0xd7c0+(c>>10));
                }
                /* keep incrementing the destIndex for preflighting */
                destIndex+=2;
            }
        }
    }

    if(destIndex>destCapacity) {
        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
    }
    return destIndex;
}
