1f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius/*
2f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius*******************************************************************************
3f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* Copyright (C) 2014, International Business Machines
4f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* Corporation and others.  All Rights Reserved.
5f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius*******************************************************************************
6f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* loadednormalizer2impl.h
7f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius*
8f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* created on: 2014sep07
9f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius* created by: Markus W. Scherer
10f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius*/
11f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
12f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#ifndef __NORM2ALLMODES_H__
13f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#define __NORM2ALLMODES_H__
14f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
15f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/utypes.h"
16f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
17f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#if !UCONFIG_NO_NORMALIZATION
18f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
19f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/normalizer2.h"
20f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/unistr.h"
21f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "cpputils.h"
22f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "normalizer2impl.h"
23f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
24f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_BEGIN
25f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
26f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Intermediate class:
27f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Has Normalizer2Impl and does boilerplate argument checking and setup.
28f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass Normalizer2WithImpl : public Normalizer2 {
29f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic:
30f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    Normalizer2WithImpl(const Normalizer2Impl &ni) : impl(ni) {}
31f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual ~Normalizer2WithImpl();
32f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
33f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    // normalize
34f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UnicodeString &
35f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalize(const UnicodeString &src,
36f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius              UnicodeString &dest,
37f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius              UErrorCode &errorCode) const {
38f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
39f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            dest.setToBogus();
40f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return dest;
41f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
42f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *sArray=src.getBuffer();
43f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(&dest==&src || sArray==NULL) {
44f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
45f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            dest.setToBogus();
46f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return dest;
47f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
48f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        dest.remove();
49f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        ReorderingBuffer buffer(impl, dest);
50f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(buffer.init(src.length(), errorCode)) {
51f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            normalize(sArray, sArray+src.length(), buffer, errorCode);
52f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
53f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return dest;
54f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
55f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
56f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalize(const UChar *src, const UChar *limit,
57f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius              ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
58f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
59f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    // normalize and append
60f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UnicodeString &
61f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalizeSecondAndAppend(UnicodeString &first,
62f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                             const UnicodeString &second,
63f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                             UErrorCode &errorCode) const {
64f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return normalizeSecondAndAppend(first, second, TRUE, errorCode);
65f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
66f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UnicodeString &
67f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    append(UnicodeString &first,
68f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius           const UnicodeString &second,
69f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius           UErrorCode &errorCode) const {
70f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return normalizeSecondAndAppend(first, second, FALSE, errorCode);
71f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
72f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    UnicodeString &
73f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalizeSecondAndAppend(UnicodeString &first,
74f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                             const UnicodeString &second,
75f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                             UBool doNormalize,
76f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                             UErrorCode &errorCode) const {
77f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        uprv_checkCanGetBuffer(first, errorCode);
78f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
79f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return first;
80f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
81f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *secondArray=second.getBuffer();
82f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(&first==&second || secondArray==NULL) {
83f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
84f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return first;
85f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
86f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        int32_t firstLength=first.length();
87f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UnicodeString safeMiddle;
88f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        {
89f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            ReorderingBuffer buffer(impl, first);
90f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            if(buffer.init(firstLength+second.length(), errorCode)) {
91f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                normalizeAndAppend(secondArray, secondArray+second.length(), doNormalize,
92f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                                   safeMiddle, buffer, errorCode);
93f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            }
94f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }  // The ReorderingBuffer destructor finalizes the first string.
95f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
96f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            // Restore the modified suffix of the first string.
97f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            first.replace(firstLength-safeMiddle.length(), 0x7fffffff, safeMiddle);
98f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
99f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return first;
100f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
101f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
102f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
103f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       UnicodeString &safeMiddle,
104f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
105f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool
106f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    getDecomposition(UChar32 c, UnicodeString &decomposition) const {
107f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UChar buffer[4];
108f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        int32_t length;
109f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *d=impl.getDecomposition(c, buffer, length);
110f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(d==NULL) {
111f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
112f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
113f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(d==buffer) {
114f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            decomposition.setTo(buffer, length);  // copy the string (Jamos from Hangul syllable c)
115f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        } else {
116f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            decomposition.setTo(FALSE, d, length);  // read-only alias
117f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
118f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return TRUE;
119f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
120f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool
121f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    getRawDecomposition(UChar32 c, UnicodeString &decomposition) const {
122f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UChar buffer[30];
123f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        int32_t length;
124f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *d=impl.getRawDecomposition(c, buffer, length);
125f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(d==NULL) {
126f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
127f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
128f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(d==buffer) {
129f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            decomposition.setTo(buffer, length);  // copy the string (algorithmic decomposition)
130f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        } else {
131f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            decomposition.setTo(FALSE, d, length);  // read-only alias
132f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
133f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return TRUE;
134f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
135f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UChar32
136f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    composePair(UChar32 a, UChar32 b) const {
137f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.composePair(a, b);
138f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
139f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
140f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual uint8_t
141f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    getCombiningClass(UChar32 c) const {
142f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.getCC(impl.getNorm16(c));
143f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
144f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
145f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    // quick checks
146f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool
147f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
148f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
149f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
150f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
151f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *sArray=s.getBuffer();
152f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(sArray==NULL) {
153f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
154f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
155f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
156f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *sLimit=sArray+s.length();
157f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return sLimit==spanQuickCheckYes(sArray, sLimit, errorCode);
158f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
159f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UNormalizationCheckResult
160f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
161f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return Normalizer2WithImpl::isNormalized(s, errorCode) ? UNORM_YES : UNORM_NO;
162f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
163f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual int32_t
164f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const {
165f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
166f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return 0;
167f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
168f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *sArray=s.getBuffer();
169f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(sArray==NULL) {
170f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
171f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return 0;
172f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
173f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return (int32_t)(spanQuickCheckYes(sArray, sArray+s.length(), errorCode)-sArray);
174f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
175f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual const UChar *
176f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCode) const = 0;
177f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
178f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UNormalizationCheckResult getQuickCheck(UChar32) const {
179f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return UNORM_YES;
180f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
181f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
182f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const Normalizer2Impl &impl;
183f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius};
184f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
185f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass DecomposeNormalizer2 : public Normalizer2WithImpl {
186f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic:
187f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    DecomposeNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
188f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual ~DecomposeNormalizer2();
189f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
190f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprivate:
191f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
192f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalize(const UChar *src, const UChar *limit,
193f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
194f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.decompose(src, limit, &buffer, errorCode);
195f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
196f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
197f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
198f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
199f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       UnicodeString &safeMiddle,
200f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
201f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.decomposeAndAppend(src, limit, doNormalize, safeMiddle, buffer, errorCode);
202f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
203f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual const UChar *
204f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCode) const {
205f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.decompose(src, limit, NULL, errorCode);
206f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
207f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
208f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
209f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.isDecompYes(impl.getNorm16(c)) ? UNORM_YES : UNORM_NO;
210f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
211f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoundary(c, TRUE); }
212f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBoundary(c, FALSE); }
213f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool isInert(UChar32 c) const { return impl.isDecompInert(c); }
214f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius};
215f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
216f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass ComposeNormalizer2 : public Normalizer2WithImpl {
217f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic:
218f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    ComposeNormalizer2(const Normalizer2Impl &ni, UBool fcc) :
219f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        Normalizer2WithImpl(ni), onlyContiguous(fcc) {}
220f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual ~ComposeNormalizer2();
221f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
222f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprivate:
223f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
224f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalize(const UChar *src, const UChar *limit,
225f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
226f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.compose(src, limit, onlyContiguous, TRUE, buffer, errorCode);
227f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
228f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
229f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
230f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
231f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       UnicodeString &safeMiddle,
232f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
233f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.composeAndAppend(src, limit, doNormalize, onlyContiguous, safeMiddle, buffer, errorCode);
234f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
235f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
236f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool
237f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
238f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
239f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
240f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
241f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *sArray=s.getBuffer();
242f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(sArray==NULL) {
243f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
244f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
245f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
246f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UnicodeString temp;
247f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        ReorderingBuffer buffer(impl, temp);
248f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(!buffer.init(5, errorCode)) {  // small destCapacity for substring normalization
249f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return FALSE;
250f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
251f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.compose(sArray, sArray+s.length(), onlyContiguous, FALSE, buffer, errorCode);
252f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
253f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UNormalizationCheckResult
254f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
255f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(U_FAILURE(errorCode)) {
256f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return UNORM_MAYBE;
257f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
258f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        const UChar *sArray=s.getBuffer();
259f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if(sArray==NULL) {
260f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
261f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return UNORM_MAYBE;
262f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
263f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UNormalizationCheckResult qcResult=UNORM_YES;
264f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.composeQuickCheck(sArray, sArray+s.length(), onlyContiguous, &qcResult);
265f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return qcResult;
266f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
267f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual const UChar *
268f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &) const {
269f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.composeQuickCheck(src, limit, onlyContiguous, NULL);
270f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
271f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
272f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
273f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.getCompQuickCheck(impl.getNorm16(c));
274f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
275f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool hasBoundaryBefore(UChar32 c) const {
276f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.hasCompBoundaryBefore(c);
277f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
278f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool hasBoundaryAfter(UChar32 c) const {
279f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.hasCompBoundaryAfter(c, onlyContiguous, FALSE);
280f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
281f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool isInert(UChar32 c) const {
282f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.hasCompBoundaryAfter(c, onlyContiguous, TRUE);
283f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
284f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
285f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    const UBool onlyContiguous;
286f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius};
287f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
288f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass FCDNormalizer2 : public Normalizer2WithImpl {
289f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliuspublic:
290f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    FCDNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
291f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual ~FCDNormalizer2();
292f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
293f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusprivate:
294f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
295f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalize(const UChar *src, const UChar *limit,
296f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
297f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.makeFCD(src, limit, &buffer, errorCode);
298f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
299f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
300f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual void
301f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
302f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       UnicodeString &safeMiddle,
303f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
304f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        impl.makeFCDAndAppend(src, limit, doNormalize, safeMiddle, buffer, errorCode);
305f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
306f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual const UChar *
307f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCode) const {
308f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return impl.makeFCD(src, limit, NULL, errorCode);
309f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
310f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
311f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasFCDBoundaryBefore(c); }
312f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasFCDBoundaryAfter(c); }
313f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    virtual UBool isInert(UChar32 c) const { return impl.isFCDInert(c); }
314f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius};
315f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
316f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstruct Norm2AllModes : public UMemory {
317f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    Norm2AllModes(Normalizer2Impl *i)
318f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            : impl(i), comp(*i, FALSE), decomp(*i), fcd(*i), fcc(*i, TRUE) {}
319f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    ~Norm2AllModes();
320f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
321f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    static Norm2AllModes *createInstance(Normalizer2Impl *impl, UErrorCode &errorCode);
322f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    static Norm2AllModes *createNFCInstance(UErrorCode &errorCode);
323f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    static Norm2AllModes *createInstance(const char *packageName,
324f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                                         const char *name,
325f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                                         UErrorCode &errorCode);
326f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
327f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    static const Norm2AllModes *getNFCInstance(UErrorCode &errorCode);
328f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    static const Norm2AllModes *getNFKCInstance(UErrorCode &errorCode);
329f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    static const Norm2AllModes *getNFKC_CFInstance(UErrorCode &errorCode);
330f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
331f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    Normalizer2Impl *impl;
332f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    ComposeNormalizer2 comp;
333f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    DecomposeNormalizer2 decomp;
334f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    FCDNormalizer2 fcd;
335f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    ComposeNormalizer2 fcc;
336f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius};
337f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
338f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_END
339f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
340f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#endif  // !UCONFIG_NO_NORMALIZATION
341f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#endif  // __NORM2ALLMODES_H__
342