|
ICU 73.2
73.2
|
00001 // © 2016 and later: Unicode, Inc. and others. 00002 // License & terms of use: http://www.unicode.org/copyright.html 00003 /* 00004 ******************************************************************************* 00005 * Copyright (C) 2011-2013, International Business Machines 00006 * Corporation and others. All Rights Reserved. 00007 ******************************************************************************* 00008 * file name: messagepattern.h 00009 * encoding: UTF-8 00010 * tab size: 8 (not used) 00011 * indentation:4 00012 * 00013 * created on: 2011mar14 00014 * created by: Markus W. Scherer 00015 */ 00016 00017 #ifndef __MESSAGEPATTERN_H__ 00018 #define __MESSAGEPATTERN_H__ 00019 00025 #include "unicode/utypes.h" 00026 00027 #if U_SHOW_CPLUSPLUS_API 00028 00029 #if !UCONFIG_NO_FORMATTING 00030 00031 #include "unicode/parseerr.h" 00032 #include "unicode/unistr.h" 00033 00070 enum UMessagePatternApostropheMode { 00082 UMSGPAT_APOS_DOUBLE_OPTIONAL, 00091 UMSGPAT_APOS_DOUBLE_REQUIRED 00092 }; 00096 typedef enum UMessagePatternApostropheMode UMessagePatternApostropheMode; 00097 00102 enum UMessagePatternPartType { 00112 UMSGPAT_PART_TYPE_MSG_START, 00121 UMSGPAT_PART_TYPE_MSG_LIMIT, 00129 UMSGPAT_PART_TYPE_SKIP_SYNTAX, 00136 UMSGPAT_PART_TYPE_INSERT_CHAR, 00144 UMSGPAT_PART_TYPE_REPLACE_NUMBER, 00155 UMSGPAT_PART_TYPE_ARG_START, 00162 UMSGPAT_PART_TYPE_ARG_LIMIT, 00167 UMSGPAT_PART_TYPE_ARG_NUMBER, 00173 UMSGPAT_PART_TYPE_ARG_NAME, 00179 UMSGPAT_PART_TYPE_ARG_TYPE, 00185 UMSGPAT_PART_TYPE_ARG_STYLE, 00191 UMSGPAT_PART_TYPE_ARG_SELECTOR, 00198 UMSGPAT_PART_TYPE_ARG_INT, 00206 UMSGPAT_PART_TYPE_ARG_DOUBLE 00207 }; 00211 typedef enum UMessagePatternPartType UMessagePatternPartType; 00212 00221 enum UMessagePatternArgType { 00226 UMSGPAT_ARG_TYPE_NONE, 00232 UMSGPAT_ARG_TYPE_SIMPLE, 00238 UMSGPAT_ARG_TYPE_CHOICE, 00248 UMSGPAT_ARG_TYPE_PLURAL, 00253 UMSGPAT_ARG_TYPE_SELECT, 00259 UMSGPAT_ARG_TYPE_SELECTORDINAL 00260 }; 00264 typedef enum UMessagePatternArgType UMessagePatternArgType; 00265 00272 #define UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) \ 00273 ((argType)==UMSGPAT_ARG_TYPE_PLURAL || (argType)==UMSGPAT_ARG_TYPE_SELECTORDINAL) 00274 00275 enum { 00281 UMSGPAT_ARG_NAME_NOT_NUMBER=-1, 00282 00290 UMSGPAT_ARG_NAME_NOT_VALID=-2 00291 }; 00292 00299 #define UMSGPAT_NO_NUMERIC_VALUE ((double)(-123456789)) 00300 00301 U_NAMESPACE_BEGIN 00302 00303 class MessagePatternDoubleList; 00304 class MessagePatternPartsList; 00305 00362 class U_COMMON_API MessagePattern : public UObject { 00363 public: 00372 MessagePattern(UErrorCode &errorCode); 00373 00383 MessagePattern(UMessagePatternApostropheMode mode, UErrorCode &errorCode); 00384 00403 MessagePattern(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode); 00404 00410 MessagePattern(const MessagePattern &other); 00411 00418 MessagePattern &operator=(const MessagePattern &other); 00419 00424 virtual ~MessagePattern(); 00425 00443 MessagePattern &parse(const UnicodeString &pattern, 00444 UParseError *parseError, UErrorCode &errorCode); 00445 00463 MessagePattern &parseChoiceStyle(const UnicodeString &pattern, 00464 UParseError *parseError, UErrorCode &errorCode); 00465 00483 MessagePattern &parsePluralStyle(const UnicodeString &pattern, 00484 UParseError *parseError, UErrorCode &errorCode); 00485 00503 MessagePattern &parseSelectStyle(const UnicodeString &pattern, 00504 UParseError *parseError, UErrorCode &errorCode); 00505 00511 void clear(); 00512 00519 void clearPatternAndSetApostropheMode(UMessagePatternApostropheMode mode) { 00520 clear(); 00521 aposMode=mode; 00522 } 00523 00529 bool operator==(const MessagePattern &other) const; 00530 00536 inline bool operator!=(const MessagePattern &other) const { 00537 return !operator==(other); 00538 } 00539 00544 int32_t hashCode() const; 00545 00550 UMessagePatternApostropheMode getApostropheMode() const { 00551 return aposMode; 00552 } 00553 00554 // Java has package-private jdkAposMode() here. 00555 // In C++, this is declared in the MessageImpl class. 00556 00561 const UnicodeString &getPatternString() const { 00562 return msg; 00563 } 00564 00570 UBool hasNamedArguments() const { 00571 return hasArgNames; 00572 } 00573 00579 UBool hasNumberedArguments() const { 00580 return hasArgNumbers; 00581 } 00582 00594 static int32_t validateArgumentName(const UnicodeString &name); 00595 00606 UnicodeString autoQuoteApostropheDeep() const; 00607 00608 class Part; 00609 00616 int32_t countParts() const { 00617 return partsLength; 00618 } 00619 00626 const Part &getPart(int32_t i) const { 00627 return parts[i]; 00628 } 00629 00637 UMessagePatternPartType getPartType(int32_t i) const { 00638 return getPart(i).type; 00639 } 00640 00648 int32_t getPatternIndex(int32_t partIndex) const { 00649 return getPart(partIndex).index; 00650 } 00651 00659 UnicodeString getSubstring(const Part &part) const { 00660 return msg.tempSubString(part.index, part.length); 00661 } 00662 00670 UBool partSubstringMatches(const Part &part, const UnicodeString &s) const { 00671 return 0==msg.compare(part.index, part.length, s); 00672 } 00673 00680 double getNumericValue(const Part &part) const; 00681 00688 double getPluralOffset(int32_t pluralStart) const; 00689 00698 int32_t getLimitPartIndex(int32_t start) const { 00699 int32_t limit=getPart(start).limitPartIndex; 00700 if(limit<start) { 00701 return start; 00702 } 00703 return limit; 00704 } 00705 00713 class Part : public UMemory { 00714 public: 00719 Part() {} 00720 00726 UMessagePatternPartType getType() const { 00727 return type; 00728 } 00729 00735 int32_t getIndex() const { 00736 return index; 00737 } 00738 00745 int32_t getLength() const { 00746 return length; 00747 } 00748 00755 int32_t getLimit() const { 00756 return index+length; 00757 } 00758 00765 int32_t getValue() const { 00766 return value; 00767 } 00768 00775 UMessagePatternArgType getArgType() const { 00776 UMessagePatternPartType msgType=getType(); 00777 if(msgType ==UMSGPAT_PART_TYPE_ARG_START || msgType ==UMSGPAT_PART_TYPE_ARG_LIMIT) { 00778 return (UMessagePatternArgType)value; 00779 } else { 00780 return UMSGPAT_ARG_TYPE_NONE; 00781 } 00782 } 00783 00791 static UBool hasNumericValue(UMessagePatternPartType type) { 00792 return type==UMSGPAT_PART_TYPE_ARG_INT || type==UMSGPAT_PART_TYPE_ARG_DOUBLE; 00793 } 00794 00800 bool operator==(const Part &other) const; 00801 00807 inline bool operator!=(const Part &other) const { 00808 return !operator==(other); 00809 } 00810 00815 int32_t hashCode() const { 00816 return ((type*37+index)*37+length)*37+value; 00817 } 00818 00819 private: 00820 friend class MessagePattern; 00821 00822 static const int32_t MAX_LENGTH=0xffff; 00823 static const int32_t MAX_VALUE=0x7fff; 00824 00825 // Some fields are not final because they are modified during pattern parsing. 00826 // After pattern parsing, the parts are effectively immutable. 00827 UMessagePatternPartType type; 00828 int32_t index; 00829 uint16_t length; 00830 int16_t value; 00831 int32_t limitPartIndex; 00832 }; 00833 00834 private: 00835 void preParse(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode); 00836 00837 void postParse(); 00838 00839 int32_t parseMessage(int32_t index, int32_t msgStartLength, 00840 int32_t nestingLevel, UMessagePatternArgType parentType, 00841 UParseError *parseError, UErrorCode &errorCode); 00842 00843 int32_t parseArg(int32_t index, int32_t argStartLength, int32_t nestingLevel, 00844 UParseError *parseError, UErrorCode &errorCode); 00845 00846 int32_t parseSimpleStyle(int32_t index, UParseError *parseError, UErrorCode &errorCode); 00847 00848 int32_t parseChoiceStyle(int32_t index, int32_t nestingLevel, 00849 UParseError *parseError, UErrorCode &errorCode); 00850 00851 int32_t parsePluralOrSelectStyle(UMessagePatternArgType argType, int32_t index, int32_t nestingLevel, 00852 UParseError *parseError, UErrorCode &errorCode); 00853 00862 static int32_t parseArgNumber(const UnicodeString &s, int32_t start, int32_t limit); 00863 00864 int32_t parseArgNumber(int32_t start, int32_t limit) { 00865 return parseArgNumber(msg, start, limit); 00866 } 00867 00876 void parseDouble(int32_t start, int32_t limit, UBool allowInfinity, 00877 UParseError *parseError, UErrorCode &errorCode); 00878 00879 // Java has package-private appendReducedApostrophes() here. 00880 // In C++, this is declared in the MessageImpl class. 00881 00882 int32_t skipWhiteSpace(int32_t index); 00883 00884 int32_t skipIdentifier(int32_t index); 00885 00890 int32_t skipDouble(int32_t index); 00891 00892 static UBool isArgTypeChar(UChar32 c); 00893 00894 UBool isChoice(int32_t index); 00895 00896 UBool isPlural(int32_t index); 00897 00898 UBool isSelect(int32_t index); 00899 00900 UBool isOrdinal(int32_t index); 00901 00906 UBool inMessageFormatPattern(int32_t nestingLevel); 00907 00912 UBool inTopLevelChoiceMessage(int32_t nestingLevel, UMessagePatternArgType parentType); 00913 00914 void addPart(UMessagePatternPartType type, int32_t index, int32_t length, 00915 int32_t value, UErrorCode &errorCode); 00916 00917 void addLimitPart(int32_t start, 00918 UMessagePatternPartType type, int32_t index, int32_t length, 00919 int32_t value, UErrorCode &errorCode); 00920 00921 void addArgDoublePart(double numericValue, int32_t start, int32_t length, UErrorCode &errorCode); 00922 00923 void setParseError(UParseError *parseError, int32_t index); 00924 00925 UBool init(UErrorCode &errorCode); 00926 UBool copyStorage(const MessagePattern &other, UErrorCode &errorCode); 00927 00928 UMessagePatternApostropheMode aposMode; 00929 UnicodeString msg; 00930 // ArrayList<Part> parts=new ArrayList<Part>(); 00931 MessagePatternPartsList *partsList; 00932 Part *parts; 00933 int32_t partsLength; 00934 // ArrayList<Double> numericValues; 00935 MessagePatternDoubleList *numericValuesList; 00936 double *numericValues; 00937 int32_t numericValuesLength; 00938 UBool hasArgNames; 00939 UBool hasArgNumbers; 00940 UBool needsAutoQuoting; 00941 }; 00942 00943 U_NAMESPACE_END 00944 00945 #endif // !UCONFIG_NO_FORMATTING 00946 00947 #endif /* U_SHOW_CPLUSPLUS_API */ 00948 00949 #endif // __MESSAGEPATTERN_H__
1.7.6.1