164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others.
264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html
350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/*
450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
68de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert*   Copyright (C) 2009-2016, International Business Machines
750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   Corporation and others.  All Rights Reserved.
850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*******************************************************************************
1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   file name:  normalizer2.cpp
1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   encoding:   US-ASCII
1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   tab size:   8 (not used)
1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   indentation:4
1450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*
1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created on: 2009nov22
1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*   created by: Markus W. Scherer
1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*/
1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/utypes.h"
2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_NORMALIZATION
2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/normalizer2.h"
2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/unistr.h"
2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/unorm.h"
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "mutex.h"
28f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "norm2allmodes.h"
2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "normalizer2impl.h"
3059d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h"
3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ucln_cmn.h"
32f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
33f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliususing icu::Normalizer2Impl;
34f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
35f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// NFC/NFD data machine-generated by gennorm2 --csource
368de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert#define INCLUDED_FROM_NORMALIZER2_CPP
37f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "norm2_nfc_data.h"
3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN
4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Public API dispatch via Normalizer2 subclasses -------------------------- ***
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
43103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNormalizer2::~Normalizer2() {}
44103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
45103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUBool
46103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNormalizer2::getRawDecomposition(UChar32, UnicodeString &) const {
47103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return FALSE;
48103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
49103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
50103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUChar32
51103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNormalizer2::composePair(UChar32, UChar32) const {
52103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return U_SENTINEL;
53103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
54103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
55103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuint8_t
56103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNormalizer2::getCombiningClass(UChar32 /*c*/) const {
57103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return 0;
58103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
59103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Normalizer2 implementation for the old UNORM_NONE.
6150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass NoopNormalizer2 : public Normalizer2 {
62103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    virtual ~NoopNormalizer2();
63103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UnicodeString &
6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    normalize(const UnicodeString &src,
6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              UnicodeString &dest,
6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              UErrorCode &errorCode) const {
6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_SUCCESS(errorCode)) {
6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(&dest!=&src) {
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                dest=src;
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                errorCode=U_ILLEGAL_ARGUMENT_ERROR;
7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return dest;
7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UnicodeString &
7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    normalizeSecondAndAppend(UnicodeString &first,
7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             const UnicodeString &second,
8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                             UErrorCode &errorCode) const {
8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_SUCCESS(errorCode)) {
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(&first!=&second) {
8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                first.append(second);
8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                errorCode=U_ILLEGAL_ARGUMENT_ERROR;
8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return first;
8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UnicodeString &
9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    append(UnicodeString &first,
9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           const UnicodeString &second,
9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           UErrorCode &errorCode) const {
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if(U_SUCCESS(errorCode)) {
9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if(&first!=&second) {
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                first.append(second);
9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                errorCode=U_ILLEGAL_ARGUMENT_ERROR;
9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return first;
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UBool
10427f654740f2a26ad62a5c155af9199af9e69b889claireho    getDecomposition(UChar32, UnicodeString &) const {
10527f654740f2a26ad62a5c155af9199af9e69b889claireho        return FALSE;
10627f654740f2a26ad62a5c155af9199af9e69b889claireho    }
107103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // No need to override the default getRawDecomposition().
10827f654740f2a26ad62a5c155af9199af9e69b889claireho    virtual UBool
10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    isNormalized(const UnicodeString &, UErrorCode &) const {
11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return TRUE;
11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UNormalizationCheckResult
11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    quickCheck(const UnicodeString &, UErrorCode &) const {
11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return UNORM_YES;
11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual int32_t
11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    spanQuickCheckYes(const UnicodeString &s, UErrorCode &) const {
11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return s.length();
11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UBool hasBoundaryBefore(UChar32) const { return TRUE; }
12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UBool hasBoundaryAfter(UChar32) const { return TRUE; }
12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    virtual UBool isInert(UChar32) const { return TRUE; }
12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho};
12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
125103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNoopNormalizer2::~NoopNormalizer2() {}
126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
127103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusNormalizer2WithImpl::~Normalizer2WithImpl() {}
128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
129103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusDecomposeNormalizer2::~DecomposeNormalizer2() {}
130103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
131103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusComposeNormalizer2::~ComposeNormalizer2() {}
132103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
133103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusFCDNormalizer2::~FCDNormalizer2() {}
134103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// instance cache ---------------------------------------------------------- ***
13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
137f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::~Norm2AllModes() {
138f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    delete impl;
139f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}
14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
14150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNorm2AllModes *
142f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::createInstance(Normalizer2Impl *impl, UErrorCode &errorCode) {
14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(errorCode)) {
144f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        delete impl;
14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return NULL;
14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
147f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    Norm2AllModes *allModes=new Norm2AllModes(impl);
148f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(allModes==NULL) {
14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        errorCode=U_MEMORY_ALLOCATION_ERROR;
150f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        delete impl;
15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return NULL;
15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
153f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return allModes;
154f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}
155f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
156f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes *
157f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::createNFCInstance(UErrorCode &errorCode) {
158f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(U_FAILURE(errorCode)) {
159f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return NULL;
160f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
161f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    Normalizer2Impl *impl=new Normalizer2Impl;
162f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(impl==NULL) {
163f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        errorCode=U_MEMORY_ALLOCATION_ERROR;
164f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return NULL;
165f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
166f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    impl->init(norm2_nfc_data_indexes, &norm2_nfc_data_trie,
167f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius               norm2_nfc_data_extraData, norm2_nfc_data_smallFCD);
168f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return createInstance(impl, errorCode);
16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_BEGIN
17250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV uprv_normalizer2_cleanup();
17350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
17559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic Norm2AllModes *nfcSingleton;
17659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic Normalizer2   *noopSingleton;
17759d709d503bab6e2b61931737e662dd293b40578ccornelius
17859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce nfcInitOnce = U_INITONCE_INITIALIZER;
17959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce noopInitOnce = U_INITONCE_INITIALIZER;
18059d709d503bab6e2b61931737e662dd293b40578ccornelius
181f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// UInitOnce singleton initialization functions
182f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV initNFCSingleton(UErrorCode &errorCode) {
183f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    nfcSingleton=Norm2AllModes::createNFCInstance(errorCode);
184f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
185f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}
186f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
187f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic void U_CALLCONV initNoopSingleton(UErrorCode &errorCode) {
188f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(U_FAILURE(errorCode)) {
189f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return;
190f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
191f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    noopSingleton=new NoopNormalizer2;
192f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(noopSingleton==NULL) {
193f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        errorCode=U_MEMORY_ALLOCATION_ERROR;
194f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return;
19559d709d503bab6e2b61931737e662dd293b40578ccornelius    }
19659d709d503bab6e2b61931737e662dd293b40578ccornelius    ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
19759d709d503bab6e2b61931737e662dd293b40578ccornelius}
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
19950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_BEGIN
20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
20150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV uprv_normalizer2_cleanup() {
20259d709d503bab6e2b61931737e662dd293b40578ccornelius    delete nfcSingleton;
20359d709d503bab6e2b61931737e662dd293b40578ccornelius    nfcSingleton = NULL;
20459d709d503bab6e2b61931737e662dd293b40578ccornelius    delete noopSingleton;
20559d709d503bab6e2b61931737e662dd293b40578ccornelius    noopSingleton = NULL;
20659d709d503bab6e2b61931737e662dd293b40578ccornelius    nfcInitOnce.reset();
20759d709d503bab6e2b61931737e662dd293b40578ccornelius    noopInitOnce.reset();
20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return TRUE;
20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
21150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
213f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Norm2AllModes *
214f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNorm2AllModes::getNFCInstance(UErrorCode &errorCode) {
215f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(U_FAILURE(errorCode)) { return NULL; }
216f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    umtx_initOnce(nfcInitOnce, &initNFCSingleton, errorCode);
217f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return nfcSingleton;
21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
220f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 *
221f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2::getNFCInstance(UErrorCode &errorCode) {
222f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
223f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return allModes!=NULL ? &allModes->comp : NULL;
22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
226f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 *
227f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusNormalizer2::getNFDInstance(UErrorCode &errorCode) {
228f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
229f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return allModes!=NULL ? &allModes->decomp : NULL;
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
232f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 *Normalizer2Factory::getFCDInstance(UErrorCode &errorCode) {
233f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
234f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return allModes!=NULL ? &allModes->fcd : NULL;
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
237f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst Normalizer2 *Normalizer2Factory::getFCCInstance(UErrorCode &errorCode) {
238f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
239f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return allModes!=NULL ? &allModes->fcc : NULL;
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst Normalizer2 *Normalizer2Factory::getNoopInstance(UErrorCode &errorCode) {
243f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(U_FAILURE(errorCode)) { return NULL; }
244f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    umtx_initOnce(noopInitOnce, &initNoopSingleton, errorCode);
24559d709d503bab6e2b61931737e662dd293b40578ccornelius    return noopSingleton;
24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
24850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst Normalizer2Impl *
24950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNormalizer2Factory::getNFCImpl(UErrorCode &errorCode) {
250f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
251f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    return allModes!=NULL ? allModes->impl : NULL;
25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst Normalizer2Impl *
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoNormalizer2Factory::getImpl(const Normalizer2 *norm2) {
25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return &((Normalizer2WithImpl *)norm2)->impl;
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
25950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// C API ------------------------------------------------------------------- ***
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_USE
26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
26554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI const UNormalizer2 * U_EXPORT2
266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusunorm2_getNFCInstance(UErrorCode *pErrorCode) {
267103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return (const UNormalizer2 *)Normalizer2::getNFCInstance(*pErrorCode);
268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
269103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
27054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI const UNormalizer2 * U_EXPORT2
271103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusunorm2_getNFDInstance(UErrorCode *pErrorCode) {
272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return (const UNormalizer2 *)Normalizer2::getNFDInstance(*pErrorCode);
273103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
274103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
27554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI void U_EXPORT2
27650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_close(UNormalizer2 *norm2) {
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    delete (Normalizer2 *)norm2;
27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
28054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_normalize(const UNormalizer2 *norm2,
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 const UChar *src, int32_t length,
28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 UChar *dest, int32_t capacity,
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                 UErrorCode *pErrorCode) {
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*pErrorCode)) {
28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
28827f654740f2a26ad62a5c155af9199af9e69b889claireho    if( (src==NULL ? length!=0 : length<-1) ||
28927f654740f2a26ad62a5c155af9199af9e69b889claireho        (dest==NULL ? capacity!=0 : capacity<0) ||
29027f654740f2a26ad62a5c155af9199af9e69b889claireho        (src==dest && src!=NULL)
29127f654740f2a26ad62a5c155af9199af9e69b889claireho    ) {
29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString destString(dest, 0, capacity);
29627f654740f2a26ad62a5c155af9199af9e69b889claireho    // length==0: Nothing to do, and n2wi->normalize(NULL, NULL, buffer, ...) would crash.
29727f654740f2a26ad62a5c155af9199af9e69b889claireho    if(length!=0) {
29827f654740f2a26ad62a5c155af9199af9e69b889claireho        const Normalizer2 *n2=(const Normalizer2 *)norm2;
29927f654740f2a26ad62a5c155af9199af9e69b889claireho        const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
30027f654740f2a26ad62a5c155af9199af9e69b889claireho        if(n2wi!=NULL) {
30127f654740f2a26ad62a5c155af9199af9e69b889claireho            // Avoid duplicate argument checking and support NUL-terminated src.
30227f654740f2a26ad62a5c155af9199af9e69b889claireho            ReorderingBuffer buffer(n2wi->impl, destString);
30327f654740f2a26ad62a5c155af9199af9e69b889claireho            if(buffer.init(length, *pErrorCode)) {
30427f654740f2a26ad62a5c155af9199af9e69b889claireho                n2wi->normalize(src, length>=0 ? src+length : NULL, buffer, *pErrorCode);
30527f654740f2a26ad62a5c155af9199af9e69b889claireho            }
30627f654740f2a26ad62a5c155af9199af9e69b889claireho        } else {
30727f654740f2a26ad62a5c155af9199af9e69b889claireho            UnicodeString srcString(length<0, src, length);
30827f654740f2a26ad62a5c155af9199af9e69b889claireho            n2->normalize(srcString, destString, *pErrorCode);
30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return destString.extract(dest, capacity, *pErrorCode);
31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
31450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t
31550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehonormalizeSecondAndAppend(const UNormalizer2 *norm2,
31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         UChar *first, int32_t firstLength, int32_t firstCapacity,
31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         const UChar *second, int32_t secondLength,
31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         UBool doNormalize,
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         UErrorCode *pErrorCode) {
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*pErrorCode)) {
32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
32327f654740f2a26ad62a5c155af9199af9e69b889claireho    if( (second==NULL ? secondLength!=0 : secondLength<-1) ||
32427f654740f2a26ad62a5c155af9199af9e69b889claireho        (first==NULL ? (firstCapacity!=0 || firstLength!=0) :
32527f654740f2a26ad62a5c155af9199af9e69b889claireho                       (firstCapacity<0 || firstLength<-1)) ||
32627f654740f2a26ad62a5c155af9199af9e69b889claireho        (first==second && first!=NULL)
32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ) {
32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString firstString(first, firstLength, firstCapacity);
332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    firstLength=firstString.length();  // In case it was -1.
33327f654740f2a26ad62a5c155af9199af9e69b889claireho    // secondLength==0: Nothing to do, and n2wi->normalizeAndAppend(NULL, NULL, buffer, ...) would crash.
33427f654740f2a26ad62a5c155af9199af9e69b889claireho    if(secondLength!=0) {
33527f654740f2a26ad62a5c155af9199af9e69b889claireho        const Normalizer2 *n2=(const Normalizer2 *)norm2;
33627f654740f2a26ad62a5c155af9199af9e69b889claireho        const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
33727f654740f2a26ad62a5c155af9199af9e69b889claireho        if(n2wi!=NULL) {
33827f654740f2a26ad62a5c155af9199af9e69b889claireho            // Avoid duplicate argument checking and support NUL-terminated src.
339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UnicodeString safeMiddle;
340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            {
341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                ReorderingBuffer buffer(n2wi->impl, firstString);
342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(buffer.init(firstLength+secondLength+1, *pErrorCode)) {  // destCapacity>=-1
343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    n2wi->normalizeAndAppend(second, secondLength>=0 ? second+secondLength : NULL,
344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                             doNormalize, safeMiddle, buffer, *pErrorCode);
345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }  // The ReorderingBuffer destructor finalizes firstString.
347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if(U_FAILURE(*pErrorCode) || firstString.length()>firstCapacity) {
348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Restore the modified suffix of the first string.
349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // This does not restore first[] array contents between firstLength and firstCapacity.
350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // (That might be uninitialized memory, as far as we know.)
351103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if(first!=NULL) { /* don't dereference NULL */
352103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                  safeMiddle.extract(0, 0x7fffffff, first+firstLength-safeMiddle.length());
353103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                  if(firstLength<firstCapacity) {
354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    first[firstLength]=0;  // NUL-terminate in case it was originally.
355103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                  }
356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
35727f654740f2a26ad62a5c155af9199af9e69b889claireho            }
35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        } else {
35927f654740f2a26ad62a5c155af9199af9e69b889claireho            UnicodeString secondString(secondLength<0, second, secondLength);
36027f654740f2a26ad62a5c155af9199af9e69b889claireho            if(doNormalize) {
36127f654740f2a26ad62a5c155af9199af9e69b889claireho                n2->normalizeSecondAndAppend(firstString, secondString, *pErrorCode);
36227f654740f2a26ad62a5c155af9199af9e69b889claireho            } else {
36327f654740f2a26ad62a5c155af9199af9e69b889claireho                n2->append(firstString, secondString, *pErrorCode);
36427f654740f2a26ad62a5c155af9199af9e69b889claireho            }
36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return firstString.extract(first, firstCapacity, *pErrorCode);
36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
37054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
37150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_normalizeSecondAndAppend(const UNormalizer2 *norm2,
37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                UChar *first, int32_t firstLength, int32_t firstCapacity,
37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                const UChar *second, int32_t secondLength,
37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                UErrorCode *pErrorCode) {
37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return normalizeSecondAndAppend(norm2,
37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    first, firstLength, firstCapacity,
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    second, secondLength,
37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    TRUE, pErrorCode);
37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
38154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
38250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_append(const UNormalizer2 *norm2,
38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              UChar *first, int32_t firstLength, int32_t firstCapacity,
38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              const UChar *second, int32_t secondLength,
38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho              UErrorCode *pErrorCode) {
38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return normalizeSecondAndAppend(norm2,
38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    first, firstLength, firstCapacity,
38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    second, secondLength,
38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    FALSE, pErrorCode);
39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
39254dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
39327f654740f2a26ad62a5c155af9199af9e69b889clairehounorm2_getDecomposition(const UNormalizer2 *norm2,
39427f654740f2a26ad62a5c155af9199af9e69b889claireho                        UChar32 c, UChar *decomposition, int32_t capacity,
39527f654740f2a26ad62a5c155af9199af9e69b889claireho                        UErrorCode *pErrorCode) {
39627f654740f2a26ad62a5c155af9199af9e69b889claireho    if(U_FAILURE(*pErrorCode)) {
39727f654740f2a26ad62a5c155af9199af9e69b889claireho        return 0;
39827f654740f2a26ad62a5c155af9199af9e69b889claireho    }
39927f654740f2a26ad62a5c155af9199af9e69b889claireho    if(decomposition==NULL ? capacity!=0 : capacity<0) {
40027f654740f2a26ad62a5c155af9199af9e69b889claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
40127f654740f2a26ad62a5c155af9199af9e69b889claireho        return 0;
40227f654740f2a26ad62a5c155af9199af9e69b889claireho    }
40327f654740f2a26ad62a5c155af9199af9e69b889claireho    UnicodeString destString(decomposition, 0, capacity);
40427f654740f2a26ad62a5c155af9199af9e69b889claireho    if(reinterpret_cast<const Normalizer2 *>(norm2)->getDecomposition(c, destString)) {
40527f654740f2a26ad62a5c155af9199af9e69b889claireho        return destString.extract(decomposition, capacity, *pErrorCode);
40627f654740f2a26ad62a5c155af9199af9e69b889claireho    } else {
40727f654740f2a26ad62a5c155af9199af9e69b889claireho        return -1;
40827f654740f2a26ad62a5c155af9199af9e69b889claireho    }
40927f654740f2a26ad62a5c155af9199af9e69b889claireho}
41027f654740f2a26ad62a5c155af9199af9e69b889claireho
41154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusunorm2_getRawDecomposition(const UNormalizer2 *norm2,
413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                           UChar32 c, UChar *decomposition, int32_t capacity,
414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                           UErrorCode *pErrorCode) {
415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(U_FAILURE(*pErrorCode)) {
416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return 0;
417103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(decomposition==NULL ? capacity!=0 : capacity<0) {
419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return 0;
421103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UnicodeString destString(decomposition, 0, capacity);
423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(reinterpret_cast<const Normalizer2 *>(norm2)->getRawDecomposition(c, destString)) {
424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return destString.extract(decomposition, capacity, *pErrorCode);
425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    } else {
426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return -1;
427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
429103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
43054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UChar32 U_EXPORT2
431103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusunorm2_composePair(const UNormalizer2 *norm2, UChar32 a, UChar32 b) {
432103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return reinterpret_cast<const Normalizer2 *>(norm2)->composePair(a, b);
433103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
434103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
43554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI uint8_t U_EXPORT2
436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusunorm2_getCombiningClass(const UNormalizer2 *norm2, UChar32 c) {
437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return reinterpret_cast<const Normalizer2 *>(norm2)->getCombiningClass(c);
438103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
439103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
44054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UBool U_EXPORT2
44150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_isNormalized(const UNormalizer2 *norm2,
44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    const UChar *s, int32_t length,
44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    UErrorCode *pErrorCode) {
44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*pErrorCode)) {
44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
44727f654740f2a26ad62a5c155af9199af9e69b889claireho    if((s==NULL && length!=0) || length<-1) {
44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString sString(length<0, s, length);
45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return ((const Normalizer2 *)norm2)->isNormalized(sString, *pErrorCode);
45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UNormalizationCheckResult U_EXPORT2
45650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_quickCheck(const UNormalizer2 *norm2,
45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                  const UChar *s, int32_t length,
45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                  UErrorCode *pErrorCode) {
45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*pErrorCode)) {
46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return UNORM_NO;
46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
46227f654740f2a26ad62a5c155af9199af9e69b889claireho    if((s==NULL && length!=0) || length<-1) {
46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return UNORM_NO;
46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString sString(length<0, s, length);
46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return ((const Normalizer2 *)norm2)->quickCheck(sString, *pErrorCode);
46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
47054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI int32_t U_EXPORT2
47150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_spanQuickCheckYes(const UNormalizer2 *norm2,
47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         const UChar *s, int32_t length,
47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         UErrorCode *pErrorCode) {
47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(U_FAILURE(*pErrorCode)) {
47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
47727f654740f2a26ad62a5c155af9199af9e69b889claireho    if((s==NULL && length!=0) || length<-1) {
47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        return 0;
48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UnicodeString sString(length<0, s, length);
48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return ((const Normalizer2 *)norm2)->spanQuickCheckYes(sString, *pErrorCode);
48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
48554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UBool U_EXPORT2
48650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_hasBoundaryBefore(const UNormalizer2 *norm2, UChar32 c) {
48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return ((const Normalizer2 *)norm2)->hasBoundaryBefore(c);
48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UBool U_EXPORT2
49150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_hasBoundaryAfter(const UNormalizer2 *norm2, UChar32 c) {
49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return ((const Normalizer2 *)norm2)->hasBoundaryAfter(c);
49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
49554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UBool U_EXPORT2
49650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehounorm2_isInert(const UNormalizer2 *norm2, UChar32 c) {
49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return ((const Normalizer2 *)norm2)->isInert(c);
49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Some properties APIs ---------------------------------------------------- ***
50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
502103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI uint8_t U_EXPORT2
503103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusu_getCombiningClass(UChar32 c) {
504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UErrorCode errorCode=U_ZERO_ERROR;
505f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Normalizer2 *nfd=Normalizer2::getNFDInstance(errorCode);
506103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(U_SUCCESS(errorCode)) {
507103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return nfd->getCombiningClass(c);
508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    } else {
509103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return 0;
510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
513103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CFUNC uint16_t
514103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusunorm_getFCD16(UChar32 c) {
515103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UErrorCode errorCode=U_ZERO_ERROR;
516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if(U_SUCCESS(errorCode)) {
518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return impl->getFCD16(c);
51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    } else {
520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return 0;
52150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif  // !UCONFIG_NO_NORMALIZATION
525