Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c
41119 views
1
/*
2
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "sun_util_locale_provider_HostLocaleProviderAdapterImpl.h"
27
#include "jni_util.h"
28
#include <windows.h>
29
#include <gdefs.h>
30
#include <stdlib.h>
31
32
#define BUFLEN 256
33
34
// java.util.Calendar constants
35
#define CALENDAR_FIELD_ERA 0 // Calendar.ERA
36
#define CALENDAR_FIELD_MONTH 2 // Calendar.MONTH
37
#define CALENDAR_FIELD_DAY_OF_WEEK 7 // Calendar.DAY_OF_WEEK
38
#define CALENDAR_FIELD_AM_PM 9 // Calendar.AM_PM
39
#define CALENDAR_STYLE_SHORT_MASK 0x00000001 // Calendar.SHORT
40
#define CALENDAR_STYLE_STANDALONE_MASK 0x00008000 // Calendar.STANDALONE
41
42
// global variables
43
typedef int (WINAPI *PGLIE)(const jchar *, LCTYPE, LPWSTR, int);
44
typedef int (WINAPI *PGCIE)(const jchar *, CALID, LPCWSTR, CALTYPE, LPWSTR, int, LPDWORD);
45
typedef int (WINAPI *PECIEE)(CALINFO_ENUMPROCEXEX, const jchar *, CALID, LPCWSTR, CALTYPE, LPARAM);
46
PGLIE pGetLocaleInfoEx;
47
PGCIE pGetCalendarInfoEx;
48
PECIEE pEnumCalendarInfoExEx;
49
BOOL initialized = FALSE;
50
51
// prototypes
52
int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen);
53
int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val);
54
jint getCalendarID(const jchar *langtag);
55
void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjectArray jarray, DWORD* pTypes, int offset, int length, int style, BOOL bCal);
56
WCHAR * getNumberPattern(const jchar * langtag, const jint numberStyle);
57
void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number);
58
void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret);
59
int enumCalendarInfoWrapper(const jchar * langtag, CALID calid, CALTYPE type, LPWSTR buf, int buflen);
60
BOOL CALLBACK EnumCalendarInfoProc(LPWSTR lpCalInfoStr, CALID calid, LPWSTR lpReserved, LPARAM lParam);
61
jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint calid, jint style, jobjectArray eras);
62
63
// from java_props_md.c
64
extern __declspec(dllexport) const char * getJavaIDFromLangID(LANGID langID);
65
66
CALTYPE monthsType[] = {
67
CAL_SMONTHNAME1,
68
CAL_SMONTHNAME2,
69
CAL_SMONTHNAME3,
70
CAL_SMONTHNAME4,
71
CAL_SMONTHNAME5,
72
CAL_SMONTHNAME6,
73
CAL_SMONTHNAME7,
74
CAL_SMONTHNAME8,
75
CAL_SMONTHNAME9,
76
CAL_SMONTHNAME10,
77
CAL_SMONTHNAME11,
78
CAL_SMONTHNAME12,
79
CAL_SMONTHNAME13,
80
};
81
82
CALTYPE sMonthsType[] = {
83
CAL_SABBREVMONTHNAME1,
84
CAL_SABBREVMONTHNAME2,
85
CAL_SABBREVMONTHNAME3,
86
CAL_SABBREVMONTHNAME4,
87
CAL_SABBREVMONTHNAME5,
88
CAL_SABBREVMONTHNAME6,
89
CAL_SABBREVMONTHNAME7,
90
CAL_SABBREVMONTHNAME8,
91
CAL_SABBREVMONTHNAME9,
92
CAL_SABBREVMONTHNAME10,
93
CAL_SABBREVMONTHNAME11,
94
CAL_SABBREVMONTHNAME12,
95
CAL_SABBREVMONTHNAME13,
96
};
97
98
#define MONTHTYPES (sizeof(monthsType) / sizeof(CALTYPE))
99
100
CALTYPE wDaysType[] = {
101
CAL_SDAYNAME7,
102
CAL_SDAYNAME1,
103
CAL_SDAYNAME2,
104
CAL_SDAYNAME3,
105
CAL_SDAYNAME4,
106
CAL_SDAYNAME5,
107
CAL_SDAYNAME6,
108
};
109
110
CALTYPE sWDaysType[] = {
111
CAL_SABBREVDAYNAME7,
112
CAL_SABBREVDAYNAME1,
113
CAL_SABBREVDAYNAME2,
114
CAL_SABBREVDAYNAME3,
115
CAL_SABBREVDAYNAME4,
116
CAL_SABBREVDAYNAME5,
117
CAL_SABBREVDAYNAME6,
118
};
119
120
#define DOWTYPES (sizeof(wDaysType) / sizeof(CALTYPE))
121
122
LCTYPE ampmType [] = {
123
LOCALE_SAM,
124
LOCALE_SPM,
125
};
126
127
#define AMPMTYPES (sizeof(ampmType) / sizeof(LCTYPE))
128
129
WCHAR * fixes[2][2][3][16] =
130
{
131
{ //prefix
132
{ //positive
133
{ // number
134
L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
135
},
136
{ // currency
137
L"\xA4", L"", L"\xA4 ", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
138
},
139
{ // percent
140
L"", L"", L"%", L"% ", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
141
}
142
},
143
{ // negative
144
{ // number
145
L"(", L"-", L"- ", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
146
},
147
{ //currency
148
L"(\xA4", L"-\xA4", L"\xA4-", L"\xA4", L"(", L"-", L"", L"", L"-", L"-\xA4 ", L"", L"\xA4 ", L"\xA4 -", L"", L"(\xA4 ", L"("
149
},
150
{ // percent
151
L"-", L"-", L"-%", L"%-", L"%", L"", L"", L"-% ", L"", L"% ", L"% -", L"", L"", L"", L"", L"",
152
}
153
}
154
},
155
{ // suffix
156
{ //positive
157
{ // number
158
L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L""
159
},
160
{ // currency
161
L"", L"\xA4 ", L"", L" \xA4", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
162
},
163
{ // percent
164
L" %", L"%", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
165
}
166
},
167
{ // negative
168
{ // number
169
L")", L"", L" ", L"-", L" -", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"", L"",
170
},
171
{ //currency
172
L")", L"", L"", L"-", L"\xA4)", L"\xA4", L"-\xA4", L"\xA4-", L" \xA4", L"", L" \xA4-", L"-", L"", L"- \xA4", L")", L" \xA4)"
173
},
174
{ // percent
175
L" %", L"%", L"", L"", L"-", L"-%", L"%-", L"", L" %-", L"-", L"", L"- %", L"", L"", L"", L"",
176
}
177
}
178
}
179
};
180
181
/*
182
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
183
* Method: initialize
184
* Signature: ()Z
185
*/
186
JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_initialize
187
(JNIEnv *env, jclass cls) {
188
if (!initialized) {
189
pGetLocaleInfoEx = (PGLIE)GetProcAddress(
190
GetModuleHandle("kernel32.dll"),
191
"GetLocaleInfoEx");
192
pGetCalendarInfoEx = (PGCIE)GetProcAddress(
193
GetModuleHandle("kernel32.dll"),
194
"GetCalendarInfoEx");
195
pEnumCalendarInfoExEx = (PECIEE)GetProcAddress(
196
GetModuleHandle("kernel32.dll"),
197
"EnumCalendarInfoExEx");
198
initialized =TRUE;
199
}
200
201
return pGetLocaleInfoEx != NULL &&
202
pGetCalendarInfoEx != NULL &&
203
pEnumCalendarInfoExEx != NULL;
204
}
205
206
/*
207
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
208
* Method: getDefaultLocale
209
* Signature: (I)Ljava/lang/String;
210
*/
211
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDefaultLocale
212
(JNIEnv *env, jclass cls, jint cat) {
213
char * localeString = NULL;
214
LANGID langid;
215
jstring ret;
216
217
switch (cat) {
218
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_DISPLAY:
219
langid = LANGIDFROMLCID(GetUserDefaultUILanguage());
220
break;
221
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_FORMAT:
222
default:
223
langid = LANGIDFROMLCID(GetUserDefaultLCID());
224
break;
225
}
226
227
localeString = (char *)getJavaIDFromLangID(langid);
228
if (localeString != NULL) {
229
ret = (*env)->NewStringUTF(env, localeString);
230
free(localeString);
231
} else {
232
JNU_ThrowOutOfMemoryError(env, "memory allocation error");
233
ret = NULL;
234
}
235
return ret;
236
}
237
238
/*
239
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
240
* Method: getDateTimePattern
241
* Signature: (IILjava/lang/String;)Ljava/lang/String;
242
*/
243
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePattern
244
(JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
245
WCHAR pattern[BUFLEN];
246
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
247
CHECK_NULL_RETURN(langtag, NULL);
248
249
pattern[0] = L'\0';
250
251
if (dateStyle == 0 || dateStyle == 1) {
252
getLocaleInfoWrapper(langtag, LOCALE_SLONGDATE, pattern, BUFLEN);
253
} else if (dateStyle == 2 || dateStyle == 3) {
254
getLocaleInfoWrapper(langtag, LOCALE_SSHORTDATE, pattern, BUFLEN);
255
}
256
257
if (timeStyle == 0 || timeStyle == 1) {
258
getLocaleInfoWrapper(langtag, LOCALE_STIMEFORMAT, pattern, BUFLEN);
259
} else if (timeStyle == 2 || timeStyle == 3) {
260
getLocaleInfoWrapper(langtag, LOCALE_SSHORTTIME, pattern, BUFLEN);
261
}
262
263
(*env)->ReleaseStringChars(env, jlangtag, langtag);
264
265
return (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
266
}
267
268
/*
269
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
270
* Method: getCalendarID
271
* Signature: (Ljava/lang/String;)I
272
*/
273
JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarID
274
(JNIEnv *env, jclass cls, jstring jlangtag) {
275
const jchar *langtag;
276
jint ret;
277
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
278
CHECK_NULL_RETURN(langtag, 0);
279
ret = getCalendarID(langtag);
280
(*env)->ReleaseStringChars(env, jlangtag, langtag);
281
return ret;
282
}
283
284
/*
285
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
286
* Method: getAmPmStrings
287
* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
288
*/
289
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getAmPmStrings
290
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray ampms) {
291
replaceCalendarArrayElems(env, jlangtag, -1, ampms, ampmType,
292
0, AMPMTYPES, 0, FALSE);
293
return ampms;
294
}
295
296
/*
297
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
298
* Method: getEras
299
* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
300
*/
301
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getEras
302
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray eras) {
303
return getErasImpl(env, jlangtag, -1, 0, eras);
304
}
305
306
/*
307
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
308
* Method: getMonths
309
* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
310
*/
311
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonths
312
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray months) {
313
replaceCalendarArrayElems(env, jlangtag, -1, months, monthsType,
314
0, MONTHTYPES, 0, TRUE);
315
return months;
316
}
317
318
/*
319
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
320
* Method: getShortMonths
321
* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
322
*/
323
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortMonths
324
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray smonths) {
325
replaceCalendarArrayElems(env, jlangtag, -1, smonths, sMonthsType,
326
0, MONTHTYPES, 0, TRUE);
327
return smonths;
328
}
329
330
/*
331
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
332
* Method: getWeekdays
333
* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
334
*/
335
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getWeekdays
336
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray wdays) {
337
replaceCalendarArrayElems(env, jlangtag, -1, wdays, wDaysType,
338
1, DOWTYPES, 0, TRUE);
339
return wdays;
340
}
341
342
/*
343
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
344
* Method: getShortWeekdays
345
* Signature: (Ljava/lang/String;[Ljava/lang/String;)[Ljava/lang/String;
346
*/
347
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getShortWeekdays
348
(JNIEnv *env, jclass cls, jstring jlangtag, jobjectArray swdays) {
349
replaceCalendarArrayElems(env, jlangtag, -1, swdays, sWDaysType,
350
1, DOWTYPES, 0, TRUE);
351
return swdays;
352
}
353
354
/*
355
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
356
* Method: getNumberPattern
357
* Signature: (ILjava/lang/String;)Ljava/lang/String;
358
*/
359
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNumberPattern
360
(JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {
361
const jchar *langtag;
362
jstring ret;
363
WCHAR * pattern;
364
365
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
366
CHECK_NULL_RETURN(langtag, NULL);
367
pattern = getNumberPattern(langtag, numberStyle);
368
CHECK_NULL_RETURN(pattern, NULL);
369
370
(*env)->ReleaseStringChars(env, jlangtag, langtag);
371
ret = (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
372
free(pattern);
373
374
return ret;
375
}
376
377
/*
378
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
379
* Method: isNativeDigit
380
* Signature: (Ljava/lang/String;)Z
381
*/
382
JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
383
(JNIEnv *env, jclass cls, jstring jlangtag) {
384
DWORD num;
385
int got;
386
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
387
CHECK_NULL_RETURN(langtag, JNI_FALSE);
388
got = getLocaleInfoWrapper(langtag,
389
LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
390
(LPWSTR)&num, sizeof(num));
391
(*env)->ReleaseStringChars(env, jlangtag, langtag);
392
393
return got && num == 2; // 2: native digit substitution
394
}
395
396
/*
397
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
398
* Method: getCurrencySymbol
399
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
400
*/
401
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
402
(JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
403
WCHAR buf[BUFLEN];
404
int got;
405
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
406
CHECK_NULL_RETURN(langtag, currencySymbol);
407
got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
408
(*env)->ReleaseStringChars(env, jlangtag, langtag);
409
410
if (got) {
411
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
412
} else {
413
return currencySymbol;
414
}
415
}
416
417
/*
418
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
419
* Method: getDecimalSeparator
420
* Signature: (Ljava/lang/String;C)C
421
*/
422
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator
423
(JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) {
424
WCHAR buf[BUFLEN];
425
int got;
426
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
427
CHECK_NULL_RETURN(langtag, decimalSeparator);
428
got = getLocaleInfoWrapper(langtag, LOCALE_SDECIMAL, buf, BUFLEN);
429
(*env)->ReleaseStringChars(env, jlangtag, langtag);
430
431
if (got) {
432
return buf[0];
433
} else {
434
return decimalSeparator;
435
}
436
}
437
438
/*
439
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
440
* Method: getGroupingSeparator
441
* Signature: (Ljava/lang/String;C)C
442
*/
443
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator
444
(JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) {
445
WCHAR buf[BUFLEN];
446
int got;
447
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
448
CHECK_NULL_RETURN(langtag, groupingSeparator);
449
got = getLocaleInfoWrapper(langtag, LOCALE_STHOUSAND, buf, BUFLEN);
450
(*env)->ReleaseStringChars(env, jlangtag, langtag);
451
452
if (got) {
453
return buf[0];
454
} else {
455
return groupingSeparator;
456
}
457
}
458
459
/*
460
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
461
* Method: getInfinity
462
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
463
*/
464
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity
465
(JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) {
466
WCHAR buf[BUFLEN];
467
int got;
468
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
469
CHECK_NULL_RETURN(langtag, infinity);
470
got = getLocaleInfoWrapper(langtag, LOCALE_SPOSINFINITY, buf, BUFLEN);
471
(*env)->ReleaseStringChars(env, jlangtag, langtag);
472
473
if (got) {
474
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
475
} else {
476
return infinity;
477
}
478
}
479
480
/*
481
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
482
* Method: getInternationalCurrencySymbol
483
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
484
*/
485
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol
486
(JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) {
487
WCHAR buf[BUFLEN];
488
int got;
489
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
490
CHECK_NULL_RETURN(langtag, internationalCurrencySymbol);
491
got = getLocaleInfoWrapper(langtag, LOCALE_SINTLSYMBOL, buf, BUFLEN);
492
(*env)->ReleaseStringChars(env, jlangtag, langtag);
493
494
if (got) {
495
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
496
} else {
497
return internationalCurrencySymbol;
498
}
499
}
500
501
/*
502
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
503
* Method: getMinusSign
504
* Signature: (Ljava/lang/String;C)C
505
*/
506
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign
507
(JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) {
508
WCHAR buf[BUFLEN];
509
int got;
510
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
511
CHECK_NULL_RETURN(langtag, minusSign);
512
got = getLocaleInfoWrapper(langtag, LOCALE_SNEGATIVESIGN, buf, BUFLEN);
513
(*env)->ReleaseStringChars(env, jlangtag, langtag);
514
515
if (got) {
516
return buf[0];
517
} else {
518
return minusSign;
519
}
520
}
521
522
/*
523
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
524
* Method: getMonetaryDecimalSeparator
525
* Signature: (Ljava/lang/String;C)C
526
*/
527
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator
528
(JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) {
529
WCHAR buf[BUFLEN];
530
int got;
531
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
532
CHECK_NULL_RETURN(langtag, monetaryDecimalSeparator);
533
got = getLocaleInfoWrapper(langtag, LOCALE_SMONDECIMALSEP, buf, BUFLEN);
534
(*env)->ReleaseStringChars(env, jlangtag, langtag);
535
536
if (got) {
537
return buf[0];
538
} else {
539
return monetaryDecimalSeparator;
540
}
541
}
542
543
/*
544
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
545
* Method: getNaN
546
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
547
*/
548
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN
549
(JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) {
550
WCHAR buf[BUFLEN];
551
int got;
552
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
553
CHECK_NULL_RETURN(langtag, nan);
554
got = getLocaleInfoWrapper(langtag, LOCALE_SNAN, buf, BUFLEN);
555
(*env)->ReleaseStringChars(env, jlangtag, langtag);
556
557
if (got) {
558
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
559
} else {
560
return nan;
561
}
562
}
563
564
/*
565
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
566
* Method: getPercent
567
* Signature: (Ljava/lang/String;C)C
568
*/
569
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent
570
(JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) {
571
WCHAR buf[BUFLEN];
572
int got;
573
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
574
CHECK_NULL_RETURN(langtag, percent);
575
got = getLocaleInfoWrapper(langtag, LOCALE_SPERCENT, buf, BUFLEN);
576
(*env)->ReleaseStringChars(env, jlangtag, langtag);
577
578
if (got) {
579
return buf[0];
580
} else {
581
return percent;
582
}
583
}
584
585
/*
586
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
587
* Method: getPerMill
588
* Signature: (Ljava/lang/String;C)C
589
*/
590
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill
591
(JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) {
592
WCHAR buf[BUFLEN];
593
const jchar *langtag;
594
int got;
595
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
596
CHECK_NULL_RETURN(langtag, perMill);
597
got = getLocaleInfoWrapper(langtag, LOCALE_SPERMILLE, buf, BUFLEN);
598
599
(*env)->ReleaseStringChars(env, jlangtag, langtag);
600
601
if (got) {
602
return buf[0];
603
} else {
604
return perMill;
605
}
606
}
607
608
/*
609
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
610
* Method: getZeroDigit
611
* Signature: (Ljava/lang/String;C)C
612
*/
613
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit
614
(JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
615
WCHAR buf[BUFLEN];
616
const jchar *langtag;
617
int got;
618
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
619
CHECK_NULL_RETURN(langtag, zeroDigit);
620
got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
621
622
(*env)->ReleaseStringChars(env, jlangtag, langtag);
623
624
if (got) {
625
return buf[0];
626
} else {
627
return zeroDigit;
628
}
629
}
630
631
/*
632
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
633
* Method: getCalendarDataValue
634
* Signature: (Ljava/lang/String;I)I
635
*/
636
JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
637
(JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
638
DWORD num;
639
const jchar *langtag;
640
int got = 0;
641
642
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
643
CHECK_NULL_RETURN(langtag, -1);
644
switch (type) {
645
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
646
got = getLocaleInfoWrapper(langtag,
647
LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
648
(LPWSTR)&num, sizeof(num));
649
break;
650
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTWEEKOFYEAR:
651
got = getLocaleInfoWrapper(langtag,
652
LOCALE_IFIRSTWEEKOFYEAR | LOCALE_RETURN_NUMBER,
653
(LPWSTR)&num, sizeof(num));
654
break;
655
}
656
657
(*env)->ReleaseStringChars(env, jlangtag, langtag);
658
659
if (got) {
660
return num;
661
} else {
662
return -1;
663
}
664
}
665
666
/*
667
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
668
* Method: getCalendarDisplayStrings
669
* Signature: (Ljava/lang/String;III)[Ljava/lang/String;
670
*/
671
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDisplayStrings
672
(JNIEnv *env, jclass cls, jstring jlangtag, jint calid, jint field, jint style) {
673
jobjectArray ret = NULL;
674
CALTYPE * pCalType = NULL;
675
676
switch (field) {
677
case CALENDAR_FIELD_ERA:
678
return getErasImpl(env, jlangtag, calid, style, NULL);
679
680
case CALENDAR_FIELD_AM_PM:
681
ret = (*env)->NewObjectArray(env, AMPMTYPES,
682
(*env)->FindClass(env, "java/lang/String"), NULL);
683
if (ret != NULL) {
684
replaceCalendarArrayElems(env, jlangtag, calid, ret, ampmType,
685
0, AMPMTYPES, style, FALSE);
686
}
687
return ret;
688
689
case CALENDAR_FIELD_DAY_OF_WEEK:
690
ret = (*env)->NewObjectArray(env, DOWTYPES,
691
(*env)->FindClass(env, "java/lang/String"), NULL);
692
if (ret != NULL) {
693
if (style & CALENDAR_STYLE_SHORT_MASK) {
694
pCalType = sWDaysType;
695
} else {
696
pCalType = wDaysType;
697
}
698
699
replaceCalendarArrayElems(env, jlangtag, calid, ret, pCalType,
700
0, DOWTYPES, style, TRUE);
701
}
702
return ret;
703
704
case CALENDAR_FIELD_MONTH:
705
ret = (*env)->NewObjectArray(env, MONTHTYPES,
706
(*env)->FindClass(env, "java/lang/String"), NULL);
707
if (ret != NULL) {
708
if (style & CALENDAR_STYLE_SHORT_MASK) {
709
pCalType = sMonthsType;
710
} else {
711
pCalType = monthsType;
712
}
713
714
replaceCalendarArrayElems(env, jlangtag, calid, ret, pCalType,
715
0, MONTHTYPES, style, TRUE);
716
}
717
return ret;
718
719
default:
720
// not supported
721
return NULL;
722
}
723
}
724
725
/*
726
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
727
* Method: getDisplayString
728
* Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
729
*/
730
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDisplayString
731
(JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring jvalue) {
732
LCTYPE lcType;
733
jstring jStr;
734
const jchar * pjChar;
735
WCHAR buf[BUFLEN];
736
int got = 0;
737
738
switch (type) {
739
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_NAME:
740
lcType = LOCALE_SNATIVECURRNAME;
741
jStr = jlangtag;
742
break;
743
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_SYMBOL:
744
lcType = LOCALE_SCURRENCY;
745
jStr = jlangtag;
746
break;
747
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_LANGUAGE:
748
lcType = LOCALE_SLOCALIZEDLANGUAGENAME;
749
jStr = jvalue;
750
break;
751
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION:
752
lcType = LOCALE_SLOCALIZEDCOUNTRYNAME;
753
jStr = jvalue;
754
break;
755
default:
756
return NULL;
757
}
758
759
pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE);
760
CHECK_NULL_RETURN(pjChar, NULL);
761
got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN);
762
(*env)->ReleaseStringChars(env, jStr, pjChar);
763
764
if (got) {
765
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
766
} else {
767
return NULL;
768
}
769
}
770
771
int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
772
if (pGetLocaleInfoEx) {
773
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
774
// defaults to "en"
775
return pGetLocaleInfoEx(L"en", type, data, buflen);
776
} else {
777
return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen);
778
}
779
} else {
780
// If we ever wanted to support WinXP, we will need extra module from
781
// MS...
782
// return GetLocaleInfo(DownlevelLocaleNameToLCID(langtag, 0), type, data, buflen);
783
return 0;
784
}
785
}
786
787
int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val) {
788
if (pGetCalendarInfoEx) {
789
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
790
// defaults to "en"
791
return pGetCalendarInfoEx(L"en", id, reserved, type, data, buflen, val);
792
} else {
793
return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val);
794
}
795
} else {
796
// If we ever wanted to support WinXP, we will need extra module from
797
// MS...
798
// return GetCalendarInfo(DownlevelLocaleNameToLCID(langtag, 0), ...);
799
return 0;
800
}
801
}
802
803
jint getCalendarID(const jchar *langtag) {
804
DWORD type = -1;
805
int got = getLocaleInfoWrapper(langtag,
806
LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
807
(LPWSTR)&type, sizeof(type));
808
809
if (got) {
810
switch (type) {
811
case CAL_GREGORIAN:
812
case CAL_GREGORIAN_US:
813
case CAL_JAPAN:
814
case CAL_TAIWAN:
815
case CAL_HIJRI:
816
case CAL_THAI:
817
case CAL_GREGORIAN_ME_FRENCH:
818
case CAL_GREGORIAN_ARABIC:
819
case CAL_GREGORIAN_XLIT_ENGLISH:
820
case CAL_GREGORIAN_XLIT_FRENCH:
821
case CAL_UMALQURA:
822
break;
823
824
default:
825
// non-supported calendars return -1
826
type = -1;
827
break;
828
}
829
}
830
831
return type;
832
}
833
834
void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjectArray jarray, DWORD* pTypes, int offset, int length, int style, BOOL bCal) {
835
WCHAR name[BUFLEN];
836
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
837
jstring tmp_string;
838
CALTYPE isGenitive;
839
840
CHECK_NULL(langtag);
841
842
if (calid < 0) {
843
calid = getCalendarID(langtag);
844
}
845
846
if (calid != -1) {
847
int i;
848
849
if (!(style & CALENDAR_STYLE_STANDALONE_MASK)) {
850
isGenitive = CAL_RETURN_GENITIVE_NAMES;
851
}
852
853
for (i = 0; i < length; i++) {
854
if (bCal && getCalendarInfoWrapper(langtag, calid, NULL,
855
pTypes[i] | isGenitive, name, BUFLEN, NULL) != 0 ||
856
getLocaleInfoWrapper(langtag, pTypes[i] | isGenitive, name, BUFLEN) != 0) {
857
tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name));
858
if (tmp_string != NULL) {
859
(*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string);
860
}
861
}
862
}
863
}
864
865
(*env)->ReleaseStringChars(env, jlangtag, langtag);
866
}
867
868
WCHAR * getNumberPattern(const jchar * langtag, const jint numberStyle) {
869
WCHAR ret[BUFLEN];
870
WCHAR number[BUFLEN];
871
WCHAR fix[BUFLEN];
872
873
getFixPart(langtag, numberStyle, TRUE, TRUE, ret); // "+"
874
getNumberPart(langtag, numberStyle, number);
875
wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34"
876
getFixPart(langtag, numberStyle, TRUE, FALSE, fix);
877
wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$"
878
wcscat_s(ret, BUFLEN-wcslen(ret), L";"); // "+12.34$;"
879
getFixPart(langtag, numberStyle, FALSE, TRUE, fix);
880
wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;("
881
wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34$;(12.34"
882
getFixPart(langtag, numberStyle, FALSE, FALSE, fix);
883
wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;(12.34$)"
884
885
return _wcsdup(ret);
886
}
887
888
void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number) {
889
DWORD digits = 0;
890
DWORD leadingZero = 0;
891
WCHAR grouping[BUFLEN];
892
int groupingLen;
893
WCHAR fractionPattern[BUFLEN];
894
WCHAR * integerPattern = number;
895
WCHAR * pDest;
896
897
// Get info from Windows
898
switch (numberStyle) {
899
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY:
900
getLocaleInfoWrapper(langtag,
901
LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
902
(LPWSTR)&digits, sizeof(digits));
903
break;
904
905
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER:
906
break;
907
908
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER:
909
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT:
910
default:
911
getLocaleInfoWrapper(langtag,
912
LOCALE_IDIGITS | LOCALE_RETURN_NUMBER,
913
(LPWSTR)&digits, sizeof(digits));
914
break;
915
}
916
917
getLocaleInfoWrapper(langtag,
918
LOCALE_ILZERO | LOCALE_RETURN_NUMBER,
919
(LPWSTR)&leadingZero, sizeof(leadingZero));
920
groupingLen = getLocaleInfoWrapper(langtag, LOCALE_SGROUPING, grouping, BUFLEN);
921
922
// fraction pattern
923
if (digits > 0) {
924
int i;
925
for(i = digits; i > 0; i--) {
926
fractionPattern[i] = L'#';
927
}
928
fractionPattern[0] = L'.';
929
fractionPattern[digits+1] = L'\0';
930
} else {
931
fractionPattern[0] = L'\0';
932
}
933
934
// integer pattern
935
pDest = integerPattern;
936
if (groupingLen > 0) {
937
int cur = groupingLen - 1;// subtracting null terminator
938
while (--cur >= 0) {
939
int repnum;
940
941
if (grouping[cur] == L';') {
942
continue;
943
}
944
945
repnum = grouping[cur] - 0x30;
946
if (repnum > 0) {
947
*pDest++ = L'#';
948
*pDest++ = L',';
949
while(--repnum > 0) {
950
*pDest++ = L'#';
951
}
952
}
953
}
954
}
955
956
if (leadingZero != 0) {
957
*pDest++ = L'0';
958
} else {
959
*pDest++ = L'#';
960
}
961
*pDest = L'\0';
962
963
wcscat_s(integerPattern, BUFLEN, fractionPattern);
964
}
965
966
void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret) {
967
DWORD pattern = 0;
968
int style = numberStyle;
969
int got = 0;
970
971
if (positive) {
972
if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
973
got = getLocaleInfoWrapper(langtag,
974
LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
975
(LPWSTR)&pattern, sizeof(pattern));
976
} else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
977
got = getLocaleInfoWrapper(langtag,
978
LOCALE_IPOSITIVEPERCENT | LOCALE_RETURN_NUMBER,
979
(LPWSTR)&pattern, sizeof(pattern));
980
}
981
} else {
982
if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
983
got = getLocaleInfoWrapper(langtag,
984
LOCALE_INEGCURR | LOCALE_RETURN_NUMBER,
985
(LPWSTR)&pattern, sizeof(pattern));
986
} else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
987
got = getLocaleInfoWrapper(langtag,
988
LOCALE_INEGATIVEPERCENT | LOCALE_RETURN_NUMBER,
989
(LPWSTR)&pattern, sizeof(pattern));
990
} else {
991
got = getLocaleInfoWrapper(langtag,
992
LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
993
(LPWSTR)&pattern, sizeof(pattern));
994
}
995
}
996
997
if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
998
style = sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER;
999
}
1000
1001
wcscpy(ret, fixes[!prefix][!positive][style][pattern]);
1002
}
1003
1004
int enumCalendarInfoWrapper(const jchar *langtag, CALID calid, CALTYPE type, LPWSTR buf, int buflen) {
1005
if (pEnumCalendarInfoExEx) {
1006
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
1007
// defaults to "en"
1008
return pEnumCalendarInfoExEx(&EnumCalendarInfoProc, L"en",
1009
calid, NULL, type, (LPARAM)buf);
1010
} else {
1011
return pEnumCalendarInfoExEx(&EnumCalendarInfoProc, langtag,
1012
calid, NULL, type, (LPARAM)buf);
1013
}
1014
} else {
1015
return 0;
1016
}
1017
}
1018
1019
BOOL CALLBACK EnumCalendarInfoProc(LPWSTR lpCalInfoStr, CALID calid, LPWSTR lpReserved, LPARAM lParam) {
1020
wcscat_s((LPWSTR)lParam, BUFLEN, lpCalInfoStr);
1021
wcscat_s((LPWSTR)lParam, BUFLEN, L",");
1022
return TRUE;
1023
}
1024
1025
jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint calid, jint style, jobjectArray eras) {
1026
const jchar * langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
1027
WCHAR buf[BUFLEN];
1028
jobjectArray ret = eras;
1029
CALTYPE type;
1030
1031
CHECK_NULL_RETURN(langtag, ret);
1032
1033
buf[0] = '\0';
1034
if (style & CALENDAR_STYLE_SHORT_MASK) {
1035
type = CAL_SABBREVERASTRING;
1036
} else {
1037
type = CAL_SERASTRING;
1038
}
1039
1040
if (calid < 0) {
1041
calid = getCalendarID(langtag);
1042
}
1043
1044
if (calid != -1 && enumCalendarInfoWrapper(langtag, calid, type, buf, BUFLEN)) {
1045
// format in buf: "era0,era1,era2," where era0 is the current one
1046
int eraCount;
1047
LPWSTR current;
1048
jsize array_length;
1049
1050
for(eraCount = 0, current = buf; *current != '\0'; current++) {
1051
if (*current == L',') {
1052
eraCount ++;
1053
}
1054
}
1055
1056
if (eras != NULL) {
1057
array_length = (*env)->GetArrayLength(env, eras);
1058
} else {
1059
// +1 for the "before" era, e.g., BC, which Windows does not return.
1060
array_length = (jsize)eraCount + 1;
1061
ret = (*env)->NewObjectArray(env, array_length,
1062
(*env)->FindClass(env, "java/lang/String"), NULL);
1063
}
1064
1065
if (ret != NULL) {
1066
int eraIndex;
1067
LPWSTR era;
1068
1069
for(eraIndex = 0, era = current = buf; eraIndex < eraCount; era = current, eraIndex++) {
1070
while (*current != L',') {
1071
current++;
1072
}
1073
*current++ = '\0';
1074
1075
if (eraCount - eraIndex < array_length &&
1076
*era != '\0') {
1077
(*env)->SetObjectArrayElement(env, ret,
1078
(jsize)(eraCount - eraIndex),
1079
(*env)->NewString(env, era, (jsize)wcslen(era)));
1080
}
1081
}
1082
1083
// Hack for the Japanese Imperial Calendar to insert Gregorian era for
1084
// "Before Meiji"
1085
if (calid == CAL_JAPAN) {
1086
buf[0] = '\0';
1087
if (enumCalendarInfoWrapper(langtag, CAL_GREGORIAN, type, buf, BUFLEN)) {
1088
jsize len = (jsize)wcslen(buf);
1089
buf[--len] = '\0'; // remove the last ','
1090
(*env)->SetObjectArrayElement(env, ret, 0, (*env)->NewString(env, buf, len));
1091
}
1092
}
1093
}
1094
}
1095
1096
(*env)->ReleaseStringChars(env, jlangtag, langtag);
1097
return ret;
1098
}
1099
1100