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-2016, International Business Machines
8* Corporation and others.  All Rights Reserved.
9***********************************************************************
10***********************************************************************
11*/
12/**
13 * This Program tests the performance of ICU's Normalization engine against Windows
14 * to run it use the command like
15 *
16 * c:\normperf.exe -s C:\work\ICUCupertinoRep\icu4c\collation-perf-data  -i 10 -p 15 -f TestNames_Asian.txt -u -e UTF-8  -l
17 */
18#include "normperf.h"
19#include "uoptions.h"
20#include "cmemory.h" // for UPRV_LENGTHOF
21#include <stdio.h>
22
23UPerfFunction* NormalizerPerformanceTest::runIndexedTest(int32_t index, UBool exec,const char* &name, char* par) {
24    switch (index) {
25        TESTCASE(0,TestICU_NFC_NFD_Text);
26        TESTCASE(1,TestICU_NFC_NFC_Text);
27        TESTCASE(2,TestICU_NFC_Orig_Text);
28
29        TESTCASE(3,TestICU_NFD_NFD_Text);
30        TESTCASE(4,TestICU_NFD_NFC_Text);
31        TESTCASE(5,TestICU_NFD_Orig_Text);
32
33        TESTCASE(6,TestICU_FCD_NFD_Text);
34        TESTCASE(7,TestICU_FCD_NFC_Text);
35        TESTCASE(8,TestICU_FCD_Orig_Text);
36
37        TESTCASE(9,TestWin_NFC_NFD_Text);
38        TESTCASE(10,TestWin_NFC_NFC_Text);
39        TESTCASE(11,TestWin_NFC_Orig_Text);
40
41        TESTCASE(12,TestWin_NFD_NFD_Text);
42        TESTCASE(13,TestWin_NFD_NFC_Text);
43        TESTCASE(14,TestWin_NFD_Orig_Text);
44
45        TESTCASE(15,TestQC_NFC_NFD_Text);
46        TESTCASE(16,TestQC_NFC_NFC_Text);
47        TESTCASE(17,TestQC_NFC_Orig_Text);
48
49        TESTCASE(18,TestQC_NFD_NFD_Text);
50        TESTCASE(19,TestQC_NFD_NFC_Text);
51        TESTCASE(20,TestQC_NFD_Orig_Text);
52
53        TESTCASE(21,TestQC_FCD_NFD_Text);
54        TESTCASE(22,TestQC_FCD_NFC_Text);
55        TESTCASE(23,TestQC_FCD_Orig_Text);
56
57        TESTCASE(24,TestIsNormalized_NFC_NFD_Text);
58        TESTCASE(25,TestIsNormalized_NFC_NFC_Text);
59        TESTCASE(26,TestIsNormalized_NFC_Orig_Text);
60
61        TESTCASE(27,TestIsNormalized_NFD_NFD_Text);
62        TESTCASE(28,TestIsNormalized_NFD_NFC_Text);
63        TESTCASE(29,TestIsNormalized_NFD_Orig_Text);
64
65        TESTCASE(30,TestIsNormalized_FCD_NFD_Text);
66        TESTCASE(31,TestIsNormalized_FCD_NFC_Text);
67        TESTCASE(32,TestIsNormalized_FCD_Orig_Text);
68
69        default:
70            name = "";
71            return NULL;
72    }
73    return NULL;
74
75}
76
77void NormalizerPerformanceTest::normalizeInput(ULine* dest,const UChar* src ,int32_t srcLen,UNormalizationMode mode, int32_t options){
78    int32_t reqLen = 0;
79    UErrorCode status = U_ZERO_ERROR;
80    for(;;){
81        /* pure pre-flight */
82        reqLen=unorm_normalize(src,srcLen,mode, options,NULL,0,&status);
83        if(status==U_BUFFER_OVERFLOW_ERROR){
84            status=U_ZERO_ERROR;
85            dest->name = new UChar[reqLen+1];
86            reqLen= unorm_normalize(src,srcLen,mode, options,dest->name,reqLen+1,&status);
87            dest->len=reqLen;
88            break;
89        }else if(U_FAILURE(status)){
90            printf("Could not normalize input. Error: %s", u_errorName(status));
91        }
92    }
93}
94UChar* NormalizerPerformanceTest::normalizeInput(int32_t& len, const UChar* src ,int32_t srcLen,UNormalizationMode mode, int32_t options){
95    int32_t reqLen = 0;
96    UErrorCode status = U_ZERO_ERROR;
97    UChar* dest = NULL;
98    for(;;){
99        /* pure pre-flight */
100        reqLen=unorm_normalize(src,srcLen,mode, options,NULL,0,&status);
101        if(status==U_BUFFER_OVERFLOW_ERROR){
102            status=U_ZERO_ERROR;
103            dest = new UChar[reqLen+1];
104            reqLen= unorm_normalize(src,srcLen,mode, options,dest,reqLen+1,&status);
105            len=reqLen;
106            break;
107        }else if(U_FAILURE(status)){
108            printf("Could not normalize input. Error: %s", u_errorName(status));
109            return NULL;
110        }
111    }
112    return dest;
113}
114
115static UOption cmdLineOptions[]={
116    UOPTION_DEF("options", 'o', UOPT_OPTIONAL_ARG)
117};
118
119NormalizerPerformanceTest::NormalizerPerformanceTest(int32_t argc, const char* argv[], UErrorCode& status)
120: UPerfTest(argc,argv,status), options(0) {
121    NFDBuffer = NULL;
122    NFCBuffer = NULL;
123    NFDBufferLen = 0;
124    NFCBufferLen = 0;
125    NFDFileLines = NULL;
126    NFCFileLines = NULL;
127
128    if(status== U_ILLEGAL_ARGUMENT_ERROR){
129       fprintf(stderr,gUsageString, "normperf");
130       return;
131    }
132
133    if(U_FAILURE(status)){
134        fprintf(stderr, "FAILED to create UPerfTest object. Error: %s\n", u_errorName(status));
135        return;
136    }
137
138    _remainingArgc = u_parseArgs(_remainingArgc, (char **)argv, UPRV_LENGTHOF(cmdLineOptions), cmdLineOptions);
139    if(cmdLineOptions[0].doesOccur && cmdLineOptions[0].value!=NULL) {
140        options=(int32_t)strtol(cmdLineOptions[0].value, NULL, 16);
141    }
142
143    if(line_mode){
144        ULine* filelines = getLines(status);
145        if(U_FAILURE(status)){
146            fprintf(stderr, "FAILED to read lines from file and create UPerfTest object. Error: %s\n", u_errorName(status));
147            return;
148        }
149        NFDFileLines = new ULine[numLines];
150        NFCFileLines = new ULine[numLines];
151
152        for(int32_t i=0;i<numLines;i++){
153            normalizeInput(&NFDFileLines[i],filelines[i].name,filelines[i].len,UNORM_NFD, options);
154            normalizeInput(&NFCFileLines[i],filelines[i].name,filelines[i].len,UNORM_NFC, options);
155
156        }
157    }else if(bulk_mode){
158        int32_t srcLen = 0;
159        const UChar* src = getBuffer(srcLen,status);
160        NFDBufferLen = 0;
161        NFCBufferLen = 0;
162
163        if(U_FAILURE(status)){
164            fprintf(stderr, "FAILED to read buffer from file and create UPerfTest object. Error: %s\n", u_errorName(status));
165            return;
166        }
167
168        NFDBuffer = normalizeInput(NFDBufferLen,src,srcLen,UNORM_NFD, options);
169        NFCBuffer = normalizeInput(NFCBufferLen,src,srcLen,UNORM_NFC, options);
170    }
171
172}
173
174NormalizerPerformanceTest::~NormalizerPerformanceTest(){
175    delete[] NFDFileLines;
176    delete[] NFCFileLines;
177    delete[] NFDBuffer;
178    delete[] NFCBuffer;
179}
180
181// Test NFC Performance
182UPerfFunction* NormalizerPerformanceTest::TestICU_NFC_NFD_Text(){
183    if(line_mode){
184        NormPerfFunction* func= new NormPerfFunction(ICUNormNFC, options,NFDFileLines,numLines, uselen);
185        return func;
186    }else{
187        NormPerfFunction* func= new NormPerfFunction(ICUNormNFC, options,NFDBuffer, NFDBufferLen, uselen);
188        return func;
189    }
190}
191UPerfFunction* NormalizerPerformanceTest::TestICU_NFC_NFC_Text(){
192    if(line_mode){
193        NormPerfFunction* func = new NormPerfFunction(ICUNormNFC, options,NFCFileLines,numLines, uselen);
194        return func;
195    }else{
196        NormPerfFunction* func= new NormPerfFunction(ICUNormNFC, options,NFCBuffer, NFCBufferLen, uselen);
197        return func;
198    }
199}
200UPerfFunction* NormalizerPerformanceTest::TestICU_NFC_Orig_Text(){
201    if(line_mode){
202        NormPerfFunction* func = new NormPerfFunction(ICUNormNFC, options,lines,numLines, uselen);
203        return func;
204    }else{
205        NormPerfFunction* func = new NormPerfFunction(ICUNormNFC, options,buffer, bufferLen, uselen);
206        return func;
207    }
208}
209
210// Test NFD Performance
211UPerfFunction* NormalizerPerformanceTest::TestICU_NFD_NFD_Text(){
212    if(line_mode){
213        NormPerfFunction* func = new NormPerfFunction(ICUNormNFD, options,NFDFileLines,numLines, uselen);
214        return func;
215    }else{
216        NormPerfFunction* func = new NormPerfFunction(ICUNormNFD, options,NFDBuffer,NFDBufferLen, uselen);
217        return func;
218    }
219}
220UPerfFunction* NormalizerPerformanceTest::TestICU_NFD_NFC_Text(){
221    if(line_mode){
222        NormPerfFunction* func = new NormPerfFunction(ICUNormNFD, options,NFCFileLines,numLines, uselen);
223        return func;
224    }else{
225        NormPerfFunction* func = new NormPerfFunction(ICUNormNFD, options,NFCBuffer,NFCBufferLen, uselen);
226        return func;
227    }
228}
229UPerfFunction* NormalizerPerformanceTest::TestICU_NFD_Orig_Text(){
230    if(line_mode){
231        NormPerfFunction* func = new NormPerfFunction(ICUNormNFD, options,lines,numLines, uselen);
232        return func;
233    }else{
234        NormPerfFunction* func = new NormPerfFunction(ICUNormNFD, options,buffer,bufferLen, uselen);
235        return func;
236    }
237}
238
239// Test FCD Performance
240UPerfFunction* NormalizerPerformanceTest::TestICU_FCD_NFD_Text(){
241    if(line_mode){
242        NormPerfFunction* func = new NormPerfFunction(ICUNormFCD, options,NFDFileLines,numLines, uselen);
243        return func;
244    }else{
245        NormPerfFunction* func = new NormPerfFunction(ICUNormFCD, options,NFDBuffer,NFDBufferLen, uselen);
246        return func;
247    }
248
249}
250UPerfFunction* NormalizerPerformanceTest::TestICU_FCD_NFC_Text(){
251    if(line_mode){
252        NormPerfFunction* func = new NormPerfFunction(ICUNormFCD, options,NFCFileLines,numLines, uselen);
253        return func;
254    }else{
255        NormPerfFunction* func = new NormPerfFunction(ICUNormFCD, options,NFCBuffer,NFCBufferLen, uselen);
256        return func;
257    }
258}
259UPerfFunction* NormalizerPerformanceTest::TestICU_FCD_Orig_Text(){
260    if(line_mode){
261        NormPerfFunction* func = new NormPerfFunction(ICUNormFCD, options,lines,numLines, uselen);
262        return func;
263    }else{
264        NormPerfFunction* func = new NormPerfFunction(ICUNormFCD, options,buffer,bufferLen, uselen);
265        return func;
266    }
267}
268
269// Test Win NFC Performance
270UPerfFunction* NormalizerPerformanceTest::TestWin_NFC_NFD_Text(){
271    if(line_mode){
272        NormPerfFunction* func = new NormPerfFunction(WinNormNFC, options,NFDFileLines,numLines, uselen);
273        return func;
274    }else{
275        NormPerfFunction* func = new NormPerfFunction(WinNormNFC, options,NFDBuffer,NFDBufferLen, uselen);
276        return func;
277    }
278}
279UPerfFunction* NormalizerPerformanceTest::TestWin_NFC_NFC_Text(){
280    if(line_mode){
281        NormPerfFunction* func = new NormPerfFunction(WinNormNFC, options,NFCFileLines,numLines, uselen);
282        return func;
283    }else{
284        NormPerfFunction* func = new NormPerfFunction(WinNormNFC, options,NFCBuffer,NFCBufferLen, uselen);
285        return func;
286    }
287}
288UPerfFunction* NormalizerPerformanceTest::TestWin_NFC_Orig_Text(){
289    if(line_mode){
290        NormPerfFunction* func = new NormPerfFunction(WinNormNFC, options,lines,numLines, uselen);
291        return func;
292    }else{
293        NormPerfFunction* func = new NormPerfFunction(WinNormNFC, options,buffer,bufferLen, uselen);
294        return func;
295    }
296}
297
298// Test Win NFD Performance
299UPerfFunction* NormalizerPerformanceTest::TestWin_NFD_NFD_Text(){
300    if(line_mode){
301        NormPerfFunction* func = new NormPerfFunction(WinNormNFD, options,NFDFileLines,numLines, uselen);
302        return func;
303    }else{
304        NormPerfFunction* func = new NormPerfFunction(WinNormNFD, options,NFDBuffer,NFDBufferLen, uselen);
305        return func;
306    }
307}
308UPerfFunction* NormalizerPerformanceTest::TestWin_NFD_NFC_Text(){
309    if(line_mode){
310        NormPerfFunction* func = new NormPerfFunction(WinNormNFD, options,NFCFileLines,numLines, uselen);
311        return func;
312    }else{
313        NormPerfFunction* func = new NormPerfFunction(WinNormNFD, options,NFCBuffer,NFCBufferLen, uselen);
314        return func;
315    }
316}
317UPerfFunction* NormalizerPerformanceTest::TestWin_NFD_Orig_Text(){
318    if(line_mode){
319        NormPerfFunction* func = new NormPerfFunction(WinNormNFD, options,lines,numLines, uselen);
320        return func;
321    }else{
322        NormPerfFunction* func = new NormPerfFunction(WinNormNFD, options,buffer,bufferLen, uselen);
323        return func;
324    }
325}
326
327// Test Quick Check Performance
328UPerfFunction* NormalizerPerformanceTest::TestQC_NFC_NFD_Text(){
329    if(line_mode){
330        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFDFileLines, numLines, UNORM_NFC, options,uselen);
331        return func;
332    }else{
333        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFDBuffer, NFDBufferLen, UNORM_NFC, options,uselen);
334        return func;
335    }
336}
337UPerfFunction* NormalizerPerformanceTest::TestQC_NFC_NFC_Text(){
338    if(line_mode){
339        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFCFileLines, numLines, UNORM_NFC, options,uselen);
340        return func;
341    }else{
342        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFCBuffer, NFCBufferLen, UNORM_NFC, options,uselen);
343        return func;
344    }
345}
346UPerfFunction* NormalizerPerformanceTest::TestQC_NFC_Orig_Text(){
347    if(line_mode){
348        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,lines, numLines, UNORM_NFC, options,uselen);
349        return func;
350    }else{
351        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,buffer, bufferLen, UNORM_NFC, options,uselen);
352        return func;
353    }
354}
355
356UPerfFunction* NormalizerPerformanceTest::TestQC_NFD_NFD_Text(){
357    if(line_mode){
358        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFDFileLines, numLines, UNORM_NFD, options,uselen);
359        return func;
360    }else{
361        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFDBuffer, NFDBufferLen, UNORM_NFD, options,uselen);
362        return func;
363    }
364}
365UPerfFunction* NormalizerPerformanceTest::TestQC_NFD_NFC_Text(){
366    if(line_mode){
367        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFCFileLines, numLines, UNORM_NFD, options,uselen);
368        return func;
369    }else{
370        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFCBuffer, NFCBufferLen, UNORM_NFD, options,uselen);
371        return func;
372    }
373}
374UPerfFunction* NormalizerPerformanceTest::TestQC_NFD_Orig_Text(){
375    if(line_mode){
376        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,lines, numLines, UNORM_NFD, options,uselen);
377        return func;
378    }else{
379        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,buffer, bufferLen, UNORM_NFD, options,uselen);
380        return func;
381    }
382}
383
384UPerfFunction* NormalizerPerformanceTest::TestQC_FCD_NFD_Text(){
385    if(line_mode){
386        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFDFileLines, numLines, UNORM_FCD, options,uselen);
387        return func;
388    }else{
389        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFDBuffer, NFDBufferLen, UNORM_FCD, options,uselen);
390        return func;
391    }
392}
393UPerfFunction* NormalizerPerformanceTest::TestQC_FCD_NFC_Text(){
394    if(line_mode){
395        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFCFileLines, numLines, UNORM_FCD, options,uselen);
396        return func;
397    }else{
398        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,NFCBuffer, NFCBufferLen, UNORM_FCD, options,uselen);
399        return func;
400    }
401}
402UPerfFunction* NormalizerPerformanceTest::TestQC_FCD_Orig_Text(){
403    if(line_mode){
404        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,lines, numLines, UNORM_FCD, options,uselen);
405        return func;
406    }else{
407        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUQuickCheck,buffer, bufferLen, UNORM_FCD, options,uselen);
408        return func;
409    }
410}
411
412// Test isNormalized Performance
413UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_NFC_NFD_Text(){
414    if(line_mode){
415        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFDFileLines, numLines, UNORM_NFC, options,uselen);
416        return func;
417    }else{
418        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFDBuffer, NFDBufferLen, UNORM_NFC, options,uselen);
419        return func;
420    }
421}
422UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_NFC_NFC_Text(){
423    if(line_mode){
424        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFCFileLines, numLines, UNORM_NFC, options,uselen);
425        return func;
426    }else{
427        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFCBuffer, NFCBufferLen, UNORM_NFC, options,uselen);
428        return func;
429    }
430}
431UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_NFC_Orig_Text(){
432    if(line_mode){
433        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,lines, numLines, UNORM_NFC, options,uselen);
434        return func;
435    }else{
436        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,buffer, bufferLen, UNORM_NFC, options,uselen);
437        return func;
438    }
439}
440
441UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_NFD_NFD_Text(){
442    if(line_mode){
443        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFDFileLines, numLines, UNORM_NFD, options,uselen);
444        return func;
445    }else{
446        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFDBuffer, NFDBufferLen, UNORM_NFD, options,uselen);
447        return func;
448    }
449}
450UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_NFD_NFC_Text(){
451    if(line_mode){
452        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFCFileLines, numLines, UNORM_NFD, options,uselen);
453        return func;
454    }else{
455        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFCBuffer, NFCBufferLen, UNORM_NFD, options,uselen);
456        return func;
457    }
458}
459UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_NFD_Orig_Text(){
460    if(line_mode){
461        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,lines, numLines, UNORM_NFD, options,uselen);
462        return func;
463    }else{
464        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,buffer, bufferLen, UNORM_NFD, options,uselen);
465        return func;
466    }
467}
468
469UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_FCD_NFD_Text(){
470    if(line_mode){
471        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFDFileLines, numLines, UNORM_FCD, options,uselen);
472        return func;
473    }else{
474        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFDBuffer, NFDBufferLen, UNORM_FCD, options,uselen);
475        return func;
476    }
477}
478UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_FCD_NFC_Text(){
479    if(line_mode){
480        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFCFileLines, numLines, UNORM_FCD, options,uselen);
481        return func;
482    }else{
483        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,NFCBuffer, NFCBufferLen, UNORM_FCD, options,uselen);
484        return func;
485    }
486}
487UPerfFunction* NormalizerPerformanceTest::TestIsNormalized_FCD_Orig_Text(){
488    if(line_mode){
489        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,lines, numLines, UNORM_FCD, options,uselen);
490        return func;
491    }else{
492        QuickCheckPerfFunction* func = new QuickCheckPerfFunction(ICUIsNormalized,buffer, bufferLen, UNORM_FCD, options,uselen);
493        return func;
494    }
495}
496
497int main(int argc, const char* argv[]){
498    UErrorCode status = U_ZERO_ERROR;
499    NormalizerPerformanceTest test(argc, argv, status);
500    if(U_FAILURE(status)){
501        return status;
502    }
503    if(test.run()==FALSE){
504        fprintf(stderr,"FAILED: Tests could not be run please check the arguments.\n");
505        return -1;
506    }
507    return 0;
508}
509