00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __MESSAGEPATTERN_H__
00016 #define __MESSAGEPATTERN_H__
00017
00023 #include "unicode/utypes.h"
00024
00025 #if !UCONFIG_NO_FORMATTING
00026
00027 #include "unicode/parseerr.h"
00028 #include "unicode/unistr.h"
00029
00066 enum UMessagePatternApostropheMode {
00078 UMSGPAT_APOS_DOUBLE_OPTIONAL,
00087 UMSGPAT_APOS_DOUBLE_REQUIRED
00088 };
00092 typedef enum UMessagePatternApostropheMode UMessagePatternApostropheMode;
00093
00098 enum UMessagePatternPartType {
00108 UMSGPAT_PART_TYPE_MSG_START,
00117 UMSGPAT_PART_TYPE_MSG_LIMIT,
00125 UMSGPAT_PART_TYPE_SKIP_SYNTAX,
00132 UMSGPAT_PART_TYPE_INSERT_CHAR,
00140 UMSGPAT_PART_TYPE_REPLACE_NUMBER,
00151 UMSGPAT_PART_TYPE_ARG_START,
00158 UMSGPAT_PART_TYPE_ARG_LIMIT,
00163 UMSGPAT_PART_TYPE_ARG_NUMBER,
00169 UMSGPAT_PART_TYPE_ARG_NAME,
00175 UMSGPAT_PART_TYPE_ARG_TYPE,
00181 UMSGPAT_PART_TYPE_ARG_STYLE,
00187 UMSGPAT_PART_TYPE_ARG_SELECTOR,
00194 UMSGPAT_PART_TYPE_ARG_INT,
00202 UMSGPAT_PART_TYPE_ARG_DOUBLE
00203 };
00207 typedef enum UMessagePatternPartType UMessagePatternPartType;
00208
00217 enum UMessagePatternArgType {
00222 UMSGPAT_ARG_TYPE_NONE,
00228 UMSGPAT_ARG_TYPE_SIMPLE,
00234 UMSGPAT_ARG_TYPE_CHOICE,
00244 UMSGPAT_ARG_TYPE_PLURAL,
00249 UMSGPAT_ARG_TYPE_SELECT,
00255 UMSGPAT_ARG_TYPE_SELECTORDINAL
00256 };
00260 typedef enum UMessagePatternArgType UMessagePatternArgType;
00261
00268 #define UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) \
00269 ((argType)==UMSGPAT_ARG_TYPE_PLURAL || (argType)==UMSGPAT_ARG_TYPE_SELECTORDINAL)
00270
00271 enum {
00277 UMSGPAT_ARG_NAME_NOT_NUMBER=-1,
00278
00286 UMSGPAT_ARG_NAME_NOT_VALID=-2
00287 };
00288
00295 #define UMSGPAT_NO_NUMERIC_VALUE ((double)(-123456789))
00296
00297 U_NAMESPACE_BEGIN
00298
00299 class MessagePatternDoubleList;
00300 class MessagePatternPartsList;
00301
00358 class U_COMMON_API MessagePattern : public UObject {
00359 public:
00368 MessagePattern(UErrorCode &errorCode);
00369
00379 MessagePattern(UMessagePatternApostropheMode mode, UErrorCode &errorCode);
00380
00399 MessagePattern(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode);
00400
00406 MessagePattern(const MessagePattern &other);
00407
00414 MessagePattern &operator=(const MessagePattern &other);
00415
00420 virtual ~MessagePattern();
00421
00439 MessagePattern &parse(const UnicodeString &pattern,
00440 UParseError *parseError, UErrorCode &errorCode);
00441
00459 MessagePattern &parseChoiceStyle(const UnicodeString &pattern,
00460 UParseError *parseError, UErrorCode &errorCode);
00461
00479 MessagePattern &parsePluralStyle(const UnicodeString &pattern,
00480 UParseError *parseError, UErrorCode &errorCode);
00481
00499 MessagePattern &parseSelectStyle(const UnicodeString &pattern,
00500 UParseError *parseError, UErrorCode &errorCode);
00501
00507 void clear();
00508
00515 void clearPatternAndSetApostropheMode(UMessagePatternApostropheMode mode) {
00516 clear();
00517 aposMode=mode;
00518 }
00519
00525 UBool operator==(const MessagePattern &other) const;
00526
00532 inline UBool operator!=(const MessagePattern &other) const {
00533 return !operator==(other);
00534 }
00535
00540 int32_t hashCode() const;
00541
00546 UMessagePatternApostropheMode getApostropheMode() const {
00547 return aposMode;
00548 }
00549
00550
00551
00552
00557 const UnicodeString &getPatternString() const {
00558 return msg;
00559 }
00560
00566 UBool hasNamedArguments() const {
00567 return hasArgNames;
00568 }
00569
00575 UBool hasNumberedArguments() const {
00576 return hasArgNumbers;
00577 }
00578
00590 static int32_t validateArgumentName(const UnicodeString &name);
00591
00602 UnicodeString autoQuoteApostropheDeep() const;
00603
00604 class Part;
00605
00612 int32_t countParts() const {
00613 return partsLength;
00614 }
00615
00622 const Part &getPart(int32_t i) const {
00623 return parts[i];
00624 }
00625
00633 UMessagePatternPartType getPartType(int32_t i) const {
00634 return getPart(i).type;
00635 }
00636
00644 int32_t getPatternIndex(int32_t partIndex) const {
00645 return getPart(partIndex).index;
00646 }
00647
00655 UnicodeString getSubstring(const Part &part) const {
00656 return msg.tempSubString(part.index, part.length);
00657 }
00658
00666 UBool partSubstringMatches(const Part &part, const UnicodeString &s) const {
00667 return 0==msg.compare(part.index, part.length, s);
00668 }
00669
00676 double getNumericValue(const Part &part) const;
00677
00684 double getPluralOffset(int32_t pluralStart) const;
00685
00694 int32_t getLimitPartIndex(int32_t start) const {
00695 int32_t limit=getPart(start).limitPartIndex;
00696 if(limit<start) {
00697 return start;
00698 }
00699 return limit;
00700 }
00701
00709 class Part : public UMemory {
00710 public:
00715 Part() {}
00716
00722 UMessagePatternPartType getType() const {
00723 return type;
00724 }
00725
00731 int32_t getIndex() const {
00732 return index;
00733 }
00734
00741 int32_t getLength() const {
00742 return length;
00743 }
00744
00751 int32_t getLimit() const {
00752 return index+length;
00753 }
00754
00761 int32_t getValue() const {
00762 return value;
00763 }
00764
00771 UMessagePatternArgType getArgType() const {
00772 UMessagePatternPartType type=getType();
00773 if(type==UMSGPAT_PART_TYPE_ARG_START || type==UMSGPAT_PART_TYPE_ARG_LIMIT) {
00774 return (UMessagePatternArgType)value;
00775 } else {
00776 return UMSGPAT_ARG_TYPE_NONE;
00777 }
00778 }
00779
00787 static UBool hasNumericValue(UMessagePatternPartType type) {
00788 return type==UMSGPAT_PART_TYPE_ARG_INT || type==UMSGPAT_PART_TYPE_ARG_DOUBLE;
00789 }
00790
00796 UBool operator==(const Part &other) const;
00797
00803 inline UBool operator!=(const Part &other) const {
00804 return !operator==(other);
00805 }
00806
00811 int32_t hashCode() const {
00812 return ((type*37+index)*37+length)*37+value;
00813 }
00814
00815 private:
00816 friend class MessagePattern;
00817
00818 static const int32_t MAX_LENGTH=0xffff;
00819 static const int32_t MAX_VALUE=0x7fff;
00820
00821
00822
00823 UMessagePatternPartType type;
00824 int32_t index;
00825 uint16_t length;
00826 int16_t value;
00827 int32_t limitPartIndex;
00828 };
00829
00830 private:
00831 void preParse(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode);
00832
00833 void postParse();
00834
00835 int32_t parseMessage(int32_t index, int32_t msgStartLength,
00836 int32_t nestingLevel, UMessagePatternArgType parentType,
00837 UParseError *parseError, UErrorCode &errorCode);
00838
00839 int32_t parseArg(int32_t index, int32_t argStartLength, int32_t nestingLevel,
00840 UParseError *parseError, UErrorCode &errorCode);
00841
00842 int32_t parseSimpleStyle(int32_t index, UParseError *parseError, UErrorCode &errorCode);
00843
00844 int32_t parseChoiceStyle(int32_t index, int32_t nestingLevel,
00845 UParseError *parseError, UErrorCode &errorCode);
00846
00847 int32_t parsePluralOrSelectStyle(UMessagePatternArgType argType, int32_t index, int32_t nestingLevel,
00848 UParseError *parseError, UErrorCode &errorCode);
00849
00858 static int32_t parseArgNumber(const UnicodeString &s, int32_t start, int32_t limit);
00859
00860 int32_t parseArgNumber(int32_t start, int32_t limit) {
00861 return parseArgNumber(msg, start, limit);
00862 }
00863
00872 void parseDouble(int32_t start, int32_t limit, UBool allowInfinity,
00873 UParseError *parseError, UErrorCode &errorCode);
00874
00875
00876
00877
00878 int32_t skipWhiteSpace(int32_t index);
00879
00880 int32_t skipIdentifier(int32_t index);
00881
00886 int32_t skipDouble(int32_t index);
00887
00888 static UBool isArgTypeChar(UChar32 c);
00889
00890 UBool isChoice(int32_t index);
00891
00892 UBool isPlural(int32_t index);
00893
00894 UBool isSelect(int32_t index);
00895
00896 UBool isOrdinal(int32_t index);
00897
00902 UBool inMessageFormatPattern(int32_t nestingLevel);
00903
00908 UBool inTopLevelChoiceMessage(int32_t nestingLevel, UMessagePatternArgType parentType);
00909
00910 void addPart(UMessagePatternPartType type, int32_t index, int32_t length,
00911 int32_t value, UErrorCode &errorCode);
00912
00913 void addLimitPart(int32_t start,
00914 UMessagePatternPartType type, int32_t index, int32_t length,
00915 int32_t value, UErrorCode &errorCode);
00916
00917 void addArgDoublePart(double numericValue, int32_t start, int32_t length, UErrorCode &errorCode);
00918
00919 void setParseError(UParseError *parseError, int32_t index);
00920
00921 UBool init(UErrorCode &errorCode);
00922 UBool copyStorage(const MessagePattern &other, UErrorCode &errorCode);
00923
00924 UMessagePatternApostropheMode aposMode;
00925 UnicodeString msg;
00926
00927 MessagePatternPartsList *partsList;
00928 Part *parts;
00929 int32_t partsLength;
00930
00931 MessagePatternDoubleList *numericValuesList;
00932 double *numericValues;
00933 int32_t numericValuesLength;
00934 UBool hasArgNames;
00935 UBool hasArgNumbers;
00936 UBool needsAutoQuoting;
00937 };
00938
00939 U_NAMESPACE_END
00940
00941 #endif // !UCONFIG_NO_FORMATTING
00942
00943 #endif // __MESSAGEPATTERN_H__