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 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 UBool operator==(const MessagePattern &other) const;
00530
00536 inline UBool 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
00555
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 UBool operator==(const Part &other) const;
00801
00807 inline UBool 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
00826
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
00880
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
00931 MessagePatternPartsList *partsList;
00932 Part *parts;
00933 int32_t partsLength;
00934
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
00948
00949 #endif // __MESSAGEPATTERN_H__