1 /*
2 * Copyright (c) 2012, 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
179 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
180 * Method: getDefaultLocale
181 * Signature: (I)Ljava/lang/String;
182 */
183 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDefaultLocale
184 (JNIEnv *env, jclass cls, jint cat) {
185 char * localeString = NULL;
186 LANGID langid;
187 jstring ret;
188
189 switch (cat) {
190 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_DISPLAY:
191 langid = LANGIDFROMLCID(GetUserDefaultUILanguage());
192 break;
193 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_FORMAT:
194 default:
195 langid = LANGIDFROMLCID(GetUserDefaultLCID());
196 break;
197 }
198
199 localeString = getJavaIDFromLangID(langid);
200 ret = (*env)->NewStringUTF(env, localeString);
201 free(localeString);
202 return ret;
203 }
204
205 /*
206 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
207 * Method: getDateTimePattern
208 * Signature: (IILjava/lang/String;)Ljava/lang/String;
209 */
210 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePattern
211 (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
212 WCHAR pattern[BUFLEN];
213 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
214
215 pattern[0] = L'\0';
216
217 if (dateStyle == 0 || dateStyle == 1) {
218 getLocaleInfoWrapper(langtag, LOCALE_SLONGDATE, pattern, BUFLEN);
219 } else if (dateStyle == 2 || dateStyle == 3) {
349 (JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {
350 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
351 jstring ret;
352
353 WCHAR * pattern = getNumberPattern(langtag, numberStyle);
354
355 (*env)->ReleaseStringChars(env, jlangtag, langtag);
356 ret = (*env)->NewString(env, pattern, wcslen(pattern));
357 free(pattern);
358
359 return ret;
360 }
361
362 /*
363 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
364 * Method: isNativeDigit
365 * Signature: (Ljava/lang/String;)Z
366 */
367 JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
368 (JNIEnv *env, jclass cls, jstring jlangtag) {
369 WCHAR buf[BUFLEN];
370 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
371 int got = getLocaleInfoWrapper(langtag, LOCALE_IDIGITSUBSTITUTION, buf, BUFLEN);
372 (*env)->ReleaseStringChars(env, jlangtag, langtag);
373
374 return got && buf[0] == L'2'; // 2: native digit substitution
375 }
376
377 /*
378 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
379 * Method: getCurrencySymbol
380 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
381 */
382 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
383 (JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
384 WCHAR buf[BUFLEN];
385 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
386 int got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
387 (*env)->ReleaseStringChars(env, jlangtag, langtag);
388
389 if (got) {
390 return (*env)->NewString(env, buf, wcslen(buf));
391 } else {
392 return currencySymbol;
393 }
394 }
573 (JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
574 WCHAR buf[BUFLEN];
575 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
576 int got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
577 (*env)->ReleaseStringChars(env, jlangtag, langtag);
578
579 if (got) {
580 return buf[0];
581 } else {
582 return zeroDigit;
583 }
584 }
585
586 /*
587 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
588 * Method: getCalendarDataValue
589 * Signature: (Ljava/lang/String;I)I
590 */
591 JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
592 (JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
593 WCHAR buf[BUFLEN];
594 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
595 int got = 0;
596
597 switch (type) {
598 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
599 got = getLocaleInfoWrapper(langtag, LOCALE_IFIRSTDAYOFWEEK, buf, BUFLEN);
600 break;
601 }
602
603 (*env)->ReleaseStringChars(env, jlangtag, langtag);
604
605 if (got) {
606 return _wtoi(buf);
607 } else {
608 return -1;
609 }
610 }
611
612 int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
613 if (pGetLocaleInfoEx) {
614 if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
615 // defaults to "en"
616 return pGetLocaleInfoEx(L"en", type, data, buflen);
617 } else {
618 return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen);
619 }
620 } else {
621 // If we ever wanted to support WinXP, we will need extra module from
622 // MS...
623 // return GetLocaleInfo(DownlevelLocaleNameToLCID(langtag, 0), type, data, buflen);
624 return 0;
625 }
626 }
627
628 int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val) {
629 if (pGetCalendarInfoEx) {
630 if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
631 // defaults to "en"
632 return pGetCalendarInfoEx(L"en", id, reserved, type, data, buflen, val);
633 } else {
634 return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val);
635 }
636 } else {
637 // If we ever wanted to support WinXP, we will need extra module from
638 // MS...
639 // return GetCalendarInfo(DownlevelLocaleNameToLCID(langtag, 0), ...);
640 return 0;
641 }
642 }
643
644 jint getCalendarID(const jchar *langtag) {
645 WCHAR type[BUFLEN];
646 int got = getLocaleInfoWrapper(langtag, LOCALE_ICALENDARTYPE, type, BUFLEN);
647
648 if (got) {
649 return _wtoi(type);
650 } else {
651 return 0;
652 }
653 }
654
655 void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) {
656 WCHAR name[BUFLEN];
657 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
658 int calid = getCalendarID(langtag);
659
660 if (calid != -1) {
661 int i;
662 for (i = 0; i < length; i++) {
663 getCalendarInfoWrapper(langtag, calid, NULL,
664 pCalTypes[i], name, BUFLEN, NULL);
665 (*env)->SetObjectArrayElement(env, jarray, i + offset,
666 (*env)->NewString(env, name, wcslen(name)));
667 }
668 }
669
674 WCHAR ret[BUFLEN];
675 WCHAR number[BUFLEN];
676 WCHAR fix[BUFLEN];
677
678 getFixPart(langtag, numberStyle, TRUE, TRUE, ret); // "+"
679 getNumberPart(langtag, numberStyle, number);
680 wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34"
681 getFixPart(langtag, numberStyle, TRUE, FALSE, fix);
682 wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$"
683 wcscat_s(ret, BUFLEN-wcslen(ret), L";"); // "+12.34$;"
684 getFixPart(langtag, numberStyle, FALSE, TRUE, fix);
685 wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;("
686 wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34$;(12.34"
687 getFixPart(langtag, numberStyle, FALSE, FALSE, fix);
688 wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;(12.34$)"
689
690 return _wcsdup(ret);
691 }
692
693 void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number) {
694 WCHAR buf[BUFLEN];
695 WCHAR grouping[BUFLEN];
696 WCHAR fractionPattern[BUFLEN];
697 WCHAR * integerPattern = number;
698 int digits;
699 BOOL leadingZero;
700 WCHAR * pDest;
701 int groupingLen;
702
703 // Get info from Windows
704 if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
705 getLocaleInfoWrapper(langtag, LOCALE_ICURRDIGITS, buf, BUFLEN);
706 } else {
707 getLocaleInfoWrapper(langtag, LOCALE_IDIGITS, buf, BUFLEN);
708 }
709 if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
710 digits = 0;
711 } else {
712 digits = _wtoi(buf);
713 }
714 getLocaleInfoWrapper(langtag, LOCALE_ILZERO, buf, BUFLEN);
715 leadingZero = _wtoi(buf) != 0;
716 groupingLen = getLocaleInfoWrapper(langtag, LOCALE_SGROUPING, grouping, BUFLEN);
717
718 // fraction pattern
719 if (digits > 0) {
720 int i;
721 for(i = digits; i > 0; i--) {
722 fractionPattern[i] = L'0';
723 }
724 fractionPattern[0] = L'.';
725 fractionPattern[digits+1] = L'\0';
726 } else {
727 fractionPattern[0] = L'\0';
728 }
729
730 // integer pattern
731 pDest = integerPattern;
732 if (groupingLen > 0) {
733 int cur = groupingLen - 1;// subtracting null terminator
734 while (--cur >= 0) {
735 int repnum;
736
737 if (grouping[cur] == L';') {
738 continue;
739 }
740
741 repnum = grouping[cur] - 0x30;
742 if (repnum > 0) {
743 *pDest++ = L'#';
744 *pDest++ = L',';
745 while(--repnum > 0) {
746 *pDest++ = L'#';
747 }
748 }
749 }
750 }
751
752 if (leadingZero) {
753 *pDest++ = L'0';
754 } else {
755 *pDest++ = L'#';
756 }
757 *pDest = L'\0';
758
759 wcscat_s(integerPattern, BUFLEN, fractionPattern);
760 }
761
762 void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret) {
763 WCHAR buf[BUFLEN];
764 int pattern = 0;
765 int style = numberStyle;
766 int got = 0;
767
768 if (positive) {
769 if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
770 got = getLocaleInfoWrapper(langtag, LOCALE_ICURRENCY, buf, BUFLEN);
771 } else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
772 got = getLocaleInfoWrapper(langtag, LOCALE_IPOSITIVEPERCENT, buf, BUFLEN);
773 }
774 } else {
775 if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
776 got = getLocaleInfoWrapper(langtag, LOCALE_INEGCURR, buf, BUFLEN);
777 } else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
778 got = getLocaleInfoWrapper(langtag, LOCALE_INEGATIVEPERCENT, buf, BUFLEN);
779 } else {
780 got = getLocaleInfoWrapper(langtag, LOCALE_INEGNUMBER, buf, BUFLEN);
781 }
782 }
783 if (got) {
784 pattern = _wtoi(buf);
785 }
786
787 if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
788 style = sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER;
789 }
790
791 wcscpy(ret, fixes[!prefix][!positive][style][pattern]);
792 }
|
1 /*
2 * Copyright (c) 2012, 2013, 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
179 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
180 * Method: getDefaultLocale
181 * Signature: (I)Ljava/lang/String;
182 */
183 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDefaultLocale
184 (JNIEnv *env, jclass cls, jint cat) {
185 char * localeString = NULL;
186 LANGID langid;
187 jstring ret;
188
189 switch (cat) {
190 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_DISPLAY:
191 langid = LANGIDFROMLCID(GetUserDefaultUILanguage());
192 break;
193 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CAT_FORMAT:
194 default:
195 langid = LANGIDFROMLCID(GetUserDefaultLCID());
196 break;
197 }
198
199 localeString = (char *)getJavaIDFromLangID(langid);
200 ret = (*env)->NewStringUTF(env, localeString);
201 free(localeString);
202 return ret;
203 }
204
205 /*
206 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
207 * Method: getDateTimePattern
208 * Signature: (IILjava/lang/String;)Ljava/lang/String;
209 */
210 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDateTimePattern
211 (JNIEnv *env, jclass cls, jint dateStyle, jint timeStyle, jstring jlangtag) {
212 WCHAR pattern[BUFLEN];
213 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
214
215 pattern[0] = L'\0';
216
217 if (dateStyle == 0 || dateStyle == 1) {
218 getLocaleInfoWrapper(langtag, LOCALE_SLONGDATE, pattern, BUFLEN);
219 } else if (dateStyle == 2 || dateStyle == 3) {
349 (JNIEnv *env, jclass cls, jint numberStyle, jstring jlangtag) {
350 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
351 jstring ret;
352
353 WCHAR * pattern = getNumberPattern(langtag, numberStyle);
354
355 (*env)->ReleaseStringChars(env, jlangtag, langtag);
356 ret = (*env)->NewString(env, pattern, wcslen(pattern));
357 free(pattern);
358
359 return ret;
360 }
361
362 /*
363 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
364 * Method: isNativeDigit
365 * Signature: (Ljava/lang/String;)Z
366 */
367 JNIEXPORT jboolean JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_isNativeDigit
368 (JNIEnv *env, jclass cls, jstring jlangtag) {
369 DWORD num;
370 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
371 int got = getLocaleInfoWrapper(langtag,
372 LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER,
373 (LPWSTR)&num, sizeof(num));
374 (*env)->ReleaseStringChars(env, jlangtag, langtag);
375
376 return got && num == 2; // 2: native digit substitution
377 }
378
379 /*
380 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
381 * Method: getCurrencySymbol
382 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
383 */
384 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCurrencySymbol
385 (JNIEnv *env, jclass cls, jstring jlangtag, jstring currencySymbol) {
386 WCHAR buf[BUFLEN];
387 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
388 int got = getLocaleInfoWrapper(langtag, LOCALE_SCURRENCY, buf, BUFLEN);
389 (*env)->ReleaseStringChars(env, jlangtag, langtag);
390
391 if (got) {
392 return (*env)->NewString(env, buf, wcslen(buf));
393 } else {
394 return currencySymbol;
395 }
396 }
575 (JNIEnv *env, jclass cls, jstring jlangtag, jchar zeroDigit) {
576 WCHAR buf[BUFLEN];
577 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
578 int got = getLocaleInfoWrapper(langtag, LOCALE_SNATIVEDIGITS, buf, BUFLEN);
579 (*env)->ReleaseStringChars(env, jlangtag, langtag);
580
581 if (got) {
582 return buf[0];
583 } else {
584 return zeroDigit;
585 }
586 }
587
588 /*
589 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
590 * Method: getCalendarDataValue
591 * Signature: (Ljava/lang/String;I)I
592 */
593 JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getCalendarDataValue
594 (JNIEnv *env, jclass cls, jstring jlangtag, jint type) {
595 DWORD num;
596 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
597 int got = 0;
598
599 switch (type) {
600 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_CD_FIRSTDAYOFWEEK:
601 got = getLocaleInfoWrapper(langtag,
602 LOCALE_IFIRSTDAYOFWEEK | LOCALE_RETURN_NUMBER,
603 (LPWSTR)&num, sizeof(num));
604 break;
605 }
606
607 (*env)->ReleaseStringChars(env, jlangtag, langtag);
608
609 if (got) {
610 return num;
611 } else {
612 return -1;
613 }
614 }
615
616 /*
617 * Class: sun_util_locale_provider_HostLocaleProviderAdapterImpl
618 * Method: getDisplayString
619 * Signature: (Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
620 */
621 JNIEXPORT jstring JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterImpl_getDisplayString
622 (JNIEnv *env, jclass cls, jstring jlangtag, jint type, jstring jvalue) {
623 LCTYPE lcType;
624 jstring jStr;
625 const jchar * pjChar;
626 WCHAR buf[BUFLEN];
627 int got = 0;
628
629 switch (type) {
630 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_NAME:
631 lcType = LOCALE_SNATIVECURRNAME;
632 jStr = jlangtag;
633 break;
634 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_CURRENCY_SYMBOL:
635 lcType = LOCALE_SCURRENCY;
636 jStr = jlangtag;
637 break;
638 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_LANGUAGE:
639 lcType = LOCALE_SLOCALIZEDLANGUAGENAME;
640 jStr = jvalue;
641 break;
642 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_DN_LOCALE_REGION:
643 lcType = LOCALE_SLOCALIZEDCOUNTRYNAME;
644 jStr = jvalue;
645 break;
646 default:
647 return NULL;
648 }
649
650 pjChar = (*env)->GetStringChars(env, jStr, JNI_FALSE);
651 got = getLocaleInfoWrapper(pjChar, lcType, buf, BUFLEN);
652 (*env)->ReleaseStringChars(env, jStr, pjChar);
653
654 if (got) {
655 return (*env)->NewString(env, buf, wcslen(buf));
656 } else {
657 return NULL;
658 }
659 }
660
661 int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
662 if (pGetLocaleInfoEx) {
663 if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
664 // defaults to "en"
665 return pGetLocaleInfoEx(L"en", type, data, buflen);
666 } else {
667 return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen);
668 }
669 } else {
670 // If we ever wanted to support WinXP, we will need extra module from
671 // MS...
672 // return GetLocaleInfo(DownlevelLocaleNameToLCID(langtag, 0), type, data, buflen);
673 return 0;
674 }
675 }
676
677 int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val) {
678 if (pGetCalendarInfoEx) {
679 if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
680 // defaults to "en"
681 return pGetCalendarInfoEx(L"en", id, reserved, type, data, buflen, val);
682 } else {
683 return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val);
684 }
685 } else {
686 // If we ever wanted to support WinXP, we will need extra module from
687 // MS...
688 // return GetCalendarInfo(DownlevelLocaleNameToLCID(langtag, 0), ...);
689 return 0;
690 }
691 }
692
693 jint getCalendarID(const jchar *langtag) {
694 DWORD type;
695 int got = getLocaleInfoWrapper(langtag,
696 LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
697 (LPWSTR)&type, sizeof(type));
698
699 if (got) {
700 return type;
701 } else {
702 return 0;
703 }
704 }
705
706 void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jobjectArray jarray, CALTYPE* pCalTypes, int offset, int length) {
707 WCHAR name[BUFLEN];
708 const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE);
709 int calid = getCalendarID(langtag);
710
711 if (calid != -1) {
712 int i;
713 for (i = 0; i < length; i++) {
714 getCalendarInfoWrapper(langtag, calid, NULL,
715 pCalTypes[i], name, BUFLEN, NULL);
716 (*env)->SetObjectArrayElement(env, jarray, i + offset,
717 (*env)->NewString(env, name, wcslen(name)));
718 }
719 }
720
725 WCHAR ret[BUFLEN];
726 WCHAR number[BUFLEN];
727 WCHAR fix[BUFLEN];
728
729 getFixPart(langtag, numberStyle, TRUE, TRUE, ret); // "+"
730 getNumberPart(langtag, numberStyle, number);
731 wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34"
732 getFixPart(langtag, numberStyle, TRUE, FALSE, fix);
733 wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$"
734 wcscat_s(ret, BUFLEN-wcslen(ret), L";"); // "+12.34$;"
735 getFixPart(langtag, numberStyle, FALSE, TRUE, fix);
736 wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;("
737 wcscat_s(ret, BUFLEN-wcslen(ret), number); // "+12.34$;(12.34"
738 getFixPart(langtag, numberStyle, FALSE, FALSE, fix);
739 wcscat_s(ret, BUFLEN-wcslen(ret), fix); // "+12.34$;(12.34$)"
740
741 return _wcsdup(ret);
742 }
743
744 void getNumberPart(const jchar * langtag, const jint numberStyle, WCHAR * number) {
745 DWORD digits = 0;
746 DWORD leadingZero = 0;
747 WCHAR grouping[BUFLEN];
748 int groupingLen;
749 WCHAR fractionPattern[BUFLEN];
750 WCHAR * integerPattern = number;
751 WCHAR * pDest;
752
753 // Get info from Windows
754 switch (numberStyle) {
755 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY:
756 getLocaleInfoWrapper(langtag,
757 LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER,
758 (LPWSTR)&digits, sizeof(digits));
759 break;
760
761 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER:
762 break;
763
764 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER:
765 case sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT:
766 default:
767 getLocaleInfoWrapper(langtag,
768 LOCALE_IDIGITS | LOCALE_RETURN_NUMBER,
769 (LPWSTR)&digits, sizeof(digits));
770 break;
771 }
772
773 getLocaleInfoWrapper(langtag,
774 LOCALE_ILZERO | LOCALE_RETURN_NUMBER,
775 (LPWSTR)&leadingZero, sizeof(leadingZero));
776 groupingLen = getLocaleInfoWrapper(langtag, LOCALE_SGROUPING, grouping, BUFLEN);
777
778 // fraction pattern
779 if (digits > 0) {
780 int i;
781 for(i = digits; i > 0; i--) {
782 fractionPattern[i] = L'0';
783 }
784 fractionPattern[0] = L'.';
785 fractionPattern[digits+1] = L'\0';
786 } else {
787 fractionPattern[0] = L'\0';
788 }
789
790 // integer pattern
791 pDest = integerPattern;
792 if (groupingLen > 0) {
793 int cur = groupingLen - 1;// subtracting null terminator
794 while (--cur >= 0) {
795 int repnum;
796
797 if (grouping[cur] == L';') {
798 continue;
799 }
800
801 repnum = grouping[cur] - 0x30;
802 if (repnum > 0) {
803 *pDest++ = L'#';
804 *pDest++ = L',';
805 while(--repnum > 0) {
806 *pDest++ = L'#';
807 }
808 }
809 }
810 }
811
812 if (leadingZero != 0) {
813 *pDest++ = L'0';
814 } else {
815 *pDest++ = L'#';
816 }
817 *pDest = L'\0';
818
819 wcscat_s(integerPattern, BUFLEN, fractionPattern);
820 }
821
822 void getFixPart(const jchar * langtag, const jint numberStyle, BOOL positive, BOOL prefix, WCHAR * ret) {
823 DWORD pattern = 0;
824 int style = numberStyle;
825 int got = 0;
826
827 if (positive) {
828 if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
829 got = getLocaleInfoWrapper(langtag,
830 LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
831 (LPWSTR)&pattern, sizeof(pattern));
832 } else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
833 got = getLocaleInfoWrapper(langtag,
834 LOCALE_IPOSITIVEPERCENT | LOCALE_RETURN_NUMBER,
835 (LPWSTR)&pattern, sizeof(pattern));
836 }
837 } else {
838 if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_CURRENCY) {
839 got = getLocaleInfoWrapper(langtag,
840 LOCALE_INEGCURR | LOCALE_RETURN_NUMBER,
841 (LPWSTR)&pattern, sizeof(pattern));
842 } else if (style == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_PERCENT) {
843 got = getLocaleInfoWrapper(langtag,
844 LOCALE_INEGATIVEPERCENT | LOCALE_RETURN_NUMBER,
845 (LPWSTR)&pattern, sizeof(pattern));
846 } else {
847 got = getLocaleInfoWrapper(langtag,
848 LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
849 (LPWSTR)&pattern, sizeof(pattern));
850 }
851 }
852
853 if (numberStyle == sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_INTEGER) {
854 style = sun_util_locale_provider_HostLocaleProviderAdapterImpl_NF_NUMBER;
855 }
856
857 wcscpy(ret, fixes[!prefix][!positive][style][pattern]);
858 }
|