michael@0: /* michael@0: ****************************************************************************** michael@0: * Copyright (C) 1997-2007, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ****************************************************************************** michael@0: * file name: nfsubs.h michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * Modification history michael@0: * Date Name Comments michael@0: * 10/11/2001 Doug Ported from ICU4J michael@0: */ michael@0: michael@0: #ifndef NFSUBS_H michael@0: #define NFSUBS_H michael@0: michael@0: #include "unicode/utypes.h" michael@0: #include "unicode/uobject.h" michael@0: #include "nfrule.h" michael@0: michael@0: #if U_HAVE_RBNF michael@0: michael@0: #include "unicode/utypes.h" michael@0: #include "unicode/decimfmt.h" michael@0: #include "nfrs.h" michael@0: #include michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: class NFSubstitution : public UObject { michael@0: int32_t pos; michael@0: const NFRuleSet* ruleSet; michael@0: const DecimalFormat* numberFormat; michael@0: michael@0: protected: michael@0: NFSubstitution(int32_t pos, michael@0: const NFRuleSet* ruleSet, michael@0: const RuleBasedNumberFormat* rbnf, michael@0: const UnicodeString& description, michael@0: UErrorCode& status); michael@0: michael@0: /** michael@0: * Get the Ruleset of the object. michael@0: * @return the Ruleset of the object. michael@0: */ michael@0: const NFRuleSet* getRuleSet() const { return ruleSet; } michael@0: michael@0: /** michael@0: * get the NumberFormat of this object. michael@0: * @return the numberformat of this object. michael@0: */ michael@0: const DecimalFormat* getNumberFormat() const { return numberFormat; } michael@0: michael@0: public: michael@0: static NFSubstitution* makeSubstitution(int32_t pos, michael@0: const NFRule* rule, michael@0: const NFRule* predecessor, michael@0: const NFRuleSet* ruleSet, michael@0: const RuleBasedNumberFormat* rbnf, michael@0: const UnicodeString& description, michael@0: UErrorCode& status); michael@0: michael@0: /** michael@0: * Destructor. michael@0: */ michael@0: virtual ~NFSubstitution(); michael@0: michael@0: /** michael@0: * Return true if the given Format objects are semantically equal. michael@0: * Objects of different subclasses are considered unequal. michael@0: * @param rhs the object to be compared with. michael@0: * @return true if the given Format objects are semantically equal. michael@0: */ michael@0: virtual UBool operator==(const NFSubstitution& rhs) const; michael@0: michael@0: /** michael@0: * Return true if the given Format objects are semantically unequal. michael@0: * Objects of different subclasses are considered unequal. michael@0: * @param rhs the object to be compared with. michael@0: * @return true if the given Format objects are semantically unequal. michael@0: */ michael@0: UBool operator!=(const NFSubstitution& rhs) const { return !operator==(rhs); } michael@0: michael@0: /** michael@0: * Sets the substitution's divisor. Used by NFRule.setBaseValue(). michael@0: * A no-op for all substitutions except multiplier and modulus michael@0: * substitutions. michael@0: * @param radix The radix of the divisor michael@0: * @param exponent The exponent of the divisor michael@0: */ michael@0: virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status); michael@0: michael@0: /** michael@0: * Replaces result with the string describing the substitution. michael@0: * @param result Output param which will receive the string. michael@0: */ michael@0: virtual void toString(UnicodeString& result) const; michael@0: michael@0: //----------------------------------------------------------------------- michael@0: // formatting michael@0: //----------------------------------------------------------------------- michael@0: michael@0: /** michael@0: * Performs a mathematical operation on the number, formats it using michael@0: * either ruleSet or decimalFormat, and inserts the result into michael@0: * toInsertInto. michael@0: * @param number The number being formatted. michael@0: * @param toInsertInto The string we insert the result into michael@0: * @param pos The position in toInsertInto where the owning rule's michael@0: * rule text begins (this value is added to this substitution's michael@0: * position to determine exactly where to insert the new text) michael@0: */ michael@0: virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos) const; michael@0: michael@0: /** michael@0: * Performs a mathematical operation on the number, formats it using michael@0: * either ruleSet or decimalFormat, and inserts the result into michael@0: * toInsertInto. michael@0: * @param number The number being formatted. michael@0: * @param toInsertInto The string we insert the result into michael@0: * @param pos The position in toInsertInto where the owning rule's michael@0: * rule text begins (this value is added to this substitution's michael@0: * position to determine exactly where to insert the new text) michael@0: */ michael@0: virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const; michael@0: michael@0: protected: michael@0: /** michael@0: * Subclasses override this function to perform some kind of michael@0: * mathematical operation on the number. The result of this operation michael@0: * is formatted using the rule set or DecimalFormat that this michael@0: * substitution refers to, and the result is inserted into the result michael@0: * string. michael@0: * @param The number being formatted michael@0: * @return The result of performing the opreration on the number michael@0: */ michael@0: virtual int64_t transformNumber(int64_t number) const = 0; michael@0: michael@0: /** michael@0: * Subclasses override this function to perform some kind of michael@0: * mathematical operation on the number. The result of this operation michael@0: * is formatted using the rule set or DecimalFormat that this michael@0: * substitution refers to, and the result is inserted into the result michael@0: * string. michael@0: * @param The number being formatted michael@0: * @return The result of performing the opreration on the number michael@0: */ michael@0: virtual double transformNumber(double number) const = 0; michael@0: michael@0: public: michael@0: //----------------------------------------------------------------------- michael@0: // parsing michael@0: //----------------------------------------------------------------------- michael@0: michael@0: /** michael@0: * Parses a string using the rule set or DecimalFormat belonging michael@0: * to this substitution. If there's a match, a mathematical michael@0: * operation (the inverse of the one used in formatting) is michael@0: * performed on the result of the parse and the value passed in michael@0: * and returned as the result. The parse position is updated to michael@0: * point to the first unmatched character in the string. michael@0: * @param text The string to parse michael@0: * @param parsePosition On entry, ignored, but assumed to be 0. michael@0: * On exit, this is updated to point to the first unmatched michael@0: * character (or 0 if the substitution didn't match) michael@0: * @param baseValue A partial parse result that should be michael@0: * combined with the result of this parse michael@0: * @param upperBound When searching the rule set for a rule michael@0: * matching the string passed in, only rules with base values michael@0: * lower than this are considered michael@0: * @param lenientParse If true and matching against rules fails, michael@0: * the substitution will also try matching the text against michael@0: * numerals using a default-costructed NumberFormat. If false, michael@0: * no extra work is done. (This value is false whenever the michael@0: * formatter isn't in lenient-parse mode, but is also false michael@0: * under some conditions even when the formatter _is_ in michael@0: * lenient-parse mode.) michael@0: * @return If there's a match, this is the result of composing michael@0: * baseValue with whatever was returned from matching the michael@0: * characters. This will be either a Long or a Double. If there's michael@0: * no match this is new Long(0) (not null), and parsePosition michael@0: * is left unchanged. michael@0: */ michael@0: virtual UBool doParse(const UnicodeString& text, michael@0: ParsePosition& parsePosition, michael@0: double baseValue, michael@0: double upperBound, michael@0: UBool lenientParse, michael@0: Formattable& result) const; michael@0: michael@0: /** michael@0: * Derives a new value from the two values passed in. The two values michael@0: * are typically either the base values of two rules (the one containing michael@0: * the substitution and the one matching the substitution) or partial michael@0: * parse results derived in some other way. The operation is generally michael@0: * the inverse of the operation performed by transformNumber(). michael@0: * @param newRuleValue The value produced by matching this substitution michael@0: * @param oldRuleValue The value that was passed to the substitution michael@0: * by the rule that owns it michael@0: * @return A third value derived from the other two, representing a michael@0: * partial parse result michael@0: */ michael@0: virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const = 0; michael@0: michael@0: /** michael@0: * Calculates an upper bound when searching for a rule that matches michael@0: * this substitution. Rules with base values greater than or equal michael@0: * to upperBound are not considered. michael@0: * @param oldUpperBound The current upper-bound setting. The new michael@0: * upper bound can't be any higher. michael@0: * @return the upper bound when searching for a rule that matches michael@0: * this substitution. michael@0: */ michael@0: virtual double calcUpperBound(double oldUpperBound) const = 0; michael@0: michael@0: //----------------------------------------------------------------------- michael@0: // simple accessors michael@0: //----------------------------------------------------------------------- michael@0: michael@0: /** michael@0: * Returns the substitution's position in the rule that owns it. michael@0: * @return The substitution's position in the rule that owns it. michael@0: */ michael@0: int32_t getPos() const { return pos; } michael@0: michael@0: /** michael@0: * Returns the character used in the textual representation of michael@0: * substitutions of this type. Used by toString(). michael@0: * @return This substitution's token character. michael@0: */ michael@0: virtual UChar tokenChar() const = 0; michael@0: michael@0: /** michael@0: * Returns true if this is a null substitution. (We didn't do this michael@0: * with instanceof partially because it causes source files to michael@0: * proliferate and partially because we have to port this to C++.) michael@0: * @return true if this object is an instance of NullSubstitution michael@0: */ michael@0: virtual UBool isNullSubstitution() const; michael@0: michael@0: /** michael@0: * Returns true if this is a modulus substitution. (We didn't do this michael@0: * with instanceof partially because it causes source files to michael@0: * proliferate and partially because we have to port this to C++.) michael@0: * @return true if this object is an instance of ModulusSubstitution michael@0: */ michael@0: virtual UBool isModulusSubstitution() const; michael@0: michael@0: private: michael@0: NFSubstitution(const NFSubstitution &other); // forbid copying of this class michael@0: NFSubstitution &operator=(const NFSubstitution &other); // forbid copying of this class michael@0: michael@0: public: michael@0: static UClassID getStaticClassID(void); michael@0: virtual UClassID getDynamicClassID(void) const; michael@0: }; michael@0: michael@0: U_NAMESPACE_END michael@0: michael@0: /* U_HAVE_RBNF */ michael@0: #endif michael@0: michael@0: // NFSUBS_H michael@0: #endif