1/*
2**********************************************************************
3* Copyright (c) 2010-2011,International Business Machines
4* Corporation and others.  All Rights Reserved.
5**********************************************************************
6**********************************************************************
7*/
8
9#ifndef _DTFMTRTPERF_H
10#define _DTFMTRTPERF_H
11
12#include "unicode/utypes.h"
13#include "unicode/uperf.h"
14#include "unicode/timezone.h"
15#include "unicode/simpletz.h"
16#include "unicode/calendar.h"
17#include "unicode/strenum.h"
18#include "unicode/smpdtfmt.h"
19#include "unicode/uchar.h"
20#include "unicode/basictz.h"
21#include "cstring.h"
22
23#include "unicode/uperf.h"
24#include "unicode/unistr.h"
25#include "unicode/datefmt.h"
26#include "unicode/calendar.h"
27#include "unicode/uclean.h"
28#include "unicode/brkiter.h"
29#include "util.h"
30
31static const char* PATTERNS[] = {"z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV"};
32static const int NUM_PATTERNS = sizeof(PATTERNS)/sizeof(const char*);
33
34#include <iostream>
35#include <stdlib.h>
36#include <fstream>
37#include <string>
38using namespace std;
39
40//  Stubs for Windows API functions when building on UNIXes.
41//
42#if U_PLATFORM_USES_ONLY_WIN32_API
43// do nothing
44#else
45#define _UNICODE
46typedef int DWORD;
47inline int FoldStringW(DWORD dwMapFlags, const UChar* lpSrcStr,int cchSrc, UChar* lpDestStr,int cchDest);
48#endif
49
50class DateTimeRoundTripFunction : public UPerfFunction
51{
52private:
53	int nLocales;
54public:
55
56	DateTimeRoundTripFunction()
57	{
58		nLocales = 0;
59	}
60
61	DateTimeRoundTripFunction(int locs)
62	{
63		nLocales = locs;
64	}
65
66	virtual void call(UErrorCode* status)
67	{
68        *status = U_ZERO_ERROR;
69
70        SimpleTimeZone unknownZone(-31415, (UnicodeString)"Etc/Unknown");
71        int32_t badDstOffset = -1234;
72        int32_t badZoneOffset = -2345;
73
74        int32_t testDateData[][3] = {
75            {2007, 1, 15},
76            {2007, 6, 15},
77            {1990, 1, 15},
78            {1990, 6, 15},
79            {1960, 1, 15},
80            {1960, 6, 15},
81        };
82
83        Calendar *cal = Calendar::createInstance(*status);
84        if (U_FAILURE(*status)) {
85            //dataerrln("Calendar::createInstance failed: %s", u_errorName(*status));
86            return;
87        }
88
89        // Set up rule equivalency test range
90        UDate low, high;
91        cal->set(1900, UCAL_JANUARY, 1);
92        low = cal->getTime(*status);
93        cal->set(2040, UCAL_JANUARY, 1);
94        high = cal->getTime(*status);
95        if (U_FAILURE(*status)) {
96            //errln("getTime failed");
97            return;
98        }
99
100        // Set up test dates
101        UDate DATES[(sizeof(testDateData)/sizeof(int32_t))/3];
102        const int32_t nDates = (sizeof(testDateData)/sizeof(int32_t))/3;
103        cal->clear();
104        for (int32_t i = 0; i < nDates; i++) {
105            cal->set(testDateData[i][0], testDateData[i][1], testDateData[i][2]);
106            DATES[i] = cal->getTime(*status);
107            if (U_FAILURE(*status)) {
108                //errln("getTime failed");
109                return;
110            }
111        }
112
113        // Set up test locales
114        const Locale testLocales[] = {
115            Locale("en"),
116            Locale("en_US"),
117            Locale("en_AU"),
118            Locale("de_DE"),
119            Locale("fr"),
120            Locale("ja_JP"),
121            Locale("ko"),
122            Locale("pt"),
123            Locale("th_TH"),
124            Locale("zh_Hans"),
125
126            Locale("it"),
127
128            Locale("en"),
129            Locale("en_US"),
130            Locale("en_AU"),
131            Locale("de_DE"),
132            Locale("fr"),
133            Locale("ja_JP"),
134            Locale("ko"),
135            Locale("pt"),
136            Locale("th_TH"),
137            Locale("zh_Hans"),
138        };
139
140        const Locale *LOCALES;
141        LOCALES = testLocales;
142
143        StringEnumeration *tzids = TimeZone::createEnumeration();
144        if (U_FAILURE(*status)) {
145            //errln("tzids->count failed");
146            return;
147        }
148
149        // Run the roundtrip test
150        for (int32_t locidx = 0; locidx < nLocales; locidx++) {
151            for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) {
152                SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)PATTERNS[patidx], LOCALES[locidx], *status);
153                if (U_FAILURE(*status)) {
154                    //errcheckln(*status, (UnicodeString)"new SimpleDateFormat failed for pattern " +
155                    //    PATTERNS[patidx] + " for locale " + LOCALES[locidx].getName() + " - " + u_errorName(*status));
156                    *status = U_ZERO_ERROR;
157                    continue;
158                }
159
160                tzids->reset(*status);
161                const UnicodeString *tzid;
162                while ((tzid = tzids->snext(*status))) {
163                    TimeZone *tz = TimeZone::createTimeZone(*tzid);
164
165                    for (int32_t datidx = 0; datidx < nDates; datidx++) {
166                        UnicodeString tzstr;
167                        FieldPosition fpos(0);
168
169                        // Format
170                        sdf->setTimeZone(*tz);
171                        sdf->format(DATES[datidx], tzstr, fpos);
172
173                        // Before parse, set unknown zone to SimpleDateFormat instance
174                        // just for making sure that it does not depends on the time zone
175                        // originally set.
176                        sdf->setTimeZone(unknownZone);
177
178                        // Parse
179                        ParsePosition pos(0);
180                        Calendar *outcal = Calendar::createInstance(unknownZone, *status);
181                        if (U_FAILURE(*status)) {
182                            //errln("Failed to create an instance of calendar for receiving parse result.");
183                            *status = U_ZERO_ERROR;
184                            continue;
185                        }
186                        outcal->set(UCAL_DST_OFFSET, badDstOffset);
187                        outcal->set(UCAL_ZONE_OFFSET, badZoneOffset);
188                        sdf->parse(tzstr, *outcal, pos);
189
190                        // clean loop
191                        delete outcal;
192
193                    }
194                    delete tz;
195                    // break  time zone loop
196                    break;
197
198                }
199                delete sdf;
200            }
201        }
202        delete cal;
203        delete tzids;
204
205	}
206
207	virtual long getOperationsPerIteration()
208	{
209		return NUM_PATTERNS * nLocales * 6;
210	}
211};
212
213
214class DateTimeRoundTripPerfTest : public UPerfTest
215{
216private:
217
218public:
219
220	DateTimeRoundTripPerfTest(int32_t argc, const char* argv[], UErrorCode& status);
221	~DateTimeRoundTripPerfTest();
222	virtual UPerfFunction* runIndexedTest(int32_t index, UBool exec,const char* &name, char* par);
223
224	UPerfFunction* RoundTripLocale1();
225	UPerfFunction* RoundTripLocale10();
226	UPerfFunction* RoundTripLocale11();
227	UPerfFunction* RoundTripLocale21();
228};
229
230
231#endif // DateTimeRoundTripPerfTest