• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 *
6 *   Copyright (C) 2009-2012, International Business Machines
7 *   Corporation and others.  All Rights Reserved.
8 *
9 *******************************************************************************
10 */
11 
12 #ifndef DATE_FE_DEBUG
13 #define DATE_FE_DEBUG 0
14 #endif
15 
16 #include <icuglue/icuglue.h>
17 #include "unicode/udat.h"
18 //#include <unicode/tblcoll.h>
19 #include "unicode/datefmt.h"
20 #include "unicode/smpdtfmt.h"
21 #include <string.h>
22 #include <stdio.h>
23 #include "unicode/ustring.h"
24 #include "unicode/gregocal.h"
25 
26 
27 
28 /**
29  * Macro to define the Collator_glue_4_2 class
30  */
31 #ifdef GLUE_VER
32 #error GLUE_VER is defined
33 #endif
34 
35 #define GLUE_VER(x) class GLUE_SYM_V( DateFormat, x ) : public DateFormat {  \
36   public:  static DateFormat *create(UDateFormatStyle  timeStyle, \
37                                                     UDateFormatStyle  dateStyle, \
38                                                     const char        *locale, \
39                                                     const UChar       *tzID, \
40                                                     int32_t           tzIDLength, \
41                                                     const UChar       *pattern,  \
42                                                     int32_t           patternLength,  \
43                                                       UErrorCode        *status, const Locale &loc, const char *ver); \
44   private: UDateFormat *_this; GLUE_SYM_V( DateFormat, x ) ( UDateFormat* tn ); \
45     virtual ~ GLUE_SYM_V ( DateFormat, x) ();                             \
46   public:                                                               \
47     virtual void* getDynamicClassID() const;                            \
48     static void* getStaticClassID() ;                                   \
49     virtual UnicodeString& format(  Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const; \
50     virtual void parse( const UnicodeString& text, Calendar& cal, ParsePosition& pos) const; \
51     virtual Format* clone(void) const; \
52   public: static int32_t countAvailable();                              \
53 public: static int32_t appendAvailable(UnicodeString* strs, int32_t i, int32_t count); \
54   }; \
55 
56 
57 
58 /** ==================================== The following code runs inside the 'target' version (i.e. old ICU) ========== **/
59 #if defined ( ICUGLUE_VER )
60 
61 
62 
63 /* code for some version */
64 #include <icuglue/gluren.h>
65 #include "oicu.h"
66 
67 #ifdef GLUE_VER
68 GLUE_VER( ICUGLUE_VER )
69 #endif
70 
GLUE_SYM(DateFormat)71 GLUE_SYM (DateFormat ) :: GLUE_SYM(DateFormat) ( UDateFormat* tn) :
72  _this(tn)
73 {
74 
75   UErrorCode status = U_ZERO_ERROR;
76   adoptCalendar(new GregorianCalendar(status));
77 }
78 
GLUE_SYM(DateFormat)79 GLUE_SYM ( DateFormat ) :: ~ GLUE_SYM(DateFormat) () {
80 #if DATE_FE_DEBUG
81     fprintf(stderr, "VCF " ICUGLUE_VER_STR " udat_close");
82 #endif
83     OICU_udat_close(_this);
84 }
85 
86 DateFormat *
GLUE_SYM(DateFormat)87 GLUE_SYM ( DateFormat ) :: create(UDateFormatStyle  timeStyle,
88                                                     UDateFormatStyle  dateStyle,
89                                                     const char        *locale,
90                                                     const UChar       *tzID,
91                                                     int32_t           tzIDLength,
92                                                     const UChar       *pattern,
93                                                     int32_t           patternLength,
94                                                     UErrorCode        *status,
95                                   const Locale &loc, const char */*ver*/) {
96   // TODO: save version
97   //char locBuf[200];
98   //char kwvBuf[200];
99   UDateFormat * uc =  OICU_udat_open( timeStyle, dateStyle, locale,
100                                       tzID,
101                                       tzIDLength,
102                                       pattern,
103                                       patternLength,
104                                       status);
105     if(U_FAILURE(*status)) return NULL; // TODO: ERR?
106     DateFormat *c =  new GLUE_SYM( DateFormat ) ( uc );
107 #if DATE_FE_DEBUG
108     fprintf(stderr, "VCF " ICUGLUE_VER_STR " udat_open=%s ->> %p\n", loc.getName(), (void*)c);
109 #endif
110     return c;
111 }
112 
GLUE_SYM(DateFormat)113 UnicodeString& GLUE_SYM (DateFormat ) :: format(  Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const
114 {
115 #if DATE_FE_DEBUG
116   fprintf(stderr, "VCF " ICUGLUE_VER_STR " - formatting. \n");
117 #endif
118   int32_t len = appendTo.length();
119 
120   UChar junk[200];
121   UErrorCode status = U_ZERO_ERROR;
122 
123   UFieldPosition pos2;
124 
125   int32_t nlen = OICU_udat_format(_this,
126                                   cal.getTime(status),
127                                   junk,
128                                   200,
129                                   &pos2,
130                                   &status);
131 
132   // todo: use pos2
133   pos.setBeginIndex(len);
134   pos.setEndIndex(len += nlen);
135   appendTo.append(junk, nlen);
136 
137   return appendTo;
138 }
139 
GLUE_SYM(DateFormat)140 void  GLUE_SYM (DateFormat ) :: parse( const UnicodeString& text, Calendar& cal, ParsePosition& pos) const
141 {
142   return;
143 }
144 
GLUE_SYM(DateFormat)145 Format*  GLUE_SYM (DateFormat ) :: clone(void) const
146 {
147   return NULL;
148 }
149 
150 
151 
GLUE_SYM(DateFormat)152  int32_t GLUE_SYM ( DateFormat ) :: countAvailable() {
153     int32_t count =  OICU_udat_countAvailable();
154     return count;
155  }
156 
157 
GLUE_SYM(DateFormat)158 int32_t GLUE_SYM ( DateFormat ) :: appendAvailable(UnicodeString* strs, int32_t i, int32_t /*count*/) {
159    int avail = OICU_udat_countAvailable();
160    UErrorCode status = U_ZERO_ERROR;
161    OICU_u_init(&status);
162 #if DATE_FE_DEBUG
163    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " avail %d - init %s\n", avail, u_errorName(status));
164 #endif
165     for(int j=0;j<avail;j++) {
166          strs[i+j].append(OICU_udat_getAvailable(j));
167          strs[i+j].append("@sp=icu");
168          strs[i+j].append( ICUGLUE_VER_STR[0] );  // X_y
169          strs[i+j].append( ICUGLUE_VER_STR[2] );  // x_Y
170 #if DATE_FE_DEBUG
171          {
172             char foo[999];
173             const UChar *ss = strs[i+j].getTerminatedBuffer();
174             u_austrcpy(foo, ss);
175             //            fprintf(stderr,  "VCF " ICUGLUE_VER_STR " appending [%d+%d=%d] <<%s>>\n", i, j, i+j, foo);
176         }
177 #endif
178     }
179     return OICU_ucol_countAvailable();
180  }
181 
182 UOBJECT_DEFINE_RTTI_IMPLEMENTATION( GLUE_SYM( DateFormat ) )
183 
184 
185 
186 
187 #else
188 /** ==================================== The following code runs inside the 'provider' version (i.e. current ICU) ========== **/
189 
190 #if (U_ICU_VERSION_MAJOR_NUM < 49)
191 #define DATE_PROVIDER_UNSUPPORTED
192 #endif
193 
194 #ifndef DATE_PROVIDER_UNSUPPORTED
195 // define Collator_XX
196 #include "icuglue/glver.h"
197 
198 // generate list of versions
199 static
200 #include <icuglue/fe_verlist.h>
201 
202 class VersionDateFormatFactory : public UObject  {
203 public:
204   virtual DateFormat *createFormat(UDateFormatStyle  timeStyle,
205                                    UDateFormatStyle  dateStyle,
206                                    const char        *locale,
207                                    const UChar       *tzID,
208                                    int32_t           tzIDLength,
209                                    const UChar       *pattern,
210                                    int32_t           patternLength,
211                                    UErrorCode        *status);
212   virtual const UnicodeString *getSupportedIDs(int32_t &count, UErrorCode &status);
213   virtual void* getDynamicClassID() const;
214   static void* getStaticClassID() ;
215 };
216 
217 UOBJECT_DEFINE_RTTI_IMPLEMENTATION( VersionDateFormatFactory )
218 
219 DateFormat *VersionDateFormatFactory::createFormat(UDateFormatStyle  timeStyle,
220                                                     UDateFormatStyle  dateStyle,
221                                                     const char        *locale,
222                                                     const UChar       *tzID,
223                                                     int32_t           tzIDLength,
224                                                     const UChar       *pattern,
225                                                     int32_t           patternLength,
226                                                        UErrorCode        *status) {
227     Locale loc(locale);
228     // pull off provider #
229     char provider[200];
230 #if DATE_FE_DEBUG
231     fprintf(stderr,  "VCF:CC %s\n", loc.getName());
232 #endif
233     int32_t len = loc.getKeywordValue("sp", provider, 200, *status);
234     if(U_FAILURE(*status)||len==0) return NULL;
235 #if DATE_FE_DEBUG
236     fprintf(stderr,  "VCF:KWV> %s/%d\n", u_errorName(*status), len);
237 #endif
238     provider[len]=0;
239 #if DATE_FE_DEBUG
240     fprintf(stderr,  "VCF:KWV %s\n", provider);
241 #endif
242     if(strncmp(provider,"icu",3)) return NULL;
243     const char *icuver=provider+3;
244 #if DATE_FE_DEBUG
245     fprintf(stderr,  "VCF:ICUV %s\n", icuver);
246 #endif
247 
248 #if defined(GLUE_VER)
249 #undef GLUE_VER
250 #endif
251 #define GLUE_VER(x) /*printf("%c/%c|%c/%c\n", icuver[0],(#x)[0],icuver[1],(#x)[2]);*/  if(icuver[0]== (#x)[0] && icuver[1]==(#x)[2]) { DateFormat *c = glue ## DateFormat ## x :: create(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status,loc,icuver); /*fprintf(stderr, "VCF::CC %s -> %p\n", loc.getName(), c);*/ return c; }
252 #include "icuglue/glver.h"
253 #if DATE_FE_DEBUG
254     fprintf(stderr,  "VCF:CC %s failed\n", loc.getName());
255 #endif
256 
257     return NULL;
258 }
259 
260 
261 static const UnicodeString *gLocalesDate = NULL;
262 static  int32_t gLocCountDate = 0;
263 
264 
265 const UnicodeString
266 *VersionDateFormatFactory::getSupportedIDs(int32_t &count, UErrorCode &/*status*/) {
267   if(gLocalesDate==NULL) {
268     count = 0;
269 
270 
271     /* gather counts */
272 
273 #if defined(GLUE_VER)
274 #undef GLUE_VER
275 #endif
276 #define GLUE_VER(x) count += glue ## DateFormat ## x :: countAvailable();
277 #include "icuglue/glver.h"
278 
279 #if DATE_FE_DEBUG
280     printf("VCF: count=%d\n", count);
281 #endif
282     UnicodeString *strs = new  UnicodeString[count];
283     int32_t i = 0;
284 
285 #if defined(GLUE_VER)
286 #undef GLUE_VER
287 #endif
288 #define GLUE_VER(x) i += glue ## DateFormat ## x :: appendAvailable(strs, i, count);
289 #include "icuglue/glver.h"
290 
291 #if DATE_FE_DEBUG
292     printf("VCF: appended count=%d\n", count);
293 #endif
294 
295     gLocCountDate = count;
296     gLocalesDate = strs;
297   }
298   count = gLocCountDate;
299   return gLocalesDate;
300 }
301 
302 
303 /* Plugin Code */
304 
305 #include <stdio.h>
306 #include <unicode/uversion.h>
307 
308 //static URegistryKey rkdate = NULL;
309 
310 static VersionDateFormatFactory vdf;
311 
312 extern "C" UDateFormat *versionDateFormatOpener(UDateFormatStyle  timeStyle,
313                                                     UDateFormatStyle  dateStyle,
314                                                     const char        *locale,
315                                                     const UChar       *tzID,
316                                                     int32_t           tzIDLength,
317                                                     const UChar       *pattern,
318                                                     int32_t           patternLength,
319                                                        UErrorCode        *status) {
320   DateFormat *df = vdf.createFormat(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status);
321   // printf("Hey! I got: %s -> %p\n", locale, df);
322   return (UDateFormat*)df;
323 }
324 
325 void date_provider_register(UErrorCode &status) {
326   udat_registerOpener(versionDateFormatOpener, &status);
327   //   rkdate = DateFormat::registerFactory(new VersionDateFormatFactory(), status);
328 }
329 
330 void date_provider_unregister(UErrorCode &status) {
331   udat_unregisterOpener(versionDateFormatOpener, &status);
332 }
333 
334 #else
335 
336 /* no op- this ICU doesn't support date providers */
337 
338 void date_provider_register(UErrorCode &) {
339   // not supported
340 }
341 
342 void date_provider_unregister(UErrorCode &) {
343   // not supported
344 }
345 
346 #endif
347 
348 /* Plugin- only ICU 4.4+ */
349 #if (U_ICU_VERSION_MAJOR_NUM > 4) || ((U_ICU_VERSION_MAJOR_NUM==4)&&(U_ICU_VERSION_MINOR_NUM>3))
350 #include "unicode/icuplug.h"
351 
352 U_CAPI UPlugTokenReturn U_EXPORT2 date_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status);
353 
354 U_CAPI UPlugTokenReturn U_EXPORT2 date_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status)
355 {
356   switch(reason) {
357   case UPLUG_REASON_QUERY:
358     uplug_setPlugName(data, "Date Provider Plugin");
359     uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
360     break;
361   case UPLUG_REASON_LOAD:
362     date_provider_register(*status);
363     break;
364   case UPLUG_REASON_UNLOAD:
365     date_provider_unregister(*status);
366     break;
367   default:
368     break; /* not handled */
369   }
370   return UPLUG_TOKEN;
371 }
372 #else
373 
374 /*
375    Note: this ICU version must explicitly call 'date_provider_plugin'
376 */
377 
378 #endif /* plugin */
379 
380 #endif /* provider side (vs target) */
381