Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: source/common/uloc_tag.c

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/common/uloc_keytype.cpp ('k') | source/common/ulocimp.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ********************************************************************** 2 **********************************************************************
3 * Copyright (C) 2009-2012, International Business Machines 3 * Copyright (C) 2009-2014, International Business Machines
4 * Corporation and others. All Rights Reserved. 4 * Corporation and others. All Rights Reserved.
5 ********************************************************************** 5 **********************************************************************
6 */ 6 */
7 7
8 #include "unicode/utypes.h" 8 #include "unicode/utypes.h"
9 #include "unicode/ures.h" 9 #include "unicode/ures.h"
10 #include "unicode/putil.h" 10 #include "unicode/putil.h"
11 #include "unicode/uloc.h" 11 #include "unicode/uloc.h"
12 #include "ustr_imp.h" 12 #include "ustr_imp.h"
13 #include "cmemory.h" 13 #include "cmemory.h"
14 #include "cstring.h" 14 #include "cstring.h"
15 #include "putilimp.h" 15 #include "putilimp.h"
16 #include "uinvchar.h" 16 #include "uinvchar.h"
17 #include "ulocimp.h" 17 #include "ulocimp.h"
18 #include "uassert.h" 18 #include "uassert.h"
19 19
20 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
21
22 /* struct holding a single variant */ 20 /* struct holding a single variant */
23 typedef struct VariantListEntry { 21 typedef struct VariantListEntry {
24 const char *variant; 22 const char *variant;
25 struct VariantListEntry *next; 23 struct VariantListEntry *next;
26 } VariantListEntry; 24 } VariantListEntry;
27 25
28 /* struct holding a single attribute value */ 26 /* struct holding a single attribute value */
29 typedef struct AttributeListEntry { 27 typedef struct AttributeListEntry {
30 const char *attribute; 28 const char *attribute;
31 struct AttributeListEntry *next; 29 struct AttributeListEntry *next;
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 pSubtag = p; 401 pSubtag = p;
404 } 402 }
405 p++; 403 p++;
406 } 404 }
407 if (pSubtag == NULL) { 405 if (pSubtag == NULL) {
408 return FALSE; 406 return FALSE;
409 } 407 }
410 return _isPrivateuseValueSubtag(pSubtag, (int32_t)(p - pSubtag)); 408 return _isPrivateuseValueSubtag(pSubtag, (int32_t)(p - pSubtag));
411 } 409 }
412 410
413 static UBool 411 U_CFUNC UBool
414 _isLDMLKey(const char* s, int32_t len) { 412 ultag_isUnicodeLocaleKey(const char* s, int32_t len) {
415 if (len < 0) { 413 if (len < 0) {
416 len = (int32_t)uprv_strlen(s); 414 len = (int32_t)uprv_strlen(s);
417 } 415 }
418 if (len == 2 && _isAlphaNumericString(s, len)) { 416 if (len == 2 && _isAlphaNumericString(s, len)) {
419 return TRUE; 417 return TRUE;
420 } 418 }
421 return FALSE; 419 return FALSE;
422 } 420 }
423 421
424 static UBool 422 U_CFUNC UBool
425 _isLDMLType(const char* s, int32_t len) { 423 ultag_isUnicodeLocaleType(const char*s, int32_t len) {
424 const char* p;
425 int32_t subtagLen = 0;
426
426 if (len < 0) { 427 if (len < 0) {
427 len = (int32_t)uprv_strlen(s); 428 len = (int32_t)uprv_strlen(s);
428 } 429 }
429 if (len >= 3 && len <= 8 && _isAlphaNumericString(s, len)) { 430
430 return TRUE; 431 for (p = s; len > 0; p++, len--) {
432 if (*p == SEP) {
433 if (subtagLen < 3) {
434 return FALSE;
435 }
436 subtagLen = 0;
437 } else if (ISALPHA(*p) || ISNUMERIC(*p)) {
438 subtagLen++;
439 if (subtagLen > 8) {
440 return FALSE;
441 }
442 } else {
443 return FALSE;
444 }
431 } 445 }
432 return FALSE; 446
447 return (subtagLen >= 3);
433 } 448 }
434
435 /* 449 /*
436 * ------------------------------------------------- 450 * -------------------------------------------------
437 * 451 *
438 * Helper functions 452 * Helper functions
439 * 453 *
440 * ------------------------------------------------- 454 * -------------------------------------------------
441 */ 455 */
442 456
443 static UBool 457 static UBool
444 _addVariantToList(VariantListEntry **first, VariantListEntry *var) { 458 _addVariantToList(VariantListEntry **first, VariantListEntry *var) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 langtag->script = EMPTY; 617 langtag->script = EMPTY;
604 langtag->region = EMPTY; 618 langtag->region = EMPTY;
605 619
606 langtag->variants = NULL; 620 langtag->variants = NULL;
607 langtag->extensions = NULL; 621 langtag->extensions = NULL;
608 622
609 langtag->grandfathered = EMPTY; 623 langtag->grandfathered = EMPTY;
610 langtag->privateuse = EMPTY; 624 langtag->privateuse = EMPTY;
611 } 625 }
612 626
613 #define KEYTYPEDATA "keyTypeData"
614 #define KEYMAP "keyMap"
615 #define TYPEMAP "typeMap"
616 #define TYPEALIAS "typeAlias"
617 #define MAX_BCP47_SUBTAG_LEN 9 /* including null terminator */
618 #define MAX_LDML_KEY_LEN 22
619 #define MAX_LDML_TYPE_LEN 32
620
621 static int32_t
622 _ldmlKeyToBCP47(const char* key, int32_t keyLen,
623 char* bcpKey, int32_t bcpKeyCapacity,
624 UErrorCode *status) {
625 UResourceBundle *rb;
626 char keyBuf[MAX_LDML_KEY_LEN];
627 char bcpKeyBuf[MAX_BCP47_SUBTAG_LEN];
628 int32_t resultLen = 0;
629 int32_t i;
630 UErrorCode tmpStatus = U_ZERO_ERROR;
631 const UChar *uBcpKey;
632 int32_t bcpKeyLen;
633
634 if (keyLen < 0) {
635 keyLen = (int32_t)uprv_strlen(key);
636 }
637
638 if (keyLen >= sizeof(keyBuf)) {
639 /* no known valid LDML key exceeding 21 */
640 *status = U_ILLEGAL_ARGUMENT_ERROR;
641 return 0;
642 }
643
644 uprv_memcpy(keyBuf, key, keyLen);
645 keyBuf[keyLen] = 0;
646
647 /* to lower case */
648 for (i = 0; i < keyLen; i++) {
649 keyBuf[i] = uprv_tolower(keyBuf[i]);
650 }
651
652 rb = ures_openDirect(NULL, KEYTYPEDATA, status);
653 ures_getByKey(rb, KEYMAP, rb, status);
654
655 if (U_FAILURE(*status)) {
656 ures_close(rb);
657 return 0;
658 }
659
660 uBcpKey = ures_getStringByKey(rb, keyBuf, &bcpKeyLen, &tmpStatus);
661 if (U_SUCCESS(tmpStatus)) {
662 u_UCharsToChars(uBcpKey, bcpKeyBuf, bcpKeyLen);
663 bcpKeyBuf[bcpKeyLen] = 0;
664 resultLen = bcpKeyLen;
665 } else {
666 if (_isLDMLKey(key, keyLen)) {
667 uprv_memcpy(bcpKeyBuf, key, keyLen);
668 bcpKeyBuf[keyLen] = 0;
669 resultLen = keyLen;
670 } else {
671 /* mapping not availabe */
672 *status = U_ILLEGAL_ARGUMENT_ERROR;
673 }
674 }
675 ures_close(rb);
676
677 if (U_FAILURE(*status)) {
678 return 0;
679 }
680
681 uprv_memcpy(bcpKey, bcpKeyBuf, uprv_min(resultLen, bcpKeyCapacity));
682 return u_terminateChars(bcpKey, bcpKeyCapacity, resultLen, status);
683 }
684
685 static int32_t
686 _bcp47ToLDMLKey(const char* bcpKey, int32_t bcpKeyLen,
687 char* key, int32_t keyCapacity,
688 UErrorCode *status) {
689 UResourceBundle *rb;
690 char bcpKeyBuf[MAX_BCP47_SUBTAG_LEN];
691 int32_t resultLen = 0;
692 int32_t i;
693 const char *resKey = NULL;
694 UResourceBundle *mapData;
695
696 if (bcpKeyLen < 0) {
697 bcpKeyLen = (int32_t)uprv_strlen(bcpKey);
698 }
699
700 if (bcpKeyLen >= sizeof(bcpKeyBuf)) {
701 *status = U_ILLEGAL_ARGUMENT_ERROR;
702 return 0;
703 }
704
705 uprv_memcpy(bcpKeyBuf, bcpKey, bcpKeyLen);
706 bcpKeyBuf[bcpKeyLen] = 0;
707
708 /* to lower case */
709 for (i = 0; i < bcpKeyLen; i++) {
710 bcpKeyBuf[i] = uprv_tolower(bcpKeyBuf[i]);
711 }
712
713 rb = ures_openDirect(NULL, KEYTYPEDATA, status);
714 ures_getByKey(rb, KEYMAP, rb, status);
715 if (U_FAILURE(*status)) {
716 ures_close(rb);
717 return 0;
718 }
719
720 mapData = ures_getNextResource(rb, NULL, status);
721 while (U_SUCCESS(*status)) {
722 const UChar *uBcpKey;
723 char tmpBcpKeyBuf[MAX_BCP47_SUBTAG_LEN];
724 int32_t tmpBcpKeyLen;
725
726 uBcpKey = ures_getString(mapData, &tmpBcpKeyLen, status);
727 if (U_FAILURE(*status)) {
728 break;
729 }
730 u_UCharsToChars(uBcpKey, tmpBcpKeyBuf, tmpBcpKeyLen);
731 tmpBcpKeyBuf[tmpBcpKeyLen] = 0;
732 if (uprv_compareInvCharsAsAscii(bcpKeyBuf, tmpBcpKeyBuf) == 0) {
733 /* found a matching BCP47 key */
734 resKey = ures_getKey(mapData);
735 resultLen = (int32_t)uprv_strlen(resKey);
736 break;
737 }
738 if (!ures_hasNext(rb)) {
739 break;
740 }
741 ures_getNextResource(rb, mapData, status);
742 }
743 ures_close(mapData);
744 ures_close(rb);
745
746 if (U_FAILURE(*status)) {
747 return 0;
748 }
749
750 if (resKey == NULL) {
751 resKey = bcpKeyBuf;
752 resultLen = bcpKeyLen;
753 }
754
755 uprv_memcpy(key, resKey, uprv_min(resultLen, keyCapacity));
756 return u_terminateChars(key, keyCapacity, resultLen, status);
757 }
758
759 static int32_t
760 _ldmlTypeToBCP47(const char* key, int32_t keyLen,
761 const char* type, int32_t typeLen,
762 char* bcpType, int32_t bcpTypeCapacity,
763 UErrorCode *status) {
764 UResourceBundle *rb, *keyTypeData, *typeMapForKey;
765 char keyBuf[MAX_LDML_KEY_LEN];
766 char typeBuf[MAX_LDML_TYPE_LEN];
767 char bcpTypeBuf[MAX_BCP47_SUBTAG_LEN];
768 int32_t resultLen = 0;
769 int32_t i;
770 UErrorCode tmpStatus = U_ZERO_ERROR;
771 const UChar *uBcpType, *uCanonicalType;
772 int32_t bcpTypeLen, canonicalTypeLen;
773 UBool isTimezone = FALSE;
774
775 if (keyLen < 0) {
776 keyLen = (int32_t)uprv_strlen(key);
777 }
778 if (keyLen >= sizeof(keyBuf)) {
779 /* no known valid LDML key exceeding 21 */
780 *status = U_ILLEGAL_ARGUMENT_ERROR;
781 return 0;
782 }
783 uprv_memcpy(keyBuf, key, keyLen);
784 keyBuf[keyLen] = 0;
785
786 /* to lower case */
787 for (i = 0; i < keyLen; i++) {
788 keyBuf[i] = uprv_tolower(keyBuf[i]);
789 }
790 if (uprv_compareInvCharsAsAscii(keyBuf, "timezone") == 0) {
791 isTimezone = TRUE;
792 }
793
794 if (typeLen < 0) {
795 typeLen = (int32_t)uprv_strlen(type);
796 }
797 if (typeLen >= sizeof(typeBuf)) {
798 *status = U_ILLEGAL_ARGUMENT_ERROR;
799 return 0;
800 }
801
802 if (isTimezone) {
803 /* replace '/' with ':' */
804 for (i = 0; i < typeLen; i++) {
805 if (*(type + i) == '/') {
806 typeBuf[i] = ':';
807 } else {
808 typeBuf[i] = *(type + i);
809 }
810 }
811 typeBuf[typeLen] = 0;
812 type = &typeBuf[0];
813 }
814
815 keyTypeData = ures_openDirect(NULL, KEYTYPEDATA, status);
816 rb = ures_getByKey(keyTypeData, TYPEMAP, NULL, status);
817 if (U_FAILURE(*status)) {
818 ures_close(rb);
819 ures_close(keyTypeData);
820 return 0;
821 }
822
823 typeMapForKey = ures_getByKey(rb, keyBuf, NULL, &tmpStatus);
824 uBcpType = ures_getStringByKey(typeMapForKey, type, &bcpTypeLen, &tmpStatus) ;
825 if (U_SUCCESS(tmpStatus)) {
826 u_UCharsToChars(uBcpType, bcpTypeBuf, bcpTypeLen);
827 resultLen = bcpTypeLen;
828 } else if (tmpStatus == U_MISSING_RESOURCE_ERROR) {
829 /* is this type alias? */
830 tmpStatus = U_ZERO_ERROR;
831 ures_getByKey(keyTypeData, TYPEALIAS, rb, &tmpStatus);
832 ures_getByKey(rb, keyBuf, rb, &tmpStatus);
833 uCanonicalType = ures_getStringByKey(rb, type, &canonicalTypeLen, &tmpSt atus);
834 if (U_SUCCESS(tmpStatus)) {
835 u_UCharsToChars(uCanonicalType, typeBuf, canonicalTypeLen);
836 if (isTimezone) {
837 /* replace '/' with ':' */
838 for (i = 0; i < canonicalTypeLen; i++) {
839 if (typeBuf[i] == '/') {
840 typeBuf[i] = ':';
841 }
842 }
843 }
844 typeBuf[canonicalTypeLen] = 0;
845
846 /* look up the canonical type */
847 uBcpType = ures_getStringByKey(typeMapForKey, typeBuf, &bcpTypeLen, &tmpStatus);
848 if (U_SUCCESS(tmpStatus)) {
849 u_UCharsToChars(uBcpType, bcpTypeBuf, bcpTypeLen);
850 resultLen = bcpTypeLen;
851 }
852 }
853 if (tmpStatus == U_MISSING_RESOURCE_ERROR) {
854 if (_isLDMLType(type, typeLen)) {
855 uprv_memcpy(bcpTypeBuf, type, typeLen);
856 resultLen = typeLen;
857 } else {
858 /* mapping not availabe */
859 *status = U_ILLEGAL_ARGUMENT_ERROR;
860 }
861 }
862 } else {
863 *status = tmpStatus;
864 }
865 ures_close(rb);
866 ures_close(typeMapForKey);
867 ures_close(keyTypeData);
868
869 if (U_FAILURE(*status)) {
870 return 0;
871 }
872
873 uprv_memcpy(bcpType, bcpTypeBuf, uprv_min(resultLen, bcpTypeCapacity));
874 return u_terminateChars(bcpType, bcpTypeCapacity, resultLen, status);
875 }
876
877 static int32_t
878 _bcp47ToLDMLType(const char* key, int32_t keyLen,
879 const char* bcpType, int32_t bcpTypeLen,
880 char* type, int32_t typeCapacity,
881 UErrorCode *status) {
882 UResourceBundle *rb;
883 char keyBuf[MAX_LDML_KEY_LEN];
884 char bcpTypeBuf[ULOC_KEYWORDS_CAPACITY]; /* ensure buffter is large enough f or multiple values (e.g. buddhist-greg) */
885 int32_t resultLen = 0;
886 int32_t i, typeSize;
887 const char *resType = NULL;
888 UResourceBundle *mapData;
889 UErrorCode tmpStatus = U_ZERO_ERROR;
890 int32_t copyLen;
891
892 if (keyLen < 0) {
893 keyLen = (int32_t)uprv_strlen(key);
894 }
895
896 if (keyLen >= sizeof(keyBuf)) {
897 /* no known valid LDML key exceeding 21 */
898 *status = U_ILLEGAL_ARGUMENT_ERROR;
899 return 0;
900 }
901 uprv_memcpy(keyBuf, key, keyLen);
902 keyBuf[keyLen] = 0;
903
904 /* to lower case */
905 for (i = 0; i < keyLen; i++) {
906 keyBuf[i] = uprv_tolower(keyBuf[i]);
907 }
908
909
910 if (bcpTypeLen < 0) {
911 bcpTypeLen = (int32_t)uprv_strlen(bcpType);
912 }
913
914 typeSize = 0;
915 for (i = 0; i < bcpTypeLen; i++) {
916 if (bcpType[i] == SEP) {
917 if (typeSize >= MAX_BCP47_SUBTAG_LEN) {
918 *status = U_ILLEGAL_ARGUMENT_ERROR;
919 return 0;
920 }
921 typeSize = 0;
922 } else {
923 typeSize++;
924 }
925 }
926
927 uprv_memcpy(bcpTypeBuf, bcpType, bcpTypeLen);
928 bcpTypeBuf[bcpTypeLen] = 0;
929
930 /* to lower case */
931 for (i = 0; i < bcpTypeLen; i++) {
932 bcpTypeBuf[i] = uprv_tolower(bcpTypeBuf[i]);
933 }
934
935 rb = ures_openDirect(NULL, KEYTYPEDATA, status);
936 ures_getByKey(rb, TYPEMAP, rb, status);
937 if (U_FAILURE(*status)) {
938 ures_close(rb);
939 return 0;
940 }
941
942 ures_getByKey(rb, keyBuf, rb, &tmpStatus);
943 mapData = ures_getNextResource(rb, NULL, &tmpStatus);
944 while (U_SUCCESS(tmpStatus)) {
945 const UChar *uBcpType;
946 char tmpBcpTypeBuf[MAX_BCP47_SUBTAG_LEN];
947 int32_t tmpBcpTypeLen;
948
949 uBcpType = ures_getString(mapData, &tmpBcpTypeLen, &tmpStatus);
950 if (U_FAILURE(tmpStatus)) {
951 break;
952 }
953 u_UCharsToChars(uBcpType, tmpBcpTypeBuf, tmpBcpTypeLen);
954 tmpBcpTypeBuf[tmpBcpTypeLen] = 0;
955 if (uprv_compareInvCharsAsAscii(bcpTypeBuf, tmpBcpTypeBuf) == 0) {
956 /* found a matching BCP47 type */
957 resType = ures_getKey(mapData);
958 resultLen = (int32_t)uprv_strlen(resType);
959 break;
960 }
961 if (!ures_hasNext(rb)) {
962 break;
963 }
964 ures_getNextResource(rb, mapData, &tmpStatus);
965 }
966 ures_close(mapData);
967 ures_close(rb);
968
969 if (U_FAILURE(tmpStatus) && tmpStatus != U_MISSING_RESOURCE_ERROR) {
970 *status = tmpStatus;
971 return 0;
972 }
973
974 if (resType == NULL) {
975 resType = bcpTypeBuf;
976 resultLen = bcpTypeLen;
977 }
978
979 copyLen = uprv_min(resultLen, typeCapacity);
980 uprv_memcpy(type, resType, copyLen);
981
982 if (uprv_compareInvCharsAsAscii(keyBuf, "timezone") == 0) {
983 for (i = 0; i < copyLen; i++) {
984 if (*(type + i) == ':') {
985 *(type + i) = '/';
986 }
987 }
988 }
989
990 return u_terminateChars(type, typeCapacity, resultLen, status);
991 }
992
993 static int32_t 627 static int32_t
994 _appendLanguageToLanguageTag(const char* localeID, char* appendAt, int32_t capac ity, UBool strict, UErrorCode* status) { 628 _appendLanguageToLanguageTag(const char* localeID, char* appendAt, int32_t capac ity, UBool strict, UErrorCode* status) {
995 char buf[ULOC_LANG_CAPACITY]; 629 char buf[ULOC_LANG_CAPACITY];
996 UErrorCode tmpStatus = U_ZERO_ERROR; 630 UErrorCode tmpStatus = U_ZERO_ERROR;
997 int32_t len, i; 631 int32_t len, i;
998 int32_t reslen = 0; 632 int32_t reslen = 0;
999 633
1000 if (U_FAILURE(*status)) { 634 if (U_FAILURE(*status)) {
1001 return 0; 635 return 0;
1002 } 636 }
(...skipping 19 matching lines...) Expand all
1022 if (strict) { 656 if (strict) {
1023 *status = U_ILLEGAL_ARGUMENT_ERROR; 657 *status = U_ILLEGAL_ARGUMENT_ERROR;
1024 return 0; 658 return 0;
1025 } 659 }
1026 if (reslen < capacity) { 660 if (reslen < capacity) {
1027 uprv_memcpy(appendAt + reslen, LANG_UND, uprv_min(LANG_UND_LEN, capa city - reslen)); 661 uprv_memcpy(appendAt + reslen, LANG_UND, uprv_min(LANG_UND_LEN, capa city - reslen));
1028 } 662 }
1029 reslen += LANG_UND_LEN; 663 reslen += LANG_UND_LEN;
1030 } else { 664 } else {
1031 /* resolve deprecated */ 665 /* resolve deprecated */
1032 for (i = 0; i < LENGTHOF(DEPRECATEDLANGS); i += 2) { 666 for (i = 0; i < UPRV_LENGTHOF(DEPRECATEDLANGS); i += 2) {
1033 if (uprv_compareInvCharsAsAscii(buf, DEPRECATEDLANGS[i]) == 0) { 667 if (uprv_compareInvCharsAsAscii(buf, DEPRECATEDLANGS[i]) == 0) {
1034 uprv_strcpy(buf, DEPRECATEDLANGS[i + 1]); 668 uprv_strcpy(buf, DEPRECATEDLANGS[i + 1]);
1035 len = (int32_t)uprv_strlen(buf); 669 len = (int32_t)uprv_strlen(buf);
1036 break; 670 break;
1037 } 671 }
1038 } 672 }
1039 if (reslen < capacity) { 673 if (reslen < capacity) {
1040 uprv_memcpy(appendAt + reslen, buf, uprv_min(len, capacity - reslen) ); 674 uprv_memcpy(appendAt + reslen, buf, uprv_min(len, capacity - reslen) );
1041 } 675 }
1042 reslen += len; 676 reslen += len;
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 ExtensionListEntry *ext; 909 ExtensionListEntry *ext;
1276 AttributeListEntry *firstAttr = NULL; 910 AttributeListEntry *firstAttr = NULL;
1277 AttributeListEntry *attr; 911 AttributeListEntry *attr;
1278 char *attrValue; 912 char *attrValue;
1279 char extBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY]; 913 char extBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
1280 char *pExtBuf = extBuf; 914 char *pExtBuf = extBuf;
1281 int32_t extBufCapacity = sizeof(extBuf); 915 int32_t extBufCapacity = sizeof(extBuf);
1282 const char *bcpKey, *bcpValue; 916 const char *bcpKey, *bcpValue;
1283 UErrorCode tmpStatus = U_ZERO_ERROR; 917 UErrorCode tmpStatus = U_ZERO_ERROR;
1284 int32_t keylen; 918 int32_t keylen;
1285 UBool isLDMLKeyword; 919 UBool isBcpUExt;
1286 920
1287 while (TRUE) { 921 while (TRUE) {
1288 isAttribute = FALSE; 922 isAttribute = FALSE;
1289 key = uenum_next(keywordEnum, NULL, status); 923 key = uenum_next(keywordEnum, NULL, status);
1290 if (key == NULL) { 924 if (key == NULL) {
1291 break; 925 break;
1292 } 926 }
1293 len = uloc_getKeywordValue(localeID, key, buf, sizeof(buf), &tmpStat us); 927 len = uloc_getKeywordValue(localeID, key, buf, sizeof(buf), &tmpStat us);
1294 if (U_FAILURE(tmpStatus)) { 928 /* buf must be null-terminated */
929 if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WAR NING) {
1295 if (strict) { 930 if (strict) {
1296 *status = U_ILLEGAL_ARGUMENT_ERROR; 931 *status = U_ILLEGAL_ARGUMENT_ERROR;
1297 break; 932 break;
1298 } 933 }
1299 /* ignore this keyword */ 934 /* ignore this keyword */
1300 tmpStatus = U_ZERO_ERROR; 935 tmpStatus = U_ZERO_ERROR;
1301 continue; 936 continue;
1302 } 937 }
1303 938
1304 keylen = (int32_t)uprv_strlen(key); 939 keylen = (int32_t)uprv_strlen(key);
1305 isLDMLKeyword = (keylen > 1); 940 isBcpUExt = (keylen > 1);
1306 941
1307 /* special keyword used for representing Unicode locale attributes * / 942 /* special keyword used for representing Unicode locale attributes * /
1308 if (uprv_strcmp(key, LOCALE_ATTRIBUTE_KEY) == 0) { 943 if (uprv_strcmp(key, LOCALE_ATTRIBUTE_KEY) == 0) {
1309 isAttribute = TRUE; 944 isAttribute = TRUE;
1310 if (len > 0) { 945 if (len > 0) {
1311 int32_t i = 0; 946 int32_t i = 0;
1312 while (TRUE) { 947 while (TRUE) {
1313 attrBufLength = 0; 948 attrBufLength = 0;
1314 for (; i < len; i++) { 949 for (; i < len; i++) {
1315 if (buf[i] != '-') { 950 if (buf[i] != '-') {
(...skipping 27 matching lines...) Expand all
1343 if (!_addAttributeToList(&firstAttr, attr)) { 978 if (!_addAttributeToList(&firstAttr, attr)) {
1344 uprv_free(attr); 979 uprv_free(attr);
1345 uprv_free(attrValue); 980 uprv_free(attrValue);
1346 if (strict) { 981 if (strict) {
1347 *status = U_ILLEGAL_ARGUMENT_ERROR; 982 *status = U_ILLEGAL_ARGUMENT_ERROR;
1348 break; 983 break;
1349 } 984 }
1350 } 985 }
1351 } 986 }
1352 } 987 }
1353 } else if (isLDMLKeyword) { 988 } else if (isBcpUExt) {
1354 int32_t modKeyLen; 989 bcpKey = uloc_toUnicodeLocaleKey(key);
1355 990 if (bcpKey == NULL) {
1356 /* transform key and value to bcp47 style */
1357 modKeyLen = _ldmlKeyToBCP47(key, keylen, pExtBuf, extBufCapacity , &tmpStatus);
1358 if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED _WARNING) {
1359 if (strict) { 991 if (strict) {
1360 *status = U_ILLEGAL_ARGUMENT_ERROR; 992 *status = U_ILLEGAL_ARGUMENT_ERROR;
1361 break; 993 break;
1362 } 994 }
1363 tmpStatus = U_ZERO_ERROR;
1364 continue; 995 continue;
1365 } 996 }
1366 997
1367 bcpKey = pExtBuf; 998 /* we've checked buf is null-terminated above */
1368 pExtBuf += (modKeyLen + 1); 999 bcpValue = uloc_toUnicodeLocaleType(key, buf);
1369 extBufCapacity -= (modKeyLen + 1); 1000 if (bcpValue == NULL) {
1370
1371 len = _ldmlTypeToBCP47(key, keylen, buf, len, pExtBuf, extBufCap acity, &tmpStatus);
1372 if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED _WARNING) {
1373 if (strict) { 1001 if (strict) {
1374 *status = U_ILLEGAL_ARGUMENT_ERROR; 1002 *status = U_ILLEGAL_ARGUMENT_ERROR;
1375 break; 1003 break;
1376 } 1004 }
1377 tmpStatus = U_ZERO_ERROR;
1378 continue; 1005 continue;
1379 } 1006 }
1380 bcpValue = pExtBuf; 1007 if (bcpValue == buf) {
1381 pExtBuf += (len + 1); 1008 /*
1382 extBufCapacity -= (len + 1); 1009 When uloc_toUnicodeLocaleType(key, buf) returns the
1010 input value as is, the value is well-formed, but has
1011 no known mapping. This implementation normalizes the
1012 the value to lower case
1013 */
1014 int32_t bcpValueLen = uprv_strlen(bcpValue);
1015 if (bcpValueLen < extBufCapacity) {
1016 uprv_strcpy(pExtBuf, bcpValue);
1017 T_CString_toLowerCase(pExtBuf);
1018
1019 bcpValue = pExtBuf;
1020
1021 pExtBuf += (bcpValueLen + 1);
1022 extBufCapacity -= (bcpValueLen + 1);
1023 } else {
1024 if (strict) {
1025 *status = U_ILLEGAL_ARGUMENT_ERROR;
1026 break;
1027 }
1028 continue;
1029 }
1030 }
1383 } else { 1031 } else {
1384 if (*key == PRIVATEUSE) { 1032 if (*key == PRIVATEUSE) {
1385 if (!_isPrivateuseValueSubtags(buf, len)) { 1033 if (!_isPrivateuseValueSubtags(buf, len)) {
1386 if (strict) { 1034 if (strict) {
1387 *status = U_ILLEGAL_ARGUMENT_ERROR; 1035 *status = U_ILLEGAL_ARGUMENT_ERROR;
1388 break; 1036 break;
1389 } 1037 }
1390 continue; 1038 continue;
1391 } 1039 }
1392 } else { 1040 } else {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 *posixVariant = FALSE; 1212 *posixVariant = FALSE;
1565 1213
1566 pTag = ldmlext; 1214 pTag = ldmlext;
1567 pKwds = NULL; 1215 pKwds = NULL;
1568 1216
1569 /* Iterate through u extension attributes */ 1217 /* Iterate through u extension attributes */
1570 while (*pTag) { 1218 while (*pTag) {
1571 /* locate next separator char */ 1219 /* locate next separator char */
1572 for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++); 1220 for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++);
1573 1221
1574 if (_isLDMLKey(pTag, len)) { 1222 if (ultag_isUnicodeLocaleKey(pTag, len)) {
1575 pKwds = pTag; 1223 pKwds = pTag;
1576 break; 1224 break;
1577 } 1225 }
1578 1226
1579 /* add this attribute to the list */ 1227 /* add this attribute to the list */
1580 attr = (AttributeListEntry*)uprv_malloc(sizeof(AttributeListEntry)); 1228 attr = (AttributeListEntry*)uprv_malloc(sizeof(AttributeListEntry));
1581 if (attr == NULL) { 1229 if (attr == NULL) {
1582 *status = U_MEMORY_ALLOCATION_ERROR; 1230 *status = U_MEMORY_ALLOCATION_ERROR;
1583 goto cleanup; 1231 goto cleanup;
1584 } 1232 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 /* BCP47 representation of LDML key/type pairs */ 1320 /* BCP47 representation of LDML key/type pairs */
1673 while (!isDone) { 1321 while (!isDone) {
1674 const char *pNextBcpKey = NULL; 1322 const char *pNextBcpKey = NULL;
1675 int32_t nextBcpKeyLen; 1323 int32_t nextBcpKeyLen;
1676 UBool emitKeyword = FALSE; 1324 UBool emitKeyword = FALSE;
1677 1325
1678 if (*pTag) { 1326 if (*pTag) {
1679 /* locate next separator char */ 1327 /* locate next separator char */
1680 for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++); 1328 for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++);
1681 1329
1682 if (_isLDMLKey(pTag, len)) { 1330 if (ultag_isUnicodeLocaleKey(pTag, len)) {
1683 if (pBcpKey) { 1331 if (pBcpKey) {
1684 emitKeyword = TRUE; 1332 emitKeyword = TRUE;
1685 pNextBcpKey = pTag; 1333 pNextBcpKey = pTag;
1686 nextBcpKeyLen = len; 1334 nextBcpKeyLen = len;
1687 } else { 1335 } else {
1688 pBcpKey = pTag; 1336 pBcpKey = pTag;
1689 bcpKeyLen = len; 1337 bcpKeyLen = len;
1690 } 1338 }
1691 } else { 1339 } else {
1692 U_ASSERT(pBcpKey != NULL); 1340 U_ASSERT(pBcpKey != NULL);
(...skipping 15 matching lines...) Expand all
1708 } else { 1356 } else {
1709 /* processing last one */ 1357 /* processing last one */
1710 emitKeyword = TRUE; 1358 emitKeyword = TRUE;
1711 isDone = TRUE; 1359 isDone = TRUE;
1712 } 1360 }
1713 1361
1714 if (emitKeyword) { 1362 if (emitKeyword) {
1715 const char *pKey = NULL; /* LDML key */ 1363 const char *pKey = NULL; /* LDML key */
1716 const char *pType = NULL; /* LDML type */ 1364 const char *pType = NULL; /* LDML type */
1717 1365
1366 char bcpKeyBuf[9]; /* BCP key length is always 2 for no w */
1367
1718 U_ASSERT(pBcpKey != NULL); 1368 U_ASSERT(pBcpKey != NULL);
1719 1369
1720 /* u extension key to LDML key */ 1370 if (bcpKeyLen >= sizeof(bcpKeyBuf)) {
1721 len = _bcp47ToLDMLKey(pBcpKey, bcpKeyLen, buf + bufIdx, bufSize - bufIdx - 1, status); 1371 /* the BCP key is invalid */
1722 if (U_FAILURE(*status)) { 1372 *status = U_ILLEGAL_ARGUMENT_ERROR;
1723 goto cleanup; 1373 goto cleanup;
1724 } 1374 }
1725 pKey = buf + bufIdx; 1375
1726 bufIdx += len; 1376 uprv_strncpy(bcpKeyBuf, pBcpKey, bcpKeyLen);
1727 *(buf + bufIdx) = 0; 1377 bcpKeyBuf[bcpKeyLen] = 0;
1728 bufIdx++; 1378
1379 /* u extension key to LDML key */
1380 pKey = uloc_toLegacyKey(bcpKeyBuf);
1381 if (pKey == NULL) {
1382 *status = U_ILLEGAL_ARGUMENT_ERROR;
1383 goto cleanup;
1384 }
1385 if (pKey == bcpKeyBuf) {
1386 /*
1387 The key returned by toLegacyKey points to the input buffer.
1388 We normalize the result key to lower case.
1389 */
1390 T_CString_toLowerCase(bcpKeyBuf);
1391 if (bufSize - bufIdx - 1 >= bcpKeyLen) {
1392 uprv_memcpy(buf + bufIdx, bcpKeyBuf, bcpKeyLen);
1393 pKey = buf + bufIdx;
1394 bufIdx += bcpKeyLen;
1395 *(buf + bufIdx) = 0;
1396 bufIdx++;
1397 } else {
1398 *status = U_BUFFER_OVERFLOW_ERROR;
1399 goto cleanup;
1400 }
1401 }
1729 1402
1730 if (pBcpType) { 1403 if (pBcpType) {
1731 /* BCP type to locale type */ 1404 char bcpTypeBuf[128]; /* practically long enough even considering multiple subtag type */
1732 len = _bcp47ToLDMLType(pKey, -1, pBcpType, bcpTypeLen, buf + bufIdx, bufSize - bufIdx - 1, status); 1405 if (bcpTypeLen >= sizeof(bcpTypeBuf)) {
1733 if (U_FAILURE(*status)) { 1406 /* the BCP type is too long */
1407 *status = U_ILLEGAL_ARGUMENT_ERROR;
1734 goto cleanup; 1408 goto cleanup;
1735 } 1409 }
1736 pType = buf + bufIdx; 1410
1737 bufIdx += len; 1411 uprv_strncpy(bcpTypeBuf, pBcpType, bcpTypeLen);
1738 *(buf + bufIdx) = 0; 1412 bcpTypeBuf[bcpTypeLen] = 0;
1739 bufIdx++; 1413
1414 /* BCP type to locale type */
1415 pType = uloc_toLegacyType(pKey, bcpTypeBuf);
1416 if (pType == NULL) {
1417 *status = U_ILLEGAL_ARGUMENT_ERROR;
1418 goto cleanup;
1419 }
1420 if (pType == bcpTypeBuf) {
1421 /*
1422 The type returned by toLegacyType points to the input bu ffer.
1423 We normalize the result type to lower case.
1424 */
1425 /* normalize to lower case */
1426 T_CString_toLowerCase(bcpTypeBuf);
1427 if (bufSize - bufIdx - 1 >= bcpTypeLen) {
1428 uprv_memcpy(buf + bufIdx, bcpTypeBuf, bcpTypeLen);
1429 pType = buf + bufIdx;
1430 bufIdx += bcpTypeLen;
1431 *(buf + bufIdx) = 0;
1432 bufIdx++;
1433 } else {
1434 *status = U_BUFFER_OVERFLOW_ERROR;
1435 goto cleanup;
1436 }
1437 }
1740 } else { 1438 } else {
1741 /* typeless - default type value is "yes" */ 1439 /* typeless - default type value is "yes" */
1742 pType = LOCALE_TYPE_YES; 1440 pType = LOCALE_TYPE_YES;
1743 } 1441 }
1744 1442
1745 /* Special handling for u-va-posix, since we want to treat this as a variant, 1443 /* Special handling for u-va-posix, since we want to treat this as a variant,
1746 not as a keyword */ 1444 not as a keyword */
1747 if (!variantExists && !uprv_strcmp(pKey, POSIX_KEY) && !uprv_str cmp(pType, POSIX_VALUE) ) { 1445 if (!variantExists && !uprv_strcmp(pKey, POSIX_KEY) && !uprv_str cmp(pType, POSIX_VALUE) ) {
1748 *posixVariant = TRUE; 1446 *posixVariant = TRUE;
1749 } else { 1447 } else {
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 } 2501 }
2804 len = _appendKeywords(lt, localeID + reslen, localeIDCapacity - reslen, status); 2502 len = _appendKeywords(lt, localeID + reslen, localeIDCapacity - reslen, status);
2805 reslen += len; 2503 reslen += len;
2806 } 2504 }
2807 2505
2808 ultag_close(lt); 2506 ultag_close(lt);
2809 return u_terminateChars(localeID, localeIDCapacity, reslen, status); 2507 return u_terminateChars(localeID, localeIDCapacity, reslen, status);
2810 } 2508 }
2811 2509
2812 2510
OLDNEW
« no previous file with comments | « source/common/uloc_keytype.cpp ('k') | source/common/ulocimp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698