Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c
67769 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 = NULL;
363
WCHAR * pattern;
364
365
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
366
CHECK_NULL_RETURN(langtag, NULL);
367
pattern = getNumberPattern(langtag, numberStyle);
368
if (!IS_NULL(pattern)) {
369
ret = (*env)->NewString(env, pattern, (jsize)wcslen(pattern));
370
free(pattern);
371
}
372
(*env)->ReleaseStringChars(env, jlangtag, langtag);
373
return ret;
374
}
375
376
/*
377
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
378
* Method: isNativeDigit
379
* Signature: (Ljava/lang/String;)Z
380
*/
381
JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
382
(JNIEnv *env, jclass cls, jstring jlangtag) {
383
DWORD num;
384
int got;
385
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
386
CHECK_NULL_RETURN(langtag, JNI_FALSE);
387
got = getLocaleInfoWrapper(langtag,
388
LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
389
(LPWSTR)&num, sizeof(num));
390
(*env)->ReleaseStringChars(env, jlangtag, langtag);
391
392
return got && num == 2; // 2: native digit substitution
393
}
394
395
/*
396
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
397
* Method: getCurrencySymbol
398
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
399
*/
400
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
401
(JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
402
WCHAR buf[BUFLEN];
403
int got;
404
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
405
CHECK_NULL_RETURN(langtag, currencySymbol);
406
got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
407
(*env)->ReleaseStringChars(env, jlangtag, langtag);
408
409
if (got) {
410
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
411
} else {
412
return currencySymbol;
413
}
414
}
415
416
/*
417
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
418
* Method: getDecimalSeparator
419
* Signature: (Ljava/lang/String;C)C
420
*/
421
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDecimalSeparator
422
(JNIEnv *env, jclass cls, jstring jlangtag, jchar decimalSeparator) {
423
WCHAR buf[BUFLEN];
424
int got;
425
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
426
CHECK_NULL_RETURN(langtag, decimalSeparator);
427
got = getLocaleInfoWrapper(langtag, LOCALE_SDECIMAL, buf, BUFLEN);
428
(*env)->ReleaseStringChars(env, jlangtag, langtag);
429
430
if (got) {
431
return buf[0];
432
} else {
433
return decimalSeparator;
434
}
435
}
436
437
/*
438
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
439
* Method: getGroupingSeparator
440
* Signature: (Ljava/lang/String;C)C
441
*/
442
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getGroupingSeparator
443
(JNIEnv *env, jclass cls, jstring jlangtag, jchar groupingSeparator) {
444
WCHAR buf[BUFLEN];
445
int got;
446
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
447
CHECK_NULL_RETURN(langtag, groupingSeparator);
448
got = getLocaleInfoWrapper(langtag, LOCALE_STHOUSAND, buf, BUFLEN);
449
(*env)->ReleaseStringChars(env, jlangtag, langtag);
450
451
if (got) {
452
return buf[0];
453
} else {
454
return groupingSeparator;
455
}
456
}
457
458
/*
459
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
460
* Method: getInfinity
461
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
462
*/
463
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInfinity
464
(JNIEnv *env, jclass cls, jstring jlangtag, jstring infinity) {
465
WCHAR buf[BUFLEN];
466
int got;
467
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
468
CHECK_NULL_RETURN(langtag, infinity);
469
got = getLocaleInfoWrapper(langtag, LOCALE_SPOSINFINITY, buf, BUFLEN);
470
(*env)->ReleaseStringChars(env, jlangtag, langtag);
471
472
if (got) {
473
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
474
} else {
475
return infinity;
476
}
477
}
478
479
/*
480
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
481
* Method: getInternationalCurrencySymbol
482
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
483
*/
484
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getInternationalCurrencySymbol
485
(JNIEnv *env, jclass cls, jstring jlangtag, jstring internationalCurrencySymbol) {
486
WCHAR buf[BUFLEN];
487
int got;
488
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
489
CHECK_NULL_RETURN(langtag, internationalCurrencySymbol);
490
got = getLocaleInfoWrapper(langtag, LOCALE_SINTLSYMBOL, buf, BUFLEN);
491
(*env)->ReleaseStringChars(env, jlangtag, langtag);
492
493
if (got) {
494
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
495
} else {
496
return internationalCurrencySymbol;
497
}
498
}
499
500
/*
501
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
502
* Method: getMinusSign
503
* Signature: (Ljava/lang/String;C)C
504
*/
505
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMinusSign
506
(JNIEnv *env, jclass cls, jstring jlangtag, jchar minusSign) {
507
WCHAR buf[BUFLEN];
508
int got;
509
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
510
CHECK_NULL_RETURN(langtag, minusSign);
511
got = getLocaleInfoWrapper(langtag, LOCALE_SNEGATIVESIGN, buf, BUFLEN);
512
(*env)->ReleaseStringChars(env, jlangtag, langtag);
513
514
if (got) {
515
return buf[0];
516
} else {
517
return minusSign;
518
}
519
}
520
521
/*
522
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
523
* Method: getMonetaryDecimalSeparator
524
* Signature: (Ljava/lang/String;C)C
525
*/
526
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getMonetaryDecimalSeparator
527
(JNIEnv *env, jclass cls, jstring jlangtag, jchar monetaryDecimalSeparator) {
528
WCHAR buf[BUFLEN];
529
int got;
530
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
531
CHECK_NULL_RETURN(langtag, monetaryDecimalSeparator);
532
got = getLocaleInfoWrapper(langtag, LOCALE_SMONDECIMALSEP, buf, BUFLEN);
533
(*env)->ReleaseStringChars(env, jlangtag, langtag);
534
535
if (got) {
536
return buf[0];
537
} else {
538
return monetaryDecimalSeparator;
539
}
540
}
541
542
/*
543
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
544
* Method: getNaN
545
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
546
*/
547
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getNaN
548
(JNIEnv *env, jclass cls, jstring jlangtag, jstring nan) {
549
WCHAR buf[BUFLEN];
550
int got;
551
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
552
CHECK_NULL_RETURN(langtag, nan);
553
got = getLocaleInfoWrapper(langtag, LOCALE_SNAN, buf, BUFLEN);
554
(*env)->ReleaseStringChars(env, jlangtag, langtag);
555
556
if (got) {
557
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
558
} else {
559
return nan;
560
}
561
}
562
563
/*
564
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
565
* Method: getPercent
566
* Signature: (Ljava/lang/String;C)C
567
*/
568
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPercent
569
(JNIEnv *env, jclass cls, jstring jlangtag, jchar percent) {
570
WCHAR buf[BUFLEN];
571
int got;
572
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
573
CHECK_NULL_RETURN(langtag, percent);
574
got = getLocaleInfoWrapper(langtag, LOCALE_SPERCENT, buf, BUFLEN);
575
(*env)->ReleaseStringChars(env, jlangtag, langtag);
576
577
if (got) {
578
return buf[0];
579
} else {
580
return percent;
581
}
582
}
583
584
/*
585
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
586
* Method: getPerMill
587
* Signature: (Ljava/lang/String;C)C
588
*/
589
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getPerMill
590
(JNIEnv *env, jclass cls, jstring jlangtag, jchar perMill) {
591
WCHAR buf[BUFLEN];
592
const jchar *langtag;
593
int got;
594
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
595
CHECK_NULL_RETURN(langtag, perMill);
596
got = getLocaleInfoWrapper(langtag, LOCALE_SPERMILLE, buf, BUFLEN);
597
598
(*env)->ReleaseStringChars(env, jlangtag, langtag);
599
600
if (got) {
601
return buf[0];
602
} else {
603
return perMill;
604
}
605
}
606
607
/*
608
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
609
* Method: getZeroDigit
610
* Signature: (Ljava/lang/String;C)C
611
*/
612
JNIEXPORT jchar JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getZeroDigit
613
(JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
614
WCHAR buf[BUFLEN];
615
const jchar *langtag;
616
int got;
617
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
618
CHECK_NULL_RETURN(langtag, zeroDigit);
619
got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
620
621
(*env)->ReleaseStringChars(env, jlangtag, langtag);
622
623
if (got) {
624
return buf[0];
625
} else {
626
return zeroDigit;
627
}
628
}
629
630
/*
631
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
632
* Method: getCalendarDataValue
633
* Signature: (Ljava/lang/String;I)I
634
*/
635
JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
636
(JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
637
DWORD num;
638
const jchar *langtag;
639
int got = 0;
640
641
langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
642
CHECK_NULL_RETURN(langtag, -1);
643
switch (type) {
644
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
645
got = getLocaleInfoWrapper(langtag,
646
LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
647
(LPWSTR)&num, sizeof(num));
648
break;
649
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTWEEKOFYEAR:
650
got = getLocaleInfoWrapper(langtag,
651
LOCALE_IFIRSTWEEKOFYEAR | LOCALE_RETURN_NUMBER,
652
(LPWSTR)&num, sizeof(num));
653
break;
654
}
655
656
(*env)->ReleaseStringChars(env, jlangtag, langtag);
657
658
if (got) {
659
return num;
660
} else {
661
return -1;
662
}
663
}
664
665
/*
666
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
667
* Method: getCalendarDisplayStrings
668
* Signature: (Ljava/lang/String;III)[Ljava/lang/String;
669
*/
670
JNIEXPORT jobjectArray JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDisplayStrings
671
(JNIEnv *env, jclass cls, jstring jlangtag, jint calid, jint field, jint style) {
672
jobjectArray ret = NULL;
673
CALTYPE * pCalType = NULL;
674
675
switch (field) {
676
case CALENDAR_FIELD_ERA:
677
return getErasImpl(env, jlangtag, calid, style, NULL);
678
679
case CALENDAR_FIELD_AM_PM:
680
ret = (*env)->NewObjectArray(env, AMPMTYPES,
681
(*env)->FindClass(env, "java/lang/String"), NULL);
682
if (ret != NULL) {
683
replaceCalendarArrayElems(env, jlangtag, calid, ret, ampmType,
684
0, AMPMTYPES, style, FALSE);
685
}
686
return ret;
687
688
case CALENDAR_FIELD_DAY_OF_WEEK:
689
ret = (*env)->NewObjectArray(env, DOWTYPES,
690
(*env)->FindClass(env, "java/lang/String"), NULL);
691
if (ret != NULL) {
692
if (style & CALENDAR_STYLE_SHORT_MASK) {
693
pCalType = sWDaysType;
694
} else {
695
pCalType = wDaysType;
696
}
697
698
replaceCalendarArrayElems(env, jlangtag, calid, ret, pCalType,
699
0, DOWTYPES, style, TRUE);
700
}
701
return ret;
702
703
case CALENDAR_FIELD_MONTH:
704
ret = (*env)->NewObjectArray(env, MONTHTYPES,
705
(*env)->FindClass(env, "java/lang/String"), NULL);
706
if (ret != NULL) {
707
if (style & CALENDAR_STYLE_SHORT_MASK) {
708
pCalType = sMonthsType;
709
} else {
710
pCalType = monthsType;
711
}
712
713
replaceCalendarArrayElems(env, jlangtag, calid, ret, pCalType,
714
0, MONTHTYPES, style, TRUE);
715
}
716
return ret;
717
718
default:
719
// not supported
720
return NULL;
721
}
722
}
723
724
/*
725
* Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
726
* Method: getDisplayString
727
* Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
728
*/
729
JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDisplayString
730
(JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring jvalue) {
731
LCTYPE lcType;
732
jstring jStr;
733
const jchar * pjChar;
734
WCHAR buf[BUFLEN];
735
int got = 0;
736
737
switch (type) {
738
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_NAME:
739
lcType = LOCALE_SNATIVECURRNAME;
740
jStr = jlangtag;
741
break;
742
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_SYMBOL:
743
lcType = LOCALE_SCURRENCY;
744
jStr = jlangtag;
745
break;
746
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_LANGUAGE:
747
lcType = LOCALE_SLOCALIZEDLANGUAGENAME;
748
jStr = jvalue;
749
break;
750
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION:
751
lcType = LOCALE_SLOCALIZEDCOUNTRYNAME;
752
jStr = jvalue;
753
break;
754
default:
755
return NULL;
756
}
757
758
pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE);
759
CHECK_NULL_RETURN(pjChar, NULL);
760
got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN);
761
(*env)->ReleaseStringChars(env, jStr, pjChar);
762
763
if (got) {
764
return (*env)->NewString(env, buf, (jsize)wcslen(buf));
765
} else {
766
return NULL;
767
}
768
}
769
770
int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
771
if (pGetLocaleInfoEx) {
772
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
773
// defaults to "en"
774
return pGetLocaleInfoEx(L"en", type, data, buflen);
775
} else {
776
return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen);
777
}
778
} else {
779
// If we ever wanted to support WinXP, we will need extra module from
780
// MS...
781
// return GetLocaleInfo(DownlevelLocaleNameToLCID(langtag, 0), type, data, buflen);
782
return 0;
783
}
784
}
785
786
int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val) {
787
if (pGetCalendarInfoEx) {
788
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
789
// defaults to "en"
790
return pGetCalendarInfoEx(L"en", id, reserved, type, data, buflen, val);
791
} else {
792
return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val);
793
}
794
} else {
795
// If we ever wanted to support WinXP, we will need extra module from
796
// MS...
797
// return GetCalendarInfo(DownlevelLocaleNameToLCID(langtag, 0), ...);
798
return 0;
799
}
800
}
801
802
jint getCalendarID(const jchar *langtag) {
803
DWORD type = -1;
804
int got = getLocaleInfoWrapper(langtag,
805
LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
806
(LPWSTR)&type, sizeof(type));
807
808
if (got) {
809
switch (type) {
810
case CAL_GREGORIAN:
811
case CAL_GREGORIAN_US:
812
case CAL_JAPAN:
813
case CAL_TAIWAN:
814
case CAL_HIJRI:
815
case CAL_THAI:
816
case CAL_GREGORIAN_ME_FRENCH:
817
case CAL_GREGORIAN_ARABIC:
818
case CAL_GREGORIAN_XLIT_ENGLISH:
819
case CAL_GREGORIAN_XLIT_FRENCH:
820
case CAL_UMALQURA:
821
break;
822
823
default:
824
// non-supported calendars return -1
825
type = -1;
826
break;
827
}
828
}
829
830
return type;
831
}
832
833
void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjectArray jarray, DWORD* pTypes, int offset, int length, int style, BOOL bCal) {
834
WCHAR name[BUFLEN];
835
const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
836
jstring tmp_string;
837
CALTYPE isGenitive;
838
839
CHECK_NULL(langtag);
840
841
if (calid < 0) {
842
calid = getCalendarID(langtag);
843
}
844
845
if (calid != -1) {
846
int i;
847
848
if (!(style & CALENDAR_STYLE_STANDALONE_MASK)) {
849
isGenitive = CAL_RETURN_GENITIVE_NAMES;
850
}
851
852
for (i = 0; i < length; i++) {
853
if (bCal && getCalendarInfoWrapper(langtag, calid, NULL,
854
pTypes[i] | isGenitive, name, BUFLEN, NULL) != 0 ||
855
getLocaleInfoWrapper(langtag, pTypes[i] | isGenitive, name, BUFLEN) != 0) {
856
tmp_string = (*env)->NewString(env, name, (jsize)wcslen(name));
857
if (tmp_string != NULL) {
858
(*env)->SetObjectArrayElement(env, jarray, i + offset, tmp_string);
859
}
860
}
861
}
862
}
863
864
(*env)->ReleaseStringChars(env, jlangtag, langtag);
865
}
866
867
WCHAR * getNumberPattern(const jchar * langtag, const jint numberStyle) {
868
WCHAR ret[BUFLEN];
869
WCHAR number[BUFLEN];
870
WCHAR fix[BUFLEN];
871
872
getFixPart(langtag, numberStyle, TRUE, TRUE, ret); // "+"
873
getNumberPart(langtag, numberStyle, number);
874
wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34"
875
getFixPart(langtag, numberStyle, TRUE, FALSE, fix);
876
wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$"
877
wcscat_s(ret, BUFLEN-wcslen(ret), L";"); // "+12.34$;"
878
getFixPart(langtag, numberStyle, FALSE, TRUE, fix);
879
wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;("
880
wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34$;(12.34"
881
getFixPart(langtag, numberStyle, FALSE, FALSE, fix);
882
wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;(12.34$)"
883
884
return _wcsdup(ret);
885
}
886
887
void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number) {
888
DWORD digits = 0;
889
DWORD leadingZero = 0;
890
WCHAR grouping[BUFLEN];
891
int groupingLen;
892
WCHAR fractionPattern[BUFLEN];
893
WCHAR * integerPattern = number;
894
WCHAR * pDest;
895
896
// Get info from Windows
897
switch (numberStyle) {
898
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY:
899
getLocaleInfoWrapper(langtag,
900
LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
901
(LPWSTR)&digits, sizeof(digits));
902
break;
903
904
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER:
905
break;
906
907
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER:
908
case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT:
909
default:
910
getLocaleInfoWrapper(langtag,
911
LOCALE_IDIGITS | LOCALE_RETURN_NUMBER,
912
(LPWSTR)&digits, sizeof(digits));
913
break;
914
}
915
916
getLocaleInfoWrapper(langtag,
917
LOCALE_ILZERO | LOCALE_RETURN_NUMBER,
918
(LPWSTR)&leadingZero, sizeof(leadingZero));
919
groupingLen = getLocaleInfoWrapper(langtag, LOCALE_SGROUPING, grouping, BUFLEN);
920
921
// fraction pattern
922
if (digits > 0) {
923
int i;
924
for(i = digits; i > 0; i--) {
925
fractionPattern[i] = L'#';
926
}
927
fractionPattern[0] = L'.';
928
fractionPattern[digits+1] = L'\0';
929
} else {
930
fractionPattern[0] = L'\0';
931
}
932
933
// integer pattern
934
pDest = integerPattern;
935
if (groupingLen > 0) {
936
int cur = groupingLen - 1;// subtracting null terminator
937
while (--cur >= 0) {
938
int repnum;
939
940
if (grouping[cur] == L';') {
941
continue;
942
}
943
944
repnum = grouping[cur] - 0x30;
945
if (repnum > 0) {
946
*pDest++ = L'#';
947
*pDest++ = L',';
948
while(--repnum > 0) {
949
*pDest++ = L'#';
950
}
951
}
952
}
953
}
954
955
if (leadingZero != 0) {
956
*pDest++ = L'0';
957
} else {
958
*pDest++ = L'#';
959
}
960
*pDest = L'\0';
961
962
wcscat_s(integerPattern, BUFLEN, fractionPattern);
963
}
964
965
void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret) {
966
DWORD pattern = 0;
967
int style = numberStyle;
968
int got = 0;
969
970
if (positive) {
971
if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
972
got = getLocaleInfoWrapper(langtag,
973
LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
974
(LPWSTR)&pattern, sizeof(pattern));
975
} else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
976
got = getLocaleInfoWrapper(langtag,
977
LOCALE_IPOSITIVEPERCENT | LOCALE_RETURN_NUMBER,
978
(LPWSTR)&pattern, sizeof(pattern));
979
}
980
} else {
981
if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
982
got = getLocaleInfoWrapper(langtag,
983
LOCALE_INEGCURR | LOCALE_RETURN_NUMBER,
984
(LPWSTR)&pattern, sizeof(pattern));
985
} else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
986
got = getLocaleInfoWrapper(langtag,
987
LOCALE_INEGATIVEPERCENT | LOCALE_RETURN_NUMBER,
988
(LPWSTR)&pattern, sizeof(pattern));
989
} else {
990
got = getLocaleInfoWrapper(langtag,
991
LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
992
(LPWSTR)&pattern, sizeof(pattern));
993
}
994
}
995
996
if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
997
style = sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER;
998
}
999
1000
wcscpy(ret, fixes[!prefix][!positive][style][pattern]);
1001
}
1002
1003
int enumCalendarInfoWrapper(const jchar *langtag, CALID calid, CALTYPE type, LPWSTR buf, int buflen) {
1004
if (pEnumCalendarInfoExEx) {
1005
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
1006
// defaults to "en"
1007
return pEnumCalendarInfoExEx(&EnumCalendarInfoProc, L"en",
1008
calid, NULL, type, (LPARAM)buf);
1009
} else {
1010
return pEnumCalendarInfoExEx(&EnumCalendarInfoProc, langtag,
1011
calid, NULL, type, (LPARAM)buf);
1012
}
1013
} else {
1014
return 0;
1015
}
1016
}
1017
1018
BOOL CALLBACK EnumCalendarInfoProc(LPWSTR lpCalInfoStr, CALID calid, LPWSTR lpReserved, LPARAM lParam) {
1019
wcscat_s((LPWSTR)lParam, BUFLEN, lpCalInfoStr);
1020
wcscat_s((LPWSTR)lParam, BUFLEN, L",");
1021
return TRUE;
1022
}
1023
1024
jobjectArray getErasImpl(JNIEnv *env, jstring jlangtag, jint calid, jint style, jobjectArray eras) {
1025
const jchar * langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
1026
WCHAR buf[BUFLEN];
1027
jobjectArray ret = eras;
1028
CALTYPE type;
1029
1030
CHECK_NULL_RETURN(langtag, ret);
1031
1032
buf[0] = '\0';
1033
if (style & CALENDAR_STYLE_SHORT_MASK) {
1034
type = CAL_SABBREVERASTRING;
1035
} else {
1036
type = CAL_SERASTRING;
1037
}
1038
1039
if (calid < 0) {
1040
calid = getCalendarID(langtag);
1041
}
1042
1043
if (calid != -1 && enumCalendarInfoWrapper(langtag, calid, type, buf, BUFLEN)) {
1044
// format in buf: "era0,era1,era2," where era0 is the current one
1045
int eraCount;
1046
LPWSTR current;
1047
jsize array_length;
1048
1049
for(eraCount = 0, current = buf; *current != '\0'; current++) {
1050
if (*current == L',') {
1051
eraCount ++;
1052
}
1053
}
1054
1055
if (eras != NULL) {
1056
array_length = (*env)->GetArrayLength(env, eras);
1057
} else {
1058
// +1 for the "before" era, e.g., BC, which Windows does not return.
1059
array_length = (jsize)eraCount + 1;
1060
ret = (*env)->NewObjectArray(env, array_length,
1061
(*env)->FindClass(env, "java/lang/String"), NULL);
1062
}
1063
1064
if (ret != NULL) {
1065
int eraIndex;
1066
LPWSTR era;
1067
1068
for(eraIndex = 0, era = current = buf; eraIndex < eraCount; era = current, eraIndex++) {
1069
while (*current != L',') {
1070
current++;
1071
}
1072
*current++ = '\0';
1073
1074
if (eraCount - eraIndex < array_length &&
1075
*era != '\0') {
1076
(*env)->SetObjectArrayElement(env, ret,
1077
(jsize)(eraCount - eraIndex),
1078
(*env)->NewString(env, era, (jsize)wcslen(era)));
1079
}
1080
}
1081
1082
// Hack for the Japanese Imperial Calendar to insert Gregorian era for
1083
// "Before Meiji"
1084
if (calid == CAL_JAPAN) {
1085
buf[0] = '\0';
1086
if (enumCalendarInfoWrapper(langtag, CAL_GREGORIAN, type, buf, BUFLEN)) {
1087
jsize len = (jsize)wcslen(buf);
1088
buf[--len] = '\0'; // remove the last ','
1089
(*env)->SetObjectArrayElement(env, ret, 0, (*env)->NewString(env, buf, len));
1090
}
1091
}
1092
}
1093
}
1094
1095
(*env)->ReleaseStringChars(env, jlangtag, langtag);
1096
return ret;
1097
}
1098
1099