ICU 73.2  73.2
messagepattern.h
Go to the documentation of this file.
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__