16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 2002-2013, International Business Machines
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Corporation and others.  All Rights Reserved.
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   file name:  uprops.cpp
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   encoding:   US-ASCII
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   tab size:   8 (not used)
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   indentation:4
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created on: 2002feb24
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   created by: Markus W. Scherer
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Implementations for mostly non-core Unicode character properties
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   stored in uprops.icu.
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   With the APIs implemented here, almost all properties files and
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   their associated implementation files are used from this file,
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   including those for normalization and case mappings.
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h"
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uchar.h"
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/unorm2.h"
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uscript.h"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h"
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h"
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "normalizer2impl.h"
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_cmn.h"
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "umutex.h"
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ubidi_props.h"
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uprops.h"
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucase.h"
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ustr_imp.h"
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_USE
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define GET_BIDI_PROPS() ubidi_getSingleton()
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* general properties API functions ----------------------------------------- */
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct BinaryProperty;
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef UBool BinaryPropertyContains(const BinaryProperty &prop, UChar32 c, UProperty which);
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct BinaryProperty {
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t column;  // SRC_PROPSVEC column, or "source" if mask==0
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t mask;
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    BinaryPropertyContains *contains;
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool defaultContains(const BinaryProperty &prop, UChar32 c, UProperty /*which*/) {
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* systematic, directly stored properties */
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (u_getUnicodeProperties(c, prop.column)&prop.mask)!=0;
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool caseBinaryPropertyContains(const BinaryProperty &/*prop*/, UChar32 c, UProperty which) {
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ucase_hasBinaryProperty(c, which);
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isBidiControl(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ubidi_isBidiControl(GET_BIDI_PROPS(), c);
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isMirrored(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ubidi_isMirrored(GET_BIDI_PROPS(), c);
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isJoinControl(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ubidi_isJoinControl(GET_BIDI_PROPS(), c);
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool hasFullCompositionExclusion(const BinaryProperty &, UChar32, UProperty) {
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool hasFullCompositionExclusion(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // By definition, Full_Composition_Exclusion is the same as NFC_QC=No.
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode errorCode=U_ZERO_ERROR;
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return U_SUCCESS(errorCode) && impl->isCompNo(impl->getNorm16(c));
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UCHAR_NF*_INERT properties
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isNormInert(const BinaryProperty &, UChar32, UProperty) {
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isNormInert(const BinaryProperty &/*prop*/, UChar32 c, UProperty which) {
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode errorCode=U_ZERO_ERROR;
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Normalizer2 *norm2=Normalizer2Factory::getInstance(
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        (UNormalizationMode)(which-UCHAR_NFD_INERT+UNORM_NFD), errorCode);
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return U_SUCCESS(errorCode) && norm2->isInert(c);
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool changesWhenCasefolded(const BinaryProperty &, UChar32, UProperty) {
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool changesWhenCasefolded(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString nfd;
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode errorCode=U_ZERO_ERROR;
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Normalizer2 *nfcNorm2=Normalizer2Factory::getNFCInstance(errorCode);
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(errorCode)) {
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(nfcNorm2->getDecomposition(c, nfd)) {
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* c has a decomposition */
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(nfd.length()==1) {
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            c=nfd[0];  /* single BMP code point */
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if(nfd.length()<=U16_MAX_LENGTH &&
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                  nfd.length()==U16_LENGTH(c=nfd.char32At(0))
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ) {
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* single supplementary code point */
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            c=U_SENTINEL;
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(c<0) {
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;  /* protect against bad input */
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(c>=0) {
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* single code point */
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const UCaseProps *csp=ucase_getSingleton();
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const UChar *resultString;
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return (UBool)(ucase_toFullFolding(csp, c, &resultString, U_FOLD_CASE_DEFAULT)>=0);
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* guess some large but stack-friendly capacity */
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UChar dest[2*UCASE_MAX_STRING_LENGTH];
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t destLength;
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        destLength=u_strFoldCase(dest, LENGTHOF(dest),
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  nfd.getBuffer(), nfd.length(),
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  U_FOLD_CASE_DEFAULT, &errorCode);
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return (UBool)(U_SUCCESS(errorCode) &&
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                       0!=u_strCompare(nfd.getBuffer(), nfd.length(),
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                       dest, destLength, FALSE));
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool changesWhenNFKC_Casefolded(const BinaryProperty &, UChar32, UProperty) {
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool changesWhenNFKC_Casefolded(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode errorCode=U_ZERO_ERROR;
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Normalizer2Impl *kcf=Normalizer2Factory::getNFKC_CFImpl(errorCode);
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(errorCode)) {
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString src(c);
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString dest;
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // The ReorderingBuffer must be in a block because its destructor
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // needs to release dest's buffer before we look at its contents.
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ReorderingBuffer buffer(*kcf, dest);
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Small destCapacity for NFKC_CF(c).
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(buffer.init(5, errorCode)) {
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const UChar *srcArray=src.getBuffer();
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            kcf->compose(srcArray, srcArray+src.length(), FALSE,
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                          TRUE, buffer, errorCode);
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return U_SUCCESS(errorCode) && dest!=src;
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isCanonSegmentStarter(const BinaryProperty &, UChar32, UProperty) {
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return FALSE;
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isCanonSegmentStarter(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode errorCode=U_ZERO_ERROR;
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        U_SUCCESS(errorCode) && impl->ensureCanonIterData(errorCode) &&
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        impl->isCanonSegmentStarter(c);
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isPOSIX_alnum(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return u_isalnumPOSIX(c);
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isPOSIX_blank(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return u_isblank(c);
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isPOSIX_graph(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return u_isgraphPOSIX(c);
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isPOSIX_print(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return u_isprintPOSIX(c);
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool isPOSIX_xdigit(const BinaryProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return u_isxdigit(c);
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const BinaryProperty binProps[UCHAR_BINARY_LIMIT]={
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * column and mask values for binary properties from u_getUnicodeProperties().
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Must be in order of corresponding UProperty,
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * and there must be exactly one entry per binary UProperty.
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Properties with mask==0 are handled in code.
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * For them, column is the UPropertySource value.
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_ALPHABETIC), defaultContains },
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_ASCII_HEX_DIGIT), defaultContains },
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, isBidiControl },
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, isMirrored },
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_DASH), defaultContains },
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_DEFAULT_IGNORABLE_CODE_POINT), defaultContains },
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_DEPRECATED), defaultContains },
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_DIACRITIC), defaultContains },
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_EXTENDER), defaultContains },
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, hasFullCompositionExclusion },
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_GRAPHEME_BASE), defaultContains },
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_GRAPHEME_EXTEND), defaultContains },
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_GRAPHEME_LINK), defaultContains },
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_HEX_DIGIT), defaultContains },
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_HYPHEN), defaultContains },
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_ID_CONTINUE), defaultContains },
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_ID_START), defaultContains },
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_IDEOGRAPHIC), defaultContains },
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_IDS_BINARY_OPERATOR), defaultContains },
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_IDS_TRINARY_OPERATOR), defaultContains },
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, isJoinControl },
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_LOGICAL_ORDER_EXCEPTION), defaultContains },
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_LOWERCASE
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_MATH), defaultContains },
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_NONCHARACTER_CODE_POINT), defaultContains },
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_QUOTATION_MARK), defaultContains },
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_RADICAL), defaultContains },
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_SOFT_DOTTED
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_TERMINAL_PUNCTUATION), defaultContains },
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_UNIFIED_IDEOGRAPH), defaultContains },
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_UPPERCASE
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_WHITE_SPACE), defaultContains },
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_XID_CONTINUE), defaultContains },
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_XID_START), defaultContains },
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CASE_SENSITIVE
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_S_TERM), defaultContains },
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_VARIATION_SELECTOR), defaultContains },
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, isNormInert },  // UCHAR_NFD_INERT
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFKC,  0, isNormInert },  // UCHAR_NFKD_INERT
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, isNormInert },  // UCHAR_NFC_INERT
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFKC,  0, isNormInert },  // UCHAR_NFKC_INERT
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC_CANON_ITER, 0, isCanonSegmentStarter },
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_PATTERN_SYNTAX), defaultContains },
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 1,                U_MASK(UPROPS_PATTERN_WHITE_SPACE), defaultContains },
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR_AND_PROPSVEC,  0, isPOSIX_alnum },
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR,  0, isPOSIX_blank },
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR,  0, isPOSIX_graph },
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR,  0, isPOSIX_print },
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR,  0, isPOSIX_xdigit },
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CASED
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CASE_IGNORABLE
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_LOWERCASED
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_UPPERCASED
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_TITLECASED
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE_AND_NORM,  0, changesWhenCasefolded },
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CASE,  0, caseBinaryPropertyContains },  // UCHAR_CHANGES_WHEN_CASEMAPPED
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFKC_CF, 0, changesWhenNFKC_Casefolded }
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UBool U_EXPORT2
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_hasBinaryProperty(UChar32 c, UProperty which) {
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* c is range-checked in the functions that are called from here */
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(which<UCHAR_BINARY_START || UCHAR_BINARY_LIMIT<=which) {
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* not a known binary property */
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return FALSE;
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const BinaryProperty &prop=binProps[which];
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return prop.contains(prop, c, which);
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct IntProperty;
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef int32_t IntPropertyGetValue(const IntProperty &prop, UChar32 c, UProperty which);
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef int32_t IntPropertyGetMaxValue(const IntProperty &prop, UProperty which);
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct IntProperty {
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t column;  // SRC_PROPSVEC column, or "source" if mask==0
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uint32_t mask;
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t shift;  // =maxValue if getMaxValueFromShift() is used
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    IntPropertyGetValue *getValue;
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    IntPropertyGetMaxValue *getMaxValue;
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t defaultGetValue(const IntProperty &prop, UChar32 c, UProperty /*which*/) {
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* systematic, directly stored properties */
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (int32_t)(u_getUnicodeProperties(c, prop.column)&prop.mask)>>prop.shift;
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t defaultGetMaxValue(const IntProperty &prop, UProperty /*which*/) {
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (uprv_getMaxValues(prop.column)&prop.mask)>>prop.shift;
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getMaxValueFromShift(const IntProperty &prop, UProperty /*which*/) {
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return prop.shift;
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getBiDiClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (int32_t)u_charDirection(c);
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getBiDiPairedBracketType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (int32_t)ubidi_getPairedBracketType(GET_BIDI_PROPS(), c);
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t biDiGetMaxValue(const IntProperty &/*prop*/, UProperty which) {
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ubidi_getMaxValue(GET_BIDI_PROPS(), which);
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getCombiningClass(const IntProperty &, UChar32, UProperty) {
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getCombiningClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return u_getCombiningClass(c);
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getGeneralCategory(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (int32_t)u_charType(c);
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getJoiningGroup(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ubidi_getJoiningGroup(GET_BIDI_PROPS(), c);
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getJoiningType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return ubidi_getJoiningType(GET_BIDI_PROPS(), c);
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getNumericType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t ntv=(int32_t)GET_NUMERIC_TYPE_VALUE(u_getMainProperties(c));
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return UPROPS_NTV_GET_TYPE(ntv);
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getScript(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode errorCode=U_ZERO_ERROR;
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (int32_t)uscript_getScript(c, &errorCode);
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Map some of the Grapheme Cluster Break values to Hangul Syllable Types.
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Hangul_Syllable_Type is fully redundant with a subset of Grapheme_Cluster_Break.
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UHangulSyllableType gcbToHst[]={
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_NOT_APPLICABLE,   /* U_GCB_OTHER */
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_NOT_APPLICABLE,   /* U_GCB_CONTROL */
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_NOT_APPLICABLE,   /* U_GCB_CR */
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_NOT_APPLICABLE,   /* U_GCB_EXTEND */
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_LEADING_JAMO,     /* U_GCB_L */
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_NOT_APPLICABLE,   /* U_GCB_LF */
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_LV_SYLLABLE,      /* U_GCB_LV */
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_LVT_SYLLABLE,     /* U_GCB_LVT */
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_TRAILING_JAMO,    /* U_GCB_T */
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    U_HST_VOWEL_JAMO        /* U_GCB_V */
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Omit GCB values beyond what we need for hst.
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * The code below checks for the array length.
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getHangulSyllableType(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* see comments on gcbToHst[] above */
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t gcb=(int32_t)(u_getUnicodeProperties(c, 2)&UPROPS_GCB_MASK)>>UPROPS_GCB_SHIFT;
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(gcb<LENGTHOF(gcbToHst)) {
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return gcbToHst[gcb];
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_HST_NOT_APPLICABLE;
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getNormQuickCheck(const IntProperty &, UChar32, UProperty) {
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getNormQuickCheck(const IntProperty &/*prop*/, UChar32 c, UProperty which) {
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (int32_t)unorm_getQuickCheck(c, (UNormalizationMode)(which-UCHAR_NFD_QUICK_CHECK+UNORM_NFD));
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getLeadCombiningClass(const IntProperty &, UChar32, UProperty) {
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getLeadCombiningClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return unorm_getFCD16(c)>>8;
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_NORMALIZATION
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getTrailCombiningClass(const IntProperty &, UChar32, UProperty) {
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t getTrailCombiningClass(const IntProperty &/*prop*/, UChar32 c, UProperty /*which*/) {
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return unorm_getFCD16(c)&0xff;
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const IntProperty intProps[UCHAR_INT_LIMIT-UCHAR_INT_START]={
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /*
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * column, mask and shift values for int-value properties from u_getUnicodeProperties().
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Must be in order of corresponding UProperty,
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * and there must be exactly one entry per int UProperty.
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Properties with mask==0 are handled in code.
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * For them, column is the UPropertySource value.
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, 0,                               getBiDiClass, biDiGetMaxValue },
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0,                UPROPS_BLOCK_MASK, UPROPS_BLOCK_SHIFT, defaultGetValue, defaultGetMaxValue },
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, 0xff,                            getCombiningClass, getMaxValueFromShift },
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 2,                UPROPS_DT_MASK, 0,                  defaultGetValue, defaultGetMaxValue },
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0,                UPROPS_EA_MASK, UPROPS_EA_SHIFT,    defaultGetValue, defaultGetMaxValue },
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR,  0, (int32_t)U_CHAR_CATEGORY_COUNT-1,getGeneralCategory, getMaxValueFromShift },
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, 0,                               getJoiningGroup, biDiGetMaxValue },
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, 0,                               getJoiningType, biDiGetMaxValue },
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 2,                UPROPS_LB_MASK, UPROPS_LB_SHIFT,    defaultGetValue, defaultGetMaxValue },
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_CHAR,  0, (int32_t)U_NT_COUNT-1,           getNumericType, getMaxValueFromShift },
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 0,                UPROPS_SCRIPT_MASK, 0,              getScript, defaultGetMaxValue },
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_PROPSVEC, 0, (int32_t)U_HST_COUNT-1,       getHangulSyllableType, getMaxValueFromShift },
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // UCHAR_NFD_QUICK_CHECK: max=1=YES -- never "maybe", only "no" or "yes"
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, (int32_t)UNORM_YES,              getNormQuickCheck, getMaxValueFromShift },
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // UCHAR_NFKD_QUICK_CHECK: max=1=YES -- never "maybe", only "no" or "yes"
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFKC,  0, (int32_t)UNORM_YES,              getNormQuickCheck, getMaxValueFromShift },
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // UCHAR_NFC_QUICK_CHECK: max=2=MAYBE
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, (int32_t)UNORM_MAYBE,            getNormQuickCheck, getMaxValueFromShift },
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // UCHAR_NFKC_QUICK_CHECK: max=2=MAYBE
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFKC,  0, (int32_t)UNORM_MAYBE,            getNormQuickCheck, getMaxValueFromShift },
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, 0xff,                            getLeadCombiningClass, getMaxValueFromShift },
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_NFC,   0, 0xff,                            getTrailCombiningClass, getMaxValueFromShift },
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 2,                UPROPS_GCB_MASK, UPROPS_GCB_SHIFT,  defaultGetValue, defaultGetMaxValue },
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 2,                UPROPS_SB_MASK, UPROPS_SB_SHIFT,    defaultGetValue, defaultGetMaxValue },
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { 2,                UPROPS_WB_MASK, UPROPS_WB_SHIFT,    defaultGetValue, defaultGetMaxValue },
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    { UPROPS_SRC_BIDI,  0, 0,                               getBiDiPairedBracketType, biDiGetMaxValue },
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org};
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_getIntPropertyValue(UChar32 c, UProperty which) {
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(which<UCHAR_INT_START) {
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UCHAR_BINARY_START<=which && which<UCHAR_BINARY_LIMIT) {
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            const BinaryProperty &prop=binProps[which];
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return prop.contains(prop, c, which);
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_INT_LIMIT) {
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const IntProperty &prop=intProps[which-UCHAR_INT_START];
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return prop.getValue(prop, c, which);
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which==UCHAR_GENERAL_CATEGORY_MASK) {
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return U_MASK(u_charType(c));
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0;  // undefined
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_getIntPropertyMinValue(UProperty /*which*/) {
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return 0; /* all binary/enum/int properties have a minimum value of 0 */
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_getIntPropertyMaxValue(UProperty which) {
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(which<UCHAR_INT_START) {
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(UCHAR_BINARY_START<=which && which<UCHAR_BINARY_LIMIT) {
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return 1;  // maximum TRUE for all binary properties
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_INT_LIMIT) {
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const IntProperty &prop=intProps[which-UCHAR_INT_START];
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return prop.getMaxValue(prop, which);
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return -1;  // undefined
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UPropertySource U_EXPORT2
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orguprops_getSource(UProperty which) {
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(which<UCHAR_BINARY_START) {
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return UPROPS_SRC_NONE; /* undefined */
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_BINARY_LIMIT) {
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const BinaryProperty &prop=binProps[which];
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(prop.mask!=0) {
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_PROPSVEC;
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return (UPropertySource)prop.column;
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_INT_START) {
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return UPROPS_SRC_NONE; /* undefined */
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_INT_LIMIT) {
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const IntProperty &prop=intProps[which-UCHAR_INT_START];
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(prop.mask!=0) {
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_PROPSVEC;
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return (UPropertySource)prop.column;
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_STRING_START) {
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch(which) {
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_GENERAL_CATEGORY_MASK:
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_NUMERIC_VALUE:
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_CHAR;
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_NONE;
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else if(which<UCHAR_STRING_LIMIT) {
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch(which) {
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_AGE:
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_PROPSVEC;
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_BIDI_MIRRORING_GLYPH:
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_BIDI;
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_CASE_FOLDING:
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_LOWERCASE_MAPPING:
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_SIMPLE_CASE_FOLDING:
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_SIMPLE_LOWERCASE_MAPPING:
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_SIMPLE_TITLECASE_MAPPING:
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_SIMPLE_UPPERCASE_MAPPING:
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_TITLECASE_MAPPING:
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_UPPERCASE_MAPPING:
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_CASE;
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_ISO_COMMENT:
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_NAME:
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_UNICODE_1_NAME:
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_NAMES;
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_NONE;
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        switch(which) {
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        case UCHAR_SCRIPT_EXTENSIONS:
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_PROPSVEC;
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        default:
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return UPROPS_SRC_NONE; /* undefined */
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_NORMALIZATION
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_getFC_NFKC_Closure(UChar32 c, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode) {
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(destCapacity<0 || (dest==NULL && destCapacity>0)) {
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Compute the FC_NFKC_Closure on the fly:
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // We have the API for complete coverage of Unicode properties, although
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // this value by itself is not useful via API.
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // (What could be useful is a custom normalization table that combines
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // case folding and NFKC.)
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // For the derivation, see Unicode's DerivedNormalizationProps.txt.
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const Normalizer2 *nfkc=Normalizer2Factory::getNFKCInstance(*pErrorCode);
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UCaseProps *csp=ucase_getSingleton();
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*pErrorCode)) {
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // first: b = NFKC(Fold(a))
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString folded1String;
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *folded1;
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t folded1Length=ucase_toFullFolding(csp, c, &folded1, U_FOLD_CASE_DEFAULT);
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(folded1Length<0) {
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        const Normalizer2Impl *nfkcImpl=Normalizer2Factory::getImpl(nfkc);
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(nfkcImpl->getCompQuickCheck(nfkcImpl->getNorm16(c))!=UNORM_NO) {
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return u_terminateUChars(dest, destCapacity, 0, pErrorCode);  // c does not change at all under CaseFolding+NFKC
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        folded1String.setTo(c);
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(folded1Length>UCASE_MAX_STRING_LENGTH) {
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            folded1String.setTo(folded1Length);
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            folded1String.setTo(FALSE, folded1, folded1Length);
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString kc1=nfkc->normalize(folded1String, *pErrorCode);
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // second: c = NFKC(Fold(b))
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString folded2String(kc1);
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString kc2=nfkc->normalize(folded2String.foldCase(), *pErrorCode);
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // if (c != b) add the mapping from a to c
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*pErrorCode) || kc1==kc2) {
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } else {
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return kc2.extract(dest, destCapacity, *pErrorCode);
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
610