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

Side by Side Diff: source/i18n/rbnf.cpp

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/i18n/quantityformatter.cpp ('k') | source/i18n/rbt_data.cpp » ('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) 1997-2013, International Business Machines Corporation 3 * Copyright (C) 1997-2014, International Business Machines Corporation
4 * and others. All Rights Reserved. 4 * and others. All Rights Reserved.
5 ******************************************************************************* 5 *******************************************************************************
6 */ 6 */
7 7
8 #include "unicode/utypes.h"
8 #include "utypeinfo.h" // for 'typeid' to work 9 #include "utypeinfo.h" // for 'typeid' to work
9 10
10 #include "unicode/rbnf.h" 11 #include "unicode/rbnf.h"
11 12
12 #if U_HAVE_RBNF 13 #if U_HAVE_RBNF
13 14
14 #include "unicode/normlzr.h" 15 #include "unicode/normlzr.h"
16 #include "unicode/plurfmt.h"
15 #include "unicode/tblcoll.h" 17 #include "unicode/tblcoll.h"
16 #include "unicode/uchar.h" 18 #include "unicode/uchar.h"
17 #include "unicode/ucol.h" 19 #include "unicode/ucol.h"
18 #include "unicode/uloc.h" 20 #include "unicode/uloc.h"
19 #include "unicode/unum.h" 21 #include "unicode/unum.h"
20 #include "unicode/ures.h" 22 #include "unicode/ures.h"
21 #include "unicode/ustring.h" 23 #include "unicode/ustring.h"
22 #include "unicode/utf16.h" 24 #include "unicode/utf16.h"
23 #include "unicode/udata.h" 25 #include "unicode/udata.h"
26 #include "unicode/udisplaycontext.h"
27 #include "unicode/brkiter.h"
24 #include "nfrs.h" 28 #include "nfrs.h"
25 29
26 #include "cmemory.h" 30 #include "cmemory.h"
27 #include "cstring.h" 31 #include "cstring.h"
28 #include "patternprops.h" 32 #include "patternprops.h"
29 #include "uresimp.h" 33 #include "uresimp.h"
30 34
31 // debugging 35 // debugging
32 // #define DEBUG 36 // #define RBNF_DEBUG
33 37
34 #ifdef DEBUG 38 #ifdef RBNF_DEBUG
35 #include "stdio.h" 39 #include "stdio.h"
36 #endif 40 #endif
37 41
38 #define U_ICUDATA_RBNF U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf" 42 #define U_ICUDATA_RBNF U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf"
39 43
40 static const UChar gPercentPercent[] = 44 static const UChar gPercentPercent[] =
41 { 45 {
42 0x25, 0x25, 0 46 0x25, 0x25, 0
43 }; /* "%%" */ 47 }; /* "%%" */
44 48
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 while (*list && *list != c) ++list; return *list == c; 321 while (*list && *list != c) ++list; return *list == c;
318 } 322 }
319 void parseError(const char* msg); 323 void parseError(const char* msg);
320 324
321 StringLocalizationInfo* doParse(void); 325 StringLocalizationInfo* doParse(void);
322 326
323 UChar** nextArray(int32_t& requiredLength); 327 UChar** nextArray(int32_t& requiredLength);
324 UChar* nextString(void); 328 UChar* nextString(void);
325 }; 329 };
326 330
327 #ifdef DEBUG 331 #ifdef RBNF_DEBUG
328 #define ERROR(msg) parseError(msg); return NULL; 332 #define ERROR(msg) parseError(msg); return NULL;
333 #define EXPLANATION_ARG explanationArg
329 #else 334 #else
330 #define ERROR(msg) parseError(NULL); return NULL; 335 #define ERROR(msg) parseError(NULL); return NULL;
336 #define EXPLANATION_ARG
331 #endif 337 #endif
332 338
333 339
334 static const UChar DQUOTE_STOPLIST[] = { 340 static const UChar DQUOTE_STOPLIST[] = {
335 QUOTE, 0 341 QUOTE, 0
336 }; 342 };
337 343
338 static const UChar SQUOTE_STOPLIST[] = { 344 static const UChar SQUOTE_STOPLIST[] = {
339 TICK, 0 345 TICK, 0
340 }; 346 };
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 inc(); 524 inc();
519 } else if (x == OPEN_ANGLE || x == TICK || x == QUOTE) { 525 } else if (x == OPEN_ANGLE || x == TICK || x == QUOTE) {
520 ERROR("Unexpected character in string"); 526 ERROR("Unexpected character in string");
521 } 527 }
522 } 528 }
523 529
524 // ok for there to be no next string 530 // ok for there to be no next string
525 return result; 531 return result;
526 } 532 }
527 533
528 void 534 void LocDataParser::parseError(const char* EXPLANATION_ARG)
529 LocDataParser::parseError(const char* /*str*/) { 535 {
530 if (!data) { 536 if (!data) {
531 return; 537 return;
532 } 538 }
533 539
534 const UChar* start = p - U_PARSE_CONTEXT_LEN - 1; 540 const UChar* start = p - U_PARSE_CONTEXT_LEN - 1;
535 if (start < data) { 541 if (start < data) {
536 start = data; 542 start = data;
537 } 543 }
538 for (UChar* x = p; --x >= start;) { 544 for (UChar* x = p; --x >= start;) {
539 if (!*x) { 545 if (!*x) {
540 start = x+1; 546 start = x+1;
541 break; 547 break;
542 } 548 }
543 } 549 }
544 const UChar* limit = p + U_PARSE_CONTEXT_LEN - 1; 550 const UChar* limit = p + U_PARSE_CONTEXT_LEN - 1;
545 if (limit > e) { 551 if (limit > e) {
546 limit = e; 552 limit = e;
547 } 553 }
548 u_strncpy(pe.preContext, start, (int32_t)(p-start)); 554 u_strncpy(pe.preContext, start, (int32_t)(p-start));
549 pe.preContext[p-start] = 0; 555 pe.preContext[p-start] = 0;
550 u_strncpy(pe.postContext, p, (int32_t)(limit-p)); 556 u_strncpy(pe.postContext, p, (int32_t)(limit-p));
551 pe.postContext[limit-p] = 0; 557 pe.postContext[limit-p] = 0;
552 pe.offset = (int32_t)(p - data); 558 pe.offset = (int32_t)(p - data);
553 559
554 #ifdef DEBUG 560 #ifdef RBNF_DEBUG
555 fprintf(stderr, "%s at or near character %d: ", str, p-data); 561 fprintf(stderr, "%s at or near character %ld: ", EXPLANATION_ARG, p-data);
556 562
557 UnicodeString msg; 563 UnicodeString msg;
558 msg.append(start, p - start); 564 msg.append(start, p - start);
559 msg.append((UChar)0x002f); /* SOLIDUS/SLASH */ 565 msg.append((UChar)0x002f); /* SOLIDUS/SLASH */
560 msg.append(p, limit-p); 566 msg.append(p, limit-p);
561 msg.append("'"); 567 msg.append(UNICODE_STRING_SIMPLE("'"));
562 568
563 char buf[128]; 569 char buf[128];
564 int32_t len = msg.extract(0, msg.length(), buf, 128); 570 int32_t len = msg.extract(0, msg.length(), buf, 128);
565 if (len >= 128) { 571 if (len >= 128) {
566 buf[127] = 0; 572 buf[127] = 0;
567 } else { 573 } else {
568 buf[len] = 0; 574 buf[len] = 0;
569 } 575 }
570 fprintf(stderr, "%s\n", buf); 576 fprintf(stderr, "%s\n", buf);
571 fflush(stderr); 577 fflush(stderr);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 : ruleSets(NULL) 657 : ruleSets(NULL)
652 , ruleSetDescriptions(NULL) 658 , ruleSetDescriptions(NULL)
653 , numRuleSets(0) 659 , numRuleSets(0)
654 , defaultRuleSet(NULL) 660 , defaultRuleSet(NULL)
655 , locale(alocale) 661 , locale(alocale)
656 , collator(NULL) 662 , collator(NULL)
657 , decimalFormatSymbols(NULL) 663 , decimalFormatSymbols(NULL)
658 , lenient(FALSE) 664 , lenient(FALSE)
659 , lenientParseRules(NULL) 665 , lenientParseRules(NULL)
660 , localizations(NULL) 666 , localizations(NULL)
667 , capitalizationInfoSet(FALSE)
668 , capitalizationForUIListMenu(FALSE)
669 , capitalizationForStandAlone(FALSE)
670 , capitalizationBrkIter(NULL)
661 { 671 {
662 LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, statu s); 672 LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, statu s);
663 init(description, locinfo, perror, status); 673 init(description, locinfo, perror, status);
664 } 674 }
665 675
666 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 676 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
667 const UnicodeString& locs, 677 const UnicodeString& locs,
668 UParseError& perror, UErrorCode& st atus) 678 UParseError& perror, UErrorCode& st atus)
669 : ruleSets(NULL) 679 : ruleSets(NULL)
670 , ruleSetDescriptions(NULL) 680 , ruleSetDescriptions(NULL)
671 , numRuleSets(0) 681 , numRuleSets(0)
672 , defaultRuleSet(NULL) 682 , defaultRuleSet(NULL)
673 , locale(Locale::getDefault()) 683 , locale(Locale::getDefault())
674 , collator(NULL) 684 , collator(NULL)
675 , decimalFormatSymbols(NULL) 685 , decimalFormatSymbols(NULL)
676 , lenient(FALSE) 686 , lenient(FALSE)
677 , lenientParseRules(NULL) 687 , lenientParseRules(NULL)
678 , localizations(NULL) 688 , localizations(NULL)
689 , capitalizationInfoSet(FALSE)
690 , capitalizationForUIListMenu(FALSE)
691 , capitalizationForStandAlone(FALSE)
692 , capitalizationBrkIter(NULL)
679 { 693 {
680 LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, statu s); 694 LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, statu s);
681 init(description, locinfo, perror, status); 695 init(description, locinfo, perror, status);
682 } 696 }
683 697
684 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 698 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
685 LocalizationInfo* info, 699 LocalizationInfo* info,
686 const Locale& alocale, UParseError& perror, UErrorCode& status) 700 const Locale& alocale, UParseError& perror, UErrorCode& status)
687 : ruleSets(NULL) 701 : ruleSets(NULL)
688 , ruleSetDescriptions(NULL) 702 , ruleSetDescriptions(NULL)
689 , numRuleSets(0) 703 , numRuleSets(0)
690 , defaultRuleSet(NULL) 704 , defaultRuleSet(NULL)
691 , locale(alocale) 705 , locale(alocale)
692 , collator(NULL) 706 , collator(NULL)
693 , decimalFormatSymbols(NULL) 707 , decimalFormatSymbols(NULL)
694 , lenient(FALSE) 708 , lenient(FALSE)
695 , lenientParseRules(NULL) 709 , lenientParseRules(NULL)
696 , localizations(NULL) 710 , localizations(NULL)
711 , capitalizationInfoSet(FALSE)
712 , capitalizationForUIListMenu(FALSE)
713 , capitalizationForStandAlone(FALSE)
714 , capitalizationBrkIter(NULL)
697 { 715 {
698 init(description, info, perror, status); 716 init(description, info, perror, status);
699 } 717 }
700 718
701 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 719 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
702 UParseError& perror, 720 UParseError& perror,
703 UErrorCode& status) 721 UErrorCode& status)
704 : ruleSets(NULL) 722 : ruleSets(NULL)
705 , ruleSetDescriptions(NULL) 723 , ruleSetDescriptions(NULL)
706 , numRuleSets(0) 724 , numRuleSets(0)
707 , defaultRuleSet(NULL) 725 , defaultRuleSet(NULL)
708 , locale(Locale::getDefault()) 726 , locale(Locale::getDefault())
709 , collator(NULL) 727 , collator(NULL)
710 , decimalFormatSymbols(NULL) 728 , decimalFormatSymbols(NULL)
711 , lenient(FALSE) 729 , lenient(FALSE)
712 , lenientParseRules(NULL) 730 , lenientParseRules(NULL)
713 , localizations(NULL) 731 , localizations(NULL)
732 , capitalizationInfoSet(FALSE)
733 , capitalizationForUIListMenu(FALSE)
734 , capitalizationForStandAlone(FALSE)
735 , capitalizationBrkIter(NULL)
714 { 736 {
715 init(description, NULL, perror, status); 737 init(description, NULL, perror, status);
716 } 738 }
717 739
718 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 740 RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
719 const Locale& aLocale, 741 const Locale& aLocale,
720 UParseError& perror, 742 UParseError& perror,
721 UErrorCode& status) 743 UErrorCode& status)
722 : ruleSets(NULL) 744 : ruleSets(NULL)
723 , ruleSetDescriptions(NULL) 745 , ruleSetDescriptions(NULL)
724 , numRuleSets(0) 746 , numRuleSets(0)
725 , defaultRuleSet(NULL) 747 , defaultRuleSet(NULL)
726 , locale(aLocale) 748 , locale(aLocale)
727 , collator(NULL) 749 , collator(NULL)
728 , decimalFormatSymbols(NULL) 750 , decimalFormatSymbols(NULL)
729 , lenient(FALSE) 751 , lenient(FALSE)
730 , lenientParseRules(NULL) 752 , lenientParseRules(NULL)
731 , localizations(NULL) 753 , localizations(NULL)
754 , capitalizationInfoSet(FALSE)
755 , capitalizationForUIListMenu(FALSE)
756 , capitalizationForStandAlone(FALSE)
757 , capitalizationBrkIter(NULL)
732 { 758 {
733 init(description, NULL, perror, status); 759 init(description, NULL, perror, status);
734 } 760 }
735 761
736 RuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale& alocale, UErrorCode& status) 762 RuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale& alocale, UErrorCode& status)
737 : ruleSets(NULL) 763 : ruleSets(NULL)
738 , ruleSetDescriptions(NULL) 764 , ruleSetDescriptions(NULL)
739 , numRuleSets(0) 765 , numRuleSets(0)
740 , defaultRuleSet(NULL) 766 , defaultRuleSet(NULL)
741 , locale(alocale) 767 , locale(alocale)
742 , collator(NULL) 768 , collator(NULL)
743 , decimalFormatSymbols(NULL) 769 , decimalFormatSymbols(NULL)
744 , lenient(FALSE) 770 , lenient(FALSE)
745 , lenientParseRules(NULL) 771 , lenientParseRules(NULL)
746 , localizations(NULL) 772 , localizations(NULL)
773 , capitalizationInfoSet(FALSE)
774 , capitalizationForUIListMenu(FALSE)
775 , capitalizationForStandAlone(FALSE)
776 , capitalizationBrkIter(NULL)
747 { 777 {
748 if (U_FAILURE(status)) { 778 if (U_FAILURE(status)) {
749 return; 779 return;
750 } 780 }
751 781
752 const char* rules_tag = "RBNFRules"; 782 const char* rules_tag = "RBNFRules";
753 const char* fmt_tag = ""; 783 const char* fmt_tag = "";
754 switch (tag) { 784 switch (tag) {
755 case URBNF_SPELLOUT: fmt_tag = "SpelloutRules"; break; 785 case URBNF_SPELLOUT: fmt_tag = "SpelloutRules"; break;
756 case URBNF_ORDINAL: fmt_tag = "OrdinalRules"; break; 786 case URBNF_ORDINAL: fmt_tag = "OrdinalRules"; break;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 , ruleSets(NULL) 827 , ruleSets(NULL)
798 , ruleSetDescriptions(NULL) 828 , ruleSetDescriptions(NULL)
799 , numRuleSets(0) 829 , numRuleSets(0)
800 , defaultRuleSet(NULL) 830 , defaultRuleSet(NULL)
801 , locale(rhs.locale) 831 , locale(rhs.locale)
802 , collator(NULL) 832 , collator(NULL)
803 , decimalFormatSymbols(NULL) 833 , decimalFormatSymbols(NULL)
804 , lenient(FALSE) 834 , lenient(FALSE)
805 , lenientParseRules(NULL) 835 , lenientParseRules(NULL)
806 , localizations(NULL) 836 , localizations(NULL)
837 , capitalizationInfoSet(FALSE)
838 , capitalizationForUIListMenu(FALSE)
839 , capitalizationForStandAlone(FALSE)
840 , capitalizationBrkIter(NULL)
807 { 841 {
808 this->operator=(rhs); 842 this->operator=(rhs);
809 } 843 }
810 844
811 // -------- 845 // --------
812 846
813 RuleBasedNumberFormat& 847 RuleBasedNumberFormat&
814 RuleBasedNumberFormat::operator=(const RuleBasedNumberFormat& rhs) 848 RuleBasedNumberFormat::operator=(const RuleBasedNumberFormat& rhs)
815 { 849 {
850 if (this == &rhs) {
851 return *this;
852 }
853 NumberFormat::operator=(rhs);
816 UErrorCode status = U_ZERO_ERROR; 854 UErrorCode status = U_ZERO_ERROR;
817 dispose(); 855 dispose();
818 locale = rhs.locale; 856 locale = rhs.locale;
819 lenient = rhs.lenient; 857 lenient = rhs.lenient;
820 858
821 UnicodeString rules = rhs.getRules();
822 UParseError perror; 859 UParseError perror;
823 init(rules, rhs.localizations ? rhs.localizations->ref() : NULL, perror, sta tus); 860 init(rhs.originalDescription, rhs.localizations ? rhs.localizations->ref() : NULL, perror, status);
861 setDecimalFormatSymbols(*rhs.getDecimalFormatSymbols());
862 setDefaultRuleSet(rhs.getDefaultRuleSetName(), status);
863
864 capitalizationInfoSet = rhs.capitalizationInfoSet;
865 capitalizationForUIListMenu = rhs.capitalizationForUIListMenu;
866 capitalizationForStandAlone = rhs.capitalizationForStandAlone;
867 #if !UCONFIG_NO_BREAK_ITERATION
868 capitalizationBrkIter = (rhs.capitalizationBrkIter!=NULL)? rhs.capitalizatio nBrkIter->clone(): NULL;
869 #endif
824 870
825 return *this; 871 return *this;
826 } 872 }
827 873
828 RuleBasedNumberFormat::~RuleBasedNumberFormat() 874 RuleBasedNumberFormat::~RuleBasedNumberFormat()
829 { 875 {
830 dispose(); 876 dispose();
831 } 877 }
832 878
833 Format* 879 Format*
834 RuleBasedNumberFormat::clone(void) const 880 RuleBasedNumberFormat::clone(void) const
835 { 881 {
836 RuleBasedNumberFormat * result = NULL; 882 return new RuleBasedNumberFormat(*this);
837 UnicodeString rules = getRules();
838 UErrorCode status = U_ZERO_ERROR;
839 UParseError perror;
840 result = new RuleBasedNumberFormat(rules, localizations, locale, perror, sta tus);
841 /* test for NULL */
842 if (result == 0) {
843 status = U_MEMORY_ALLOCATION_ERROR;
844 return 0;
845 }
846 if (U_FAILURE(status)) {
847 delete result;
848 result = 0;
849 } else {
850 result->lenient = lenient;
851 }
852 return result;
853 } 883 }
854 884
855 UBool 885 UBool
856 RuleBasedNumberFormat::operator==(const Format& other) const 886 RuleBasedNumberFormat::operator==(const Format& other) const
857 { 887 {
858 if (this == &other) { 888 if (this == &other) {
859 return TRUE; 889 return TRUE;
860 } 890 }
861 891
862 if (typeid(*this) == typeid(other)) { 892 if (typeid(*this) == typeid(other)) {
863 const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other; 893 const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other;
894 // test for capitalization info equality is adequately handled
895 // by the NumberFormat test for fCapitalizationContext equality;
896 // the info here is just derived from that.
864 if (locale == rhs.locale && 897 if (locale == rhs.locale &&
865 lenient == rhs.lenient && 898 lenient == rhs.lenient &&
866 (localizations == NULL 899 (localizations == NULL
867 ? rhs.localizations == NULL 900 ? rhs.localizations == NULL
868 : (rhs.localizations == NULL 901 : (rhs.localizations == NULL
869 ? FALSE 902 ? FALSE
870 : *localizations == rhs.localizations))) { 903 : *localizations == rhs.localizations))) {
871 904
872 NFRuleSet** p = ruleSets; 905 NFRuleSet** p = ruleSets;
873 NFRuleSet** q = rhs.ruleSets; 906 NFRuleSet** q = rhs.ruleSets;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 status = U_ILLEGAL_ARGUMENT_ERROR; 1058 status = U_ILLEGAL_ARGUMENT_ERROR;
1026 } 1059 }
1027 return NULL; 1060 return NULL;
1028 } 1061 }
1029 1062
1030 UnicodeString& 1063 UnicodeString&
1031 RuleBasedNumberFormat::format(int32_t number, 1064 RuleBasedNumberFormat::format(int32_t number,
1032 UnicodeString& toAppendTo, 1065 UnicodeString& toAppendTo,
1033 FieldPosition& /* pos */) const 1066 FieldPosition& /* pos */) const
1034 { 1067 {
1035 if (defaultRuleSet) defaultRuleSet->format((int64_t)number, toAppendTo, toAp pendTo.length()); 1068 if (defaultRuleSet) {
1069 UErrorCode status = U_ZERO_ERROR;
1070 int32_t startPos = toAppendTo.length();
1071 defaultRuleSet->format((int64_t)number, toAppendTo, toAppendTo.length(), status);
1072 adjustForCapitalizationContext(startPos, toAppendTo);
1073 }
1036 return toAppendTo; 1074 return toAppendTo;
1037 } 1075 }
1038 1076
1039 1077
1040 UnicodeString& 1078 UnicodeString&
1041 RuleBasedNumberFormat::format(int64_t number, 1079 RuleBasedNumberFormat::format(int64_t number,
1042 UnicodeString& toAppendTo, 1080 UnicodeString& toAppendTo,
1043 FieldPosition& /* pos */) const 1081 FieldPosition& /* pos */) const
1044 { 1082 {
1045 if (defaultRuleSet) defaultRuleSet->format(number, toAppendTo, toAppendTo.le ngth()); 1083 if (defaultRuleSet) {
1084 UErrorCode status = U_ZERO_ERROR;
1085 int32_t startPos = toAppendTo.length();
1086 defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), status);
1087 adjustForCapitalizationContext(startPos, toAppendTo);
1088 }
1046 return toAppendTo; 1089 return toAppendTo;
1047 } 1090 }
1048 1091
1049 1092
1050 UnicodeString& 1093 UnicodeString&
1051 RuleBasedNumberFormat::format(double number, 1094 RuleBasedNumberFormat::format(double number,
1052 UnicodeString& toAppendTo, 1095 UnicodeString& toAppendTo,
1053 FieldPosition& /* pos */) const 1096 FieldPosition& /* pos */) const
1054 { 1097 {
1098 int32_t startPos = toAppendTo.length();
1055 // Special case for NaN; adapted from what DecimalFormat::_format( double nu mber,...) does. 1099 // Special case for NaN; adapted from what DecimalFormat::_format( double nu mber,...) does.
1056 if (uprv_isNaN(number)) { 1100 if (uprv_isNaN(number)) {
1057 DecimalFormatSymbols* decFmtSyms = getDecimalFormatSymbols(); // RuleBas edNumberFormat internal 1101 DecimalFormatSymbols* decFmtSyms = getDecimalFormatSymbols(); // RuleBas edNumberFormat internal
1058 if (decFmtSyms) { 1102 if (decFmtSyms) {
1059 toAppendTo += decFmtSyms->getConstSymbol(DecimalFormatSymbols::kNaNS ymbol); 1103 toAppendTo += decFmtSyms->getConstSymbol(DecimalFormatSymbols::kNaNS ymbol);
1060 } 1104 }
1061 } else if (defaultRuleSet) { 1105 } else if (defaultRuleSet) {
1062 defaultRuleSet->format(number, toAppendTo, toAppendTo.length()); 1106 UErrorCode status = U_ZERO_ERROR;
1107 defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), status);
1063 } 1108 }
1064 return toAppendTo; 1109 return adjustForCapitalizationContext(startPos, toAppendTo);
1065 } 1110 }
1066 1111
1067 1112
1068 UnicodeString& 1113 UnicodeString&
1069 RuleBasedNumberFormat::format(int32_t number, 1114 RuleBasedNumberFormat::format(int32_t number,
1070 const UnicodeString& ruleSetName, 1115 const UnicodeString& ruleSetName,
1071 UnicodeString& toAppendTo, 1116 UnicodeString& toAppendTo,
1072 FieldPosition& /* pos */, 1117 FieldPosition& /* pos */,
1073 UErrorCode& status) const 1118 UErrorCode& status) const
1074 { 1119 {
1075 // return format((int64_t)number, ruleSetName, toAppendTo, pos, status); 1120 // return format((int64_t)number, ruleSetName, toAppendTo, pos, status);
1076 if (U_SUCCESS(status)) { 1121 if (U_SUCCESS(status)) {
1077 if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) { 1122 if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) {
1078 // throw new IllegalArgumentException("Can't use internal rule set") ; 1123 // throw new IllegalArgumentException("Can't use internal rule set") ;
1079 status = U_ILLEGAL_ARGUMENT_ERROR; 1124 status = U_ILLEGAL_ARGUMENT_ERROR;
1080 } else { 1125 } else {
1081 NFRuleSet *rs = findRuleSet(ruleSetName, status); 1126 NFRuleSet *rs = findRuleSet(ruleSetName, status);
1082 if (rs) { 1127 if (rs) {
1083 rs->format((int64_t)number, toAppendTo, toAppendTo.length()); 1128 int32_t startPos = toAppendTo.length();
1129 rs->format((int64_t)number, toAppendTo, toAppendTo.length(), sta tus);
1130 adjustForCapitalizationContext(startPos, toAppendTo);
1084 } 1131 }
1085 } 1132 }
1086 } 1133 }
1087 return toAppendTo; 1134 return toAppendTo;
1088 } 1135 }
1089 1136
1090 1137
1091 UnicodeString& 1138 UnicodeString&
1092 RuleBasedNumberFormat::format(int64_t number, 1139 RuleBasedNumberFormat::format(int64_t number,
1093 const UnicodeString& ruleSetName, 1140 const UnicodeString& ruleSetName,
1094 UnicodeString& toAppendTo, 1141 UnicodeString& toAppendTo,
1095 FieldPosition& /* pos */, 1142 FieldPosition& /* pos */,
1096 UErrorCode& status) const 1143 UErrorCode& status) const
1097 { 1144 {
1098 if (U_SUCCESS(status)) { 1145 if (U_SUCCESS(status)) {
1099 if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) { 1146 if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) {
1100 // throw new IllegalArgumentException("Can't use internal rule set") ; 1147 // throw new IllegalArgumentException("Can't use internal rule set") ;
1101 status = U_ILLEGAL_ARGUMENT_ERROR; 1148 status = U_ILLEGAL_ARGUMENT_ERROR;
1102 } else { 1149 } else {
1103 NFRuleSet *rs = findRuleSet(ruleSetName, status); 1150 NFRuleSet *rs = findRuleSet(ruleSetName, status);
1104 if (rs) { 1151 if (rs) {
1105 rs->format(number, toAppendTo, toAppendTo.length()); 1152 int32_t startPos = toAppendTo.length();
1153 rs->format(number, toAppendTo, toAppendTo.length(), status);
1154 adjustForCapitalizationContext(startPos, toAppendTo);
1106 } 1155 }
1107 } 1156 }
1108 } 1157 }
1109 return toAppendTo; 1158 return toAppendTo;
1110 } 1159 }
1111 1160
1112 1161
1113 UnicodeString& 1162 UnicodeString&
1114 RuleBasedNumberFormat::format(double number, 1163 RuleBasedNumberFormat::format(double number,
1115 const UnicodeString& ruleSetName, 1164 const UnicodeString& ruleSetName,
1116 UnicodeString& toAppendTo, 1165 UnicodeString& toAppendTo,
1117 FieldPosition& /* pos */, 1166 FieldPosition& /* pos */,
1118 UErrorCode& status) const 1167 UErrorCode& status) const
1119 { 1168 {
1120 if (U_SUCCESS(status)) { 1169 if (U_SUCCESS(status)) {
1121 if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) { 1170 if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) {
1122 // throw new IllegalArgumentException("Can't use internal rule set") ; 1171 // throw new IllegalArgumentException("Can't use internal rule set") ;
1123 status = U_ILLEGAL_ARGUMENT_ERROR; 1172 status = U_ILLEGAL_ARGUMENT_ERROR;
1124 } else { 1173 } else {
1125 NFRuleSet *rs = findRuleSet(ruleSetName, status); 1174 NFRuleSet *rs = findRuleSet(ruleSetName, status);
1126 if (rs) { 1175 if (rs) {
1127 rs->format(number, toAppendTo, toAppendTo.length()); 1176 int32_t startPos = toAppendTo.length();
1177 rs->format(number, toAppendTo, toAppendTo.length(), status);
1178 adjustForCapitalizationContext(startPos, toAppendTo);
1128 } 1179 }
1129 } 1180 }
1130 } 1181 }
1131 return toAppendTo; 1182 return toAppendTo;
1132 } 1183 }
1133 1184
1185 UnicodeString&
1186 RuleBasedNumberFormat::adjustForCapitalizationContext(int32_t startPos,
1187 UnicodeString& currentResu lt) const
1188 {
1189 #if !UCONFIG_NO_BREAK_ITERATION
1190 if (startPos==0 && currentResult.length() > 0) {
1191 // capitalize currentResult according to context
1192 UChar32 ch = currentResult.char32At(0);
1193 UErrorCode status = U_ZERO_ERROR;
1194 UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITAL IZATION, status);
1195 if ( u_islower(ch) && U_SUCCESS(status) && capitalizationBrkIter!= NULL &&
1196 ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_ SENTENCE ||
1197 (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_M ENU && capitalizationForUIListMenu) ||
1198 (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_STANDALONE & & capitalizationForStandAlone)) ) {
1199 // titlecase first word of currentResult, here use sentence iterator unlike current implementations
1200 // in LocaleDisplayNamesImpl::adjustForUsageAndContext and RelativeD ateFormat::format
1201 currentResult.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_ LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
1202 }
1203 }
1204 #endif
1205 return currentResult;
1206 }
1207
1208
1134 void 1209 void
1135 RuleBasedNumberFormat::parse(const UnicodeString& text, 1210 RuleBasedNumberFormat::parse(const UnicodeString& text,
1136 Formattable& result, 1211 Formattable& result,
1137 ParsePosition& parsePosition) const 1212 ParsePosition& parsePosition) const
1138 { 1213 {
1139 if (!ruleSets) { 1214 if (!ruleSets) {
1140 parsePosition.setErrorIndex(0); 1215 parsePosition.setErrorIndex(0);
1141 return; 1216 return;
1142 } 1217 }
1143 1218
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 if (rs == NULL) { 1497 if (rs == NULL) {
1423 break; // error 1498 break; // error
1424 } 1499 }
1425 if (i == 0) { 1500 if (i == 0) {
1426 defaultRuleSet = rs; 1501 defaultRuleSet = rs;
1427 } 1502 }
1428 } 1503 }
1429 } else { 1504 } else {
1430 defaultRuleSet = getDefaultRuleSet(); 1505 defaultRuleSet = getDefaultRuleSet();
1431 } 1506 }
1507 originalDescription = rules;
1508 }
1509
1510 // override the NumberFormat implementation in order to
1511 // lazily initialize relevant items
1512 void
1513 RuleBasedNumberFormat::setContext(UDisplayContext value, UErrorCode& status)
1514 {
1515 NumberFormat::setContext(value, status);
1516 if (U_SUCCESS(status)) {
1517 if (!capitalizationInfoSet &&
1518 (value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UD ISPCTX_CAPITALIZATION_FOR_STANDALONE)) {
1519 initCapitalizationContextInfo(locale);
1520 capitalizationInfoSet = TRUE;
1521 }
1522 #if !UCONFIG_NO_BREAK_ITERATION
1523 if ( capitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_FO R_BEGINNING_OF_SENTENCE ||
1524 (value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && capitaliz ationForUIListMenu) ||
1525 (value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && capitalization ForStandAlone)) ) {
1526 UErrorCode status = U_ZERO_ERROR;
1527 capitalizationBrkIter = BreakIterator::createSentenceInstance(locale , status);
1528 if (U_FAILURE(status)) {
1529 delete capitalizationBrkIter;
1530 capitalizationBrkIter = NULL;
1531 }
1532 }
1533 #endif
1534 }
1432 } 1535 }
1433 1536
1434 void 1537 void
1538 RuleBasedNumberFormat::initCapitalizationContextInfo(const Locale& thelocale)
1539 {
1540 #if !UCONFIG_NO_BREAK_ITERATION
1541 const char * localeID = (thelocale != NULL)? thelocale.getBaseName(): NULL;
1542 UErrorCode status = U_ZERO_ERROR;
1543 UResourceBundle *rb = ures_open(NULL, localeID, &status);
1544 rb = ures_getByKeyWithFallback(rb, "contextTransforms", rb, &status);
1545 rb = ures_getByKeyWithFallback(rb, "number-spellout", rb, &status);
1546 if (U_SUCCESS(status) && rb != NULL) {
1547 int32_t len = 0;
1548 const int32_t * intVector = ures_getIntVector(rb, &len, &status);
1549 if (U_SUCCESS(status) && intVector != NULL && len >= 2) {
1550 capitalizationForUIListMenu = intVector[0];
1551 capitalizationForStandAlone = intVector[1];
1552 }
1553 }
1554 ures_close(rb);
1555 #endif
1556 }
1557
1558 void
1435 RuleBasedNumberFormat::stripWhitespace(UnicodeString& description) 1559 RuleBasedNumberFormat::stripWhitespace(UnicodeString& description)
1436 { 1560 {
1437 // iterate through the characters... 1561 // iterate through the characters...
1438 UnicodeString result; 1562 UnicodeString result;
1439 1563
1440 int start = 0; 1564 int start = 0;
1441 while (start != -1 && start < description.length()) { 1565 while (start != -1 && start < description.length()) {
1442 // seek to the first non-whitespace character... 1566 // seek to the first non-whitespace character...
1443 while (start < description.length() 1567 while (start < description.length()
1444 && PatternProps::isWhiteSpace(description.charAt(start))) { 1568 && PatternProps::isWhiteSpace(description.charAt(start))) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 delete collator; 1615 delete collator;
1492 #endif 1616 #endif
1493 collator = NULL; 1617 collator = NULL;
1494 1618
1495 delete decimalFormatSymbols; 1619 delete decimalFormatSymbols;
1496 decimalFormatSymbols = NULL; 1620 decimalFormatSymbols = NULL;
1497 1621
1498 delete lenientParseRules; 1622 delete lenientParseRules;
1499 lenientParseRules = NULL; 1623 lenientParseRules = NULL;
1500 1624
1625 #if !UCONFIG_NO_BREAK_ITERATION
1626 delete capitalizationBrkIter;
1627 capitalizationBrkIter = NULL;
1628 #endif
1629
1501 if (localizations) localizations = localizations->unref(); 1630 if (localizations) localizations = localizations->unref();
1502 } 1631 }
1503 1632
1504 1633
1505 //----------------------------------------------------------------------- 1634 //-----------------------------------------------------------------------
1506 // package-internal API 1635 // package-internal API
1507 //----------------------------------------------------------------------- 1636 //-----------------------------------------------------------------------
1508 1637
1509 /** 1638 /**
1510 * Returns the collator to use for lenient parsing. The collator is lazily crea ted: 1639 * Returns the collator to use for lenient parsing. The collator is lazily crea ted:
1511 * this function creates it the first time it's called. 1640 * this function creates it the first time it's called.
1512 * @return The collator to use for lenient parsing, or null if lenient parsing 1641 * @return The collator to use for lenient parsing, or null if lenient parsing
1513 * is turned off. 1642 * is turned off.
1514 */ 1643 */
1515 Collator* 1644 const RuleBasedCollator*
1516 RuleBasedNumberFormat::getCollator() const 1645 RuleBasedNumberFormat::getCollator() const
1517 { 1646 {
1518 #if !UCONFIG_NO_COLLATION 1647 #if !UCONFIG_NO_COLLATION
1519 if (!ruleSets) { 1648 if (!ruleSets) {
1520 return NULL; 1649 return NULL;
1521 } 1650 }
1522 1651
1523 // lazy-evaulate the collator 1652 // lazy-evaluate the collator
1524 if (collator == NULL && lenient) { 1653 if (collator == NULL && lenient) {
1525 // create a default collator based on the formatter's locale, 1654 // create a default collator based on the formatter's locale,
1526 // then pull out that collator's rules, append any additional 1655 // then pull out that collator's rules, append any additional
1527 // rules specified in the description, and create a _new_ 1656 // rules specified in the description, and create a _new_
1528 // collator based on the combinaiton of those rules 1657 // collator based on the combinaiton of those rules
1529 1658
1530 UErrorCode status = U_ZERO_ERROR; 1659 UErrorCode status = U_ZERO_ERROR;
1531 1660
1532 Collator* temp = Collator::createInstance(locale, status); 1661 Collator* temp = Collator::createInstance(locale, status);
1533 RuleBasedCollator* newCollator; 1662 RuleBasedCollator* newCollator;
1534 if (U_SUCCESS(status) && (newCollator = dynamic_cast<RuleBasedCollator*> (temp)) != NULL) { 1663 if (U_SUCCESS(status) && (newCollator = dynamic_cast<RuleBasedCollator*> (temp)) != NULL) {
1535 if (lenientParseRules) { 1664 if (lenientParseRules) {
1536 UnicodeString rules(newCollator->getRules()); 1665 UnicodeString rules(newCollator->getRules());
1537 rules.append(*lenientParseRules); 1666 rules.append(*lenientParseRules);
1538 1667
1539 newCollator = new RuleBasedCollator(rules, status); 1668 newCollator = new RuleBasedCollator(rules, status);
1540 // Exit if newCollator could not be created. 1669 // Exit if newCollator could not be created.
1541 if (newCollator == NULL) { 1670 if (newCollator == NULL) {
1542 » return NULL; 1671 return NULL;
1543 } 1672 }
1544 } else { 1673 } else {
1545 temp = NULL; 1674 temp = NULL;
1546 } 1675 }
1547 if (U_SUCCESS(status)) { 1676 if (U_SUCCESS(status)) {
1548 newCollator->setAttribute(UCOL_DECOMPOSITION_MODE, UCOL_ON, stat us); 1677 newCollator->setAttribute(UCOL_DECOMPOSITION_MODE, UCOL_ON, stat us);
1549 // cast away const 1678 // cast away const
1550 ((RuleBasedNumberFormat*)this)->collator = newCollator; 1679 ((RuleBasedNumberFormat*)this)->collator = newCollator;
1551 } else { 1680 } else {
1552 delete newCollator; 1681 delete newCollator;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 } 1740 }
1612 } 1741 }
1613 1742
1614 // Setting the symbols is equlivalent to adopting a newly created localized symb ols. 1743 // Setting the symbols is equlivalent to adopting a newly created localized symb ols.
1615 void 1744 void
1616 RuleBasedNumberFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbo ls) 1745 RuleBasedNumberFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbo ls)
1617 { 1746 {
1618 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); 1747 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
1619 } 1748 }
1620 1749
1750 PluralFormat *
1751 RuleBasedNumberFormat::createPluralFormat(UPluralType pluralType,
1752 const UnicodeString &pattern,
1753 UErrorCode& status) const
1754 {
1755 return new PluralFormat(locale, pluralType, pattern, status);
1756 }
1757
1621 U_NAMESPACE_END 1758 U_NAMESPACE_END
1622 1759
1623 /* U_HAVE_RBNF */ 1760 /* U_HAVE_RBNF */
1624 #endif 1761 #endif
OLDNEW
« no previous file with comments | « source/i18n/quantityformatter.cpp ('k') | source/i18n/rbt_data.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698