1/*
2***********************************************************************
3* Copyright (C) 2016 and later: Unicode, Inc. and others.
4* License & terms of use: http://www.unicode.org/copyright.html#License
5***********************************************************************
6***********************************************************************
7* Copyright (c) 2002-2011, International Business Machines
8* Corporation and others.  All Rights Reserved.
9***********************************************************************
10***********************************************************************
11*/
12#ifndef _NORMPERF_H
13#define _NORMPERF_H
14
15#include "unicode/unorm.h"
16#include "unicode/ustring.h"
17
18#include "unicode/uperf.h"
19#include <stdlib.h>
20
21//  Stubs for Windows API functions when building on UNIXes.
22//
23#if U_PLATFORM_USES_ONLY_WIN32_API
24// do nothing
25#else
26#define _UNICODE
27typedef int DWORD;
28inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
29#endif
30
31#define DEST_BUFFER_CAPACITY 6000
32typedef int32_t (*NormFn)(const UChar* src,int32_t srcLen, UChar* dest,int32_t dstLen, int32_t options, UErrorCode* status);
33typedef int32_t (*QuickCheckFn)(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status);
34
35class QuickCheckPerfFunction : public UPerfFunction{
36private:
37    ULine* lines;
38    int32_t numLines;
39    QuickCheckFn fn;
40    UNormalizationMode mode;
41    int32_t retVal;
42    UBool uselen;
43    const UChar* src;
44    int32_t srcLen;
45    UBool line_mode;
46    int32_t options;
47
48public:
49    virtual void call(UErrorCode* status){
50        if(line_mode==TRUE){
51            if(uselen){
52                for(int32_t i = 0; i< numLines; i++){
53                    retVal =  (*fn)(lines[i].name,lines[i].len,mode, options, status);
54                }
55            }else{
56                for(int32_t i = 0; i< numLines; i++){
57                    retVal =  (*fn)(lines[i].name,-1,mode, options, status);
58                }
59            }
60        }else{
61            if(uselen){
62
63                retVal =  (*fn)(src,srcLen,mode, options, status);
64            }else{
65                retVal =  (*fn)(src,-1,mode, options, status);
66            }
67        }
68
69    }
70    virtual long getOperationsPerIteration(){
71        if(line_mode==TRUE){
72            int32_t totalChars=0;
73            for(int32_t i =0; i< numLines; i++){
74                totalChars+= lines[i].len;
75            }
76            return totalChars;
77        }else{
78            return srcLen;
79        }
80    }
81    QuickCheckPerfFunction(QuickCheckFn func, ULine* srcLines,int32_t srcNumLines, UNormalizationMode _mode, int32_t opts, UBool _uselen) : options(opts) {
82        fn = func;
83        lines = srcLines;
84        numLines = srcNumLines;
85        uselen = _uselen;
86        mode = _mode;
87        src = NULL;
88        srcLen = 0;
89        line_mode = TRUE;
90    }
91    QuickCheckPerfFunction(QuickCheckFn func, const UChar* source,int32_t sourceLen, UNormalizationMode _mode, int32_t opts, UBool _uselen) : options(opts) {
92        fn = func;
93        lines = NULL;
94        numLines = 0;
95        uselen = _uselen;
96        mode = _mode;
97        src = source;
98        srcLen = sourceLen;
99        line_mode = FALSE;
100    }
101};
102
103
104class NormPerfFunction : public UPerfFunction{
105private:
106    ULine* lines;
107    int32_t numLines;
108    UChar dest[DEST_BUFFER_CAPACITY];
109    UChar* pDest;
110    int32_t destLen;
111    NormFn fn;
112    int32_t retVal;
113    UBool uselen;
114    const UChar* src;
115    int32_t srcLen;
116    UBool line_mode;
117    int32_t options;
118
119public:
120    virtual void call(UErrorCode* status){
121        if(line_mode==TRUE){
122            if(uselen){
123                for(int32_t i = 0; i< numLines; i++){
124                    retVal =  (*fn)(lines[i].name,lines[i].len,pDest,destLen, options, status);
125                }
126            }else{
127                for(int32_t i = 0; i< numLines; i++){
128                    retVal =  (*fn)(lines[i].name,-1,pDest,destLen, options, status);
129                }
130            }
131        }else{
132            if(uselen){
133                retVal =  (*fn)(src,srcLen,pDest,destLen, options, status);
134            }else{
135                retVal =  (*fn)(src,-1,pDest,destLen, options, status);
136            }
137        }
138    }
139    virtual long getOperationsPerIteration(){
140        if(line_mode ==TRUE){
141            int32_t totalChars=0;
142            for(int32_t i =0; i< numLines; i++){
143                totalChars+= lines[i].len;
144            }
145            return totalChars;
146        }else{
147            return srcLen;
148        }
149    }
150    NormPerfFunction(NormFn func, int32_t opts, ULine* srcLines,int32_t srcNumLines,UBool _uselen) : options(opts) {
151        fn = func;
152        lines = srcLines;
153        numLines = srcNumLines;
154        uselen = _uselen;
155        destLen = DEST_BUFFER_CAPACITY;
156        pDest = dest;
157        src = NULL;
158        srcLen = 0;
159        line_mode = TRUE;
160    }
161    NormPerfFunction(NormFn func, int32_t opts, const UChar* source,int32_t sourceLen,UBool _uselen) : options(opts) {
162        fn = func;
163        lines = NULL;
164        numLines = 0;
165        uselen = _uselen;
166        destLen = sourceLen*3;
167        pDest = (UChar*) malloc(destLen * U_SIZEOF_UCHAR);
168        src = source;
169        srcLen = sourceLen;
170        line_mode = FALSE;
171    }
172    ~NormPerfFunction(){
173        if(dest != pDest){
174            free(pDest);
175        }
176    }
177};
178
179
180
181class  NormalizerPerformanceTest : public UPerfTest{
182private:
183    ULine* NFDFileLines;
184    ULine* NFCFileLines;
185    UChar* NFDBuffer;
186    UChar* NFCBuffer;
187    UChar* origBuffer;
188    int32_t origBufferLen;
189    int32_t NFDBufferLen;
190    int32_t NFCBufferLen;
191    int32_t options;
192
193    void normalizeInput(ULine* dest,const UChar* src ,int32_t srcLen,UNormalizationMode mode, int32_t options);
194    UChar* normalizeInput(int32_t& len, const UChar* src ,int32_t srcLen,UNormalizationMode mode, int32_t options);
195
196public:
197
198    NormalizerPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status);
199    ~NormalizerPerformanceTest();
200    virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par = NULL);
201    /* NFC performance */
202    UPerfFunction* TestICU_NFC_NFD_Text();
203    UPerfFunction* TestICU_NFC_NFC_Text();
204    UPerfFunction* TestICU_NFC_Orig_Text();
205
206    /* NFD performance */
207    UPerfFunction* TestICU_NFD_NFD_Text();
208    UPerfFunction* TestICU_NFD_NFC_Text();
209    UPerfFunction* TestICU_NFD_Orig_Text();
210
211    /* FCD performance */
212    UPerfFunction* TestICU_FCD_NFD_Text();
213    UPerfFunction* TestICU_FCD_NFC_Text();
214    UPerfFunction* TestICU_FCD_Orig_Text();
215
216    /*Win NFC performance */
217    UPerfFunction* TestWin_NFC_NFD_Text();
218    UPerfFunction* TestWin_NFC_NFC_Text();
219    UPerfFunction* TestWin_NFC_Orig_Text();
220
221    /* Win NFD performance */
222    UPerfFunction* TestWin_NFD_NFD_Text();
223    UPerfFunction* TestWin_NFD_NFC_Text();
224    UPerfFunction* TestWin_NFD_Orig_Text();
225
226    /* Quick check performance */
227    UPerfFunction* TestQC_NFC_NFD_Text();
228    UPerfFunction* TestQC_NFC_NFC_Text();
229    UPerfFunction* TestQC_NFC_Orig_Text();
230
231    UPerfFunction* TestQC_NFD_NFD_Text();
232    UPerfFunction* TestQC_NFD_NFC_Text();
233    UPerfFunction* TestQC_NFD_Orig_Text();
234
235    UPerfFunction* TestQC_FCD_NFD_Text();
236    UPerfFunction* TestQC_FCD_NFC_Text();
237    UPerfFunction* TestQC_FCD_Orig_Text();
238
239    /* IsNormalized performnace */
240    UPerfFunction* TestIsNormalized_NFC_NFD_Text();
241    UPerfFunction* TestIsNormalized_NFC_NFC_Text();
242    UPerfFunction* TestIsNormalized_NFC_Orig_Text();
243
244    UPerfFunction* TestIsNormalized_NFD_NFD_Text();
245    UPerfFunction* TestIsNormalized_NFD_NFC_Text();
246    UPerfFunction* TestIsNormalized_NFD_Orig_Text();
247
248    UPerfFunction* TestIsNormalized_FCD_NFD_Text();
249    UPerfFunction* TestIsNormalized_FCD_NFC_Text();
250    UPerfFunction* TestIsNormalized_FCD_Orig_Text();
251
252};
253
254//---------------------------------------------------------------------------------------
255// Platform / ICU version specific proto-types
256//---------------------------------------------------------------------------------------
257
258
259#if (U_ICU_VERSION_MAJOR_NUM > 1 ) || ((U_ICU_VERSION_MAJOR_NUM == 1 )&&(U_ICU_VERSION_MINOR_NUM > 8) && (U_ICU_VERSION_PATCHLEVEL_NUM >=1))
260
261int32_t ICUNormNFD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
262    return unorm_normalize(src,srcLen,UNORM_NFD, options,dest,dstLen,status);
263}
264
265int32_t ICUNormNFC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
266    return unorm_normalize(src,srcLen,UNORM_NFC, options,dest,dstLen,status);
267}
268
269int32_t ICUNormNFKD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
270    return unorm_normalize(src,srcLen,UNORM_NFKD, options,dest,dstLen,status);
271}
272int32_t ICUNormNFKC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
273    return unorm_normalize(src,srcLen,UNORM_NFKC, options,dest,dstLen,status);
274}
275
276int32_t ICUNormFCD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
277    return unorm_normalize(src,srcLen,UNORM_FCD, options,dest,dstLen,status);
278}
279
280int32_t ICUQuickCheck(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
281#if (U_ICU_VERSION_MAJOR_NUM > 2 ) || ((U_ICU_VERSION_MAJOR_NUM == 2 )&&(U_ICU_VERSION_MINOR_NUM >= 6))
282    return unorm_quickCheckWithOptions(src,srcLen,mode, options, status);
283#else
284    return unorm_quickCheck(src,srcLen,mode,status);
285#endif
286}
287int32_t ICUIsNormalized(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
288    return unorm_isNormalized(src,srcLen,mode,status);
289}
290
291
292#else
293
294int32_t ICUNormNFD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
295    return unorm_normalize(src,srcLen,UCOL_DECOMP_CAN, options,dest,dstLen,status);
296}
297
298int32_t ICUNormNFC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
299    return unorm_normalize(src,srcLen,UCOL_COMPOSE_CAN, options,dest,dstLen,status);
300}
301
302int32_t ICUNormNFKD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
303    return unorm_normalize(src,srcLen,UCOL_DECOMP_COMPAT, options,dest,dstLen,status);
304}
305int32_t ICUNormNFKC(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
306    return unorm_normalize(src,srcLen,UCOL_COMPOSE_COMPAT, options,dest,dstLen,status);
307}
308
309int32_t ICUNormFCD(const UChar* src, int32_t srcLen,UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
310    return unorm_normalize(src,srcLen,UNORM_FCD, options,dest,dstLen,status);
311}
312
313int32_t ICUQuickCheck(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
314    return unorm_quickCheck(src,srcLen,mode,status);
315}
316
317int32_t ICUIsNormalized(const UChar* src,int32_t srcLen, UNormalizationMode mode, int32_t options, UErrorCode* status){
318    return 0;
319}
320#endif
321
322#if U_PLATFORM_HAS_WIN32_API
323
324int32_t WinNormNFD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
325    return FoldStringW(MAP_COMPOSITE,src,srcLen,dest,dstLen);
326}
327
328int32_t WinNormNFC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
329    return FoldStringW(MAP_PRECOMPOSED,src,srcLen,dest,dstLen);
330}
331
332int32_t WinNormNFKD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
333    return FoldStringW(MAP_COMPOSITE+MAP_FOLDCZONE,src,srcLen,dest,dstLen);
334}
335int32_t WinNormNFKC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
336    return FoldStringW(MAP_FOLDCZONE,src,srcLen,dest,dstLen);
337}
338#else
339int32_t WinNormNFD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
340    return 0 ;
341}
342
343int32_t WinNormNFC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
344    return 0;
345}
346
347int32_t WinNormNFKD(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
348    return 0;
349}
350int32_t WinNormNFKC(const UChar* src, int32_t srcLen, UChar* dest, int32_t dstLen, int32_t options, UErrorCode* status) {
351    return 0;
352}
353#endif
354
355
356#endif // NORMPERF_H
357
358