00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __MESSAGEPATTERN_H__
00018 #define __MESSAGEPATTERN_H__
00019
00025 #include "unicode/utypes.h"
00026
00027 #if !UCONFIG_NO_FORMATTING
00028
00029 #include "unicode/parseerr.h"
00030 #include "unicode/unistr.h"
00031
00068 enum UMessagePatternApostropheMode {
00080 UMSGPAT_APOS_DOUBLE_OPTIONAL,
00089 UMSGPAT_APOS_DOUBLE_REQUIRED
00090 };
00094 typedef enum UMessagePatternApostropheMode UMessagePatternApostropheMode;
00095
00100 enum UMessagePatternPartType {
00110 UMSGPAT_PART_TYPE_MSG_START,
00119 UMSGPAT_PART_TYPE_MSG_LIMIT,
00127 UMSGPAT_PART_TYPE_SKIP_SYNTAX,
00134 UMSGPAT_PART_TYPE_INSERT_CHAR,
00142 UMSGPAT_PART_TYPE_REPLACE_NUMBER,
00153 UMSGPAT_PART_TYPE_ARG_START,
00160 UMSGPAT_PART_TYPE_ARG_LIMIT,
00165 UMSGPAT_PART_TYPE_ARG_NUMBER,
00171 UMSGPAT_PART_TYPE_ARG_NAME,
00177 UMSGPAT_PART_TYPE_ARG_TYPE,
00183 UMSGPAT_PART_TYPE_ARG_STYLE,
00189 UMSGPAT_PART_TYPE_ARG_SELECTOR,
00196 UMSGPAT_PART_TYPE_ARG_INT,
00204 UMSGPAT_PART_TYPE_ARG_DOUBLE
00205 };
00209 typedef enum UMessagePatternPartType UMessagePatternPartType;
00210
00219 enum UMessagePatternArgType {
00224 UMSGPAT_ARG_TYPE_NONE,
00230 UMSGPAT_ARG_TYPE_SIMPLE,
00236 UMSGPAT_ARG_TYPE_CHOICE,
00246 UMSGPAT_ARG_TYPE_PLURAL,
00251 UMSGPAT_ARG_TYPE_SELECT,
00257 UMSGPAT_ARG_TYPE_SELECTORDINAL
00258 };
00262 typedef enum UMessagePatternArgType UMessagePatternArgType;
00263
00270 #define UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) \
00271 ((argType)==UMSGPAT_ARG_TYPE_PLURAL || (argType)==UMSGPAT_ARG_TYPE_SELECTORDINAL)
00272
00273 enum {
00279 UMSGPAT_ARG_NAME_NOT_NUMBER=-1,
00280
00288 UMSGPAT_ARG_NAME_NOT_VALID=-2
00289 };
00290
00297 #define UMSGPAT_NO_NUMERIC_VALUE ((double)(-123456789))
00298
00299 U_NAMESPACE_BEGIN
00300
00301 class MessagePatternDoubleList;
00302 class MessagePatternPartsList;
00303
00360 class U_COMMON_API MessagePattern : public UObject {
00361 public:
00370 MessagePattern(UErrorCode &errorCode);
00371
00381 MessagePattern(UMessagePatternApostropheMode mode, UErrorCode &errorCode);
00382
00401 MessagePattern(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode);
00402
00408 MessagePattern(const MessagePattern &other);
00409
00416 MessagePattern &operator=(const MessagePattern &other);
00417
00422 virtual ~MessagePattern();
00423
00441 MessagePattern &parse(const UnicodeString &pattern,
00442 UParseError *parseError, UErrorCode &errorCode);
00443
00461 MessagePattern &parseChoiceStyle(const UnicodeString &pattern,
00462 UParseError *parseError, UErrorCode &errorCode);
00463
00481 MessagePattern &parsePluralStyle(const UnicodeString &pattern,
00482 UParseError *parseError, UErrorCode &errorCode);
00483
00501 MessagePattern &parseSelectStyle(const UnicodeString &pattern,
00502 UParseError *parseError, UErrorCode &errorCode);
00503
00509 void clear();
00510
00517 void clearPatternAndSetApostropheMode(UMessagePatternApostropheMode mode) {
00518 clear();
00519 aposMode=mode;
00520 }
00521
00527 UBool operator==(const MessagePattern &other) const;
00528
00534 inline UBool operator!=(const MessagePattern &other) const {
00535 return !operator==(other);
00536 }
00537
00542 int32_t hashCode() const;
00543
00548 UMessagePatternApostropheMode getApostropheMode() const {
00549 return aposMode;
00550 }
00551
00552
00553
00554
00559 const UnicodeString &getPatternString() const {
00560 return msg;
00561 }
00562
00568 UBool hasNamedArguments() const {
00569 return hasArgNames;
00570 }
00571
00577 UBool hasNumberedArguments() const {
00578 return hasArgNumbers;
00579 }
00580
00592 static int32_t validateArgumentName(const UnicodeString &name);
00593
00604 UnicodeString autoQuoteApostropheDeep() const;
00605
00606 class Part;
00607
00614 int32_t countParts() const {
00615 return partsLength;
00616 }
00617
00624 const Part &getPart(int32_t i) const {
00625 return parts[i];
00626 }
00627
00635 UMessagePatternPartType getPartType(int32_t i) const {
00636 return getPart(i).type;
00637 }
00638
00646 int32_t getPatternIndex(int32_t partIndex) const {
00647 return getPart(partIndex).index;
00648 }
00649
00657 UnicodeString getSubstring(const Part &part) const {
00658 return msg.tempSubString(part.index, part.length);
00659 }
00660
00668 UBool partSubstringMatches(const Part &part, const UnicodeString &s) const {
00669 return 0==msg.compare(part.index, part.length, s);
00670 }
00671
00678 double getNumericValue(const Part &part) const;
00679
00686 double getPluralOffset(int32_t pluralStart) const;
00687
00696 int32_t getLimitPartIndex(int32_t start) const {
00697 int32_t limit=getPart(start).limitPartIndex;
00698 if(limit<start) {
00699 return start;
00700 }
00701 return limit;
00702 }
00703
00711 class Part : public UMemory {
00712 public:
00717 Part() {}
00718
00724 UMessagePatternPartType getType() const {
00725 return type;
00726 }
00727
00733 int32_t getIndex() const {
00734 return index;
00735 }
00736
00743 int32_t getLength() const {
00744 return length;
00745 }
00746
00753 int32_t getLimit() const {
00754 return index+length;
00755 }
00756
00763 int32_t getValue() const {
00764 return value;
00765 }
00766
00773 UMessagePatternArgType getArgType() const {
00774 UMessagePatternPartType msgType=getType();
00775 if(msgType ==UMSGPAT_PART_TYPE_ARG_START || msgType ==UMSGPAT_PART_TYPE_ARG_LIMIT) {
00776 return (UMessagePatternArgType)value;
00777 } else {
00778 return UMSGPAT_ARG_TYPE_NONE;
00779 }
00780 }
00781
00789 static UBool hasNumericValue(UMessagePatternPartType type) {
00790 return type==UMSGPAT_PART_TYPE_ARG_INT || type==UMSGPAT_PART_TYPE_ARG_DOUBLE;
00791 }
00792
00798 UBool operator==(const Part &other) const;
00799
00805 inline UBool operator!=(const Part &other) const {
00806 return !operator==(other);
00807 }
00808
00813 int32_t hashCode() const {
00814 return ((type*37+index)*37+length)*37+value;
00815 }
00816
00817 private:
00818 friend class MessagePattern;
00819
00820 static const int32_t MAX_LENGTH=0xffff;
00821 static const int32_t MAX_VALUE=0x7fff;
00822
00823
00824
00825 UMessagePatternPartType type;
00826 int32_t index;
00827 uint16_t length;
00828 int16_t value;
00829 int32_t limitPartIndex;
00830 };
00831
00832 private:
00833 void preParse(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode);
00834
00835 void postParse();
00836
00837 int32_t parseMessage(int32_t index, int32_t msgStartLength,
00838 int32_t nestingLevel, UMessagePatternArgType parentType,
00839 UParseError *parseError, UErrorCode &errorCode);
00840
00841 int32_t parseArg(int32_t index, int32_t argStartLength, int32_t nestingLevel,
00842 UParseError *parseError, UErrorCode &errorCode);
00843
00844 int32_t parseSimpleStyle(int32_t index, UParseError *parseError, UErrorCode &errorCode);
00845
00846 int32_t parseChoiceStyle(int32_t index, int32_t nestingLevel,
00847 UParseError *parseError, UErrorCode &errorCode);
00848
00849 int32_t parsePluralOrSelectStyle(UMessagePatternArgType argType, int32_t index, int32_t nestingLevel,
00850 UParseError *parseError, UErrorCode &errorCode);
00851
00860 static int32_t parseArgNumber(const UnicodeString &s, int32_t start, int32_t limit);
00861
00862 int32_t parseArgNumber(int32_t start, int32_t limit) {
00863 return parseArgNumber(msg, start, limit);
00864 }
00865
00874 void parseDouble(int32_t start, int32_t limit, UBool allowInfinity,
00875 UParseError *parseError, UErrorCode &errorCode);
00876
00877
00878
00879
00880 int32_t skipWhiteSpace(int32_t index);
00881
00882 int32_t skipIdentifier(int32_t index);
00883
00888 int32_t skipDouble(int32_t index);
00889
00890 static UBool isArgTypeChar(UChar32 c);
00891
00892 UBool isChoice(int32_t index);
00893
00894 UBool isPlural(int32_t index);
00895
00896 UBool isSelect(int32_t index);
00897
00898 UBool isOrdinal(int32_t index);
00899
00904 UBool inMessageFormatPattern(int32_t nestingLevel);
00905
00910 UBool inTopLevelChoiceMessage(int32_t nestingLevel, UMessagePatternArgType parentType);
00911
00912 void addPart(UMessagePatternPartType type, int32_t index, int32_t length,
00913 int32_t value, UErrorCode &errorCode);
00914
00915 void addLimitPart(int32_t start,
00916 UMessagePatternPartType type, int32_t index, int32_t length,
00917 int32_t value, UErrorCode &errorCode);
00918
00919 void addArgDoublePart(double numericValue, int32_t start, int32_t length, UErrorCode &errorCode);
00920
00921 void setParseError(UParseError *parseError, int32_t index);
00922
00923 UBool init(UErrorCode &errorCode);
00924 UBool copyStorage(const MessagePattern &other, UErrorCode &errorCode);
00925
00926 UMessagePatternApostropheMode aposMode;
00927 UnicodeString msg;
00928
00929 MessagePatternPartsList *partsList;
00930 Part *parts;
00931 int32_t partsLength;
00932
00933 MessagePatternDoubleList *numericValuesList;
00934 double *numericValues;
00935 int32_t numericValuesLength;
00936 UBool hasArgNames;
00937 UBool hasArgNumbers;
00938 UBool needsAutoQuoting;
00939 };
00940
00941 U_NAMESPACE_END
00942
00943 #endif // !UCONFIG_NO_FORMATTING
00944
00945 #endif // __MESSAGEPATTERN_H__