Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:08

0001 // © 2016 and later: Unicode, Inc. and others.
0002 // License & terms of use: http://www.unicode.org/copyright.html
0003 /*
0004 ******************************************************************************
0005 * Copyright (C) 2014-2016, International Business Machines
0006 * Corporation and others.  All Rights Reserved.
0007 ******************************************************************************
0008 * simpleformatter.h
0009 */
0010 
0011 #ifndef __SIMPLEFORMATTER_H__
0012 #define __SIMPLEFORMATTER_H__
0013 
0014 /**
0015  * \file
0016  * \brief C++ API: Simple formatter, minimal subset of MessageFormat.
0017  */
0018 
0019 #include "unicode/utypes.h"
0020 
0021 #if U_SHOW_CPLUSPLUS_API
0022 
0023 #include "unicode/unistr.h"
0024 
0025 U_NAMESPACE_BEGIN
0026 
0027 // Forward declaration:
0028 namespace number {
0029 namespace impl {
0030 class SimpleModifier;
0031 }
0032 }
0033 
0034 /**
0035  * Formats simple patterns like "{1} was born in {0}".
0036  * Minimal subset of MessageFormat; fast, simple, minimal dependencies.
0037  * Supports only numbered arguments with no type nor style parameters,
0038  * and formats only string values.
0039  * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
0040  *
0041  * Factory methods set error codes for syntax errors
0042  * and for too few or too many arguments/placeholders.
0043  *
0044  * SimpleFormatter objects are thread-safe except for assignment and applying new patterns.
0045  *
0046  * Example:
0047  * <pre>
0048  * UErrorCode errorCode = U_ZERO_ERROR;
0049  * SimpleFormatter fmt("{1} '{born}' in {0}", errorCode);
0050  * UnicodeString result;
0051  *
0052  * // Output: "paul {born} in england"
0053  * fmt.format("england", "paul", result, errorCode);
0054  * </pre>
0055  *
0056  * This class is not intended for public subclassing.
0057  *
0058  * @see MessageFormat
0059  * @see UMessagePatternApostropheMode
0060  * @stable ICU 57
0061  */
0062 class U_COMMON_API SimpleFormatter final : public UMemory {
0063 public:
0064     /**
0065      * Default constructor.
0066      * @stable ICU 57
0067      */
0068     SimpleFormatter() : compiledPattern((char16_t)0) {}
0069 
0070     /**
0071      * Constructs a formatter from the pattern string.
0072      *
0073      * @param pattern The pattern string.
0074      * @param errorCode ICU error code in/out parameter.
0075      *                  Must fulfill U_SUCCESS before the function call.
0076      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
0077      * @stable ICU 57
0078      */
0079     SimpleFormatter(const UnicodeString& pattern, UErrorCode &errorCode) {
0080         applyPattern(pattern, errorCode);
0081     }
0082 
0083     /**
0084      * Constructs a formatter from the pattern string.
0085      * The number of arguments checked against the given limits is the
0086      * highest argument number plus one, not the number of occurrences of arguments.
0087      *
0088      * @param pattern The pattern string.
0089      * @param min The pattern must have at least this many arguments.
0090      * @param max The pattern must have at most this many arguments.
0091      * @param errorCode ICU error code in/out parameter.
0092      *                  Must fulfill U_SUCCESS before the function call.
0093      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
0094      *                  too few or too many arguments.
0095      * @stable ICU 57
0096      */
0097     SimpleFormatter(const UnicodeString& pattern, int32_t min, int32_t max,
0098                     UErrorCode &errorCode) {
0099         applyPatternMinMaxArguments(pattern, min, max, errorCode);
0100     }
0101 
0102     /**
0103      * Copy constructor.
0104      * @stable ICU 57
0105      */
0106     SimpleFormatter(const SimpleFormatter& other)
0107             : compiledPattern(other.compiledPattern) {}
0108 
0109     /**
0110      * Assignment operator.
0111      * @stable ICU 57
0112      */
0113     SimpleFormatter &operator=(const SimpleFormatter& other);
0114 
0115     /**
0116      * Destructor.
0117      * @stable ICU 57
0118      */
0119     ~SimpleFormatter();
0120 
0121     /**
0122      * Changes this object according to the new pattern.
0123      *
0124      * @param pattern The pattern string.
0125      * @param errorCode ICU error code in/out parameter.
0126      *                  Must fulfill U_SUCCESS before the function call.
0127      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
0128      * @return true if U_SUCCESS(errorCode).
0129      * @stable ICU 57
0130      */
0131     UBool applyPattern(const UnicodeString &pattern, UErrorCode &errorCode) {
0132         return applyPatternMinMaxArguments(pattern, 0, INT32_MAX, errorCode);
0133     }
0134 
0135     /**
0136      * Changes this object according to the new pattern.
0137      * The number of arguments checked against the given limits is the
0138      * highest argument number plus one, not the number of occurrences of arguments.
0139      *
0140      * @param pattern The pattern string.
0141      * @param min The pattern must have at least this many arguments.
0142      * @param max The pattern must have at most this many arguments.
0143      * @param errorCode ICU error code in/out parameter.
0144      *                  Must fulfill U_SUCCESS before the function call.
0145      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
0146      *                  too few or too many arguments.
0147      * @return true if U_SUCCESS(errorCode).
0148      * @stable ICU 57
0149      */
0150     UBool applyPatternMinMaxArguments(const UnicodeString &pattern,
0151                                       int32_t min, int32_t max, UErrorCode &errorCode);
0152 
0153     /**
0154      * @return The max argument number + 1.
0155      * @stable ICU 57
0156      */
0157     int32_t getArgumentLimit() const {
0158         return getArgumentLimit(compiledPattern.getBuffer(), compiledPattern.length());
0159     }
0160 
0161     /**
0162      * Formats the given value, appending to the appendTo builder.
0163      * The argument value must not be the same object as appendTo.
0164      * getArgumentLimit() must be at most 1.
0165      *
0166      * @param value0 Value for argument {0}.
0167      * @param appendTo Gets the formatted pattern and value appended.
0168      * @param errorCode ICU error code in/out parameter.
0169      *                  Must fulfill U_SUCCESS before the function call.
0170      * @return appendTo
0171      * @stable ICU 57
0172      */
0173     UnicodeString &format(
0174             const UnicodeString &value0,
0175             UnicodeString &appendTo, UErrorCode &errorCode) const;
0176 
0177     /**
0178      * Formats the given values, appending to the appendTo builder.
0179      * An argument value must not be the same object as appendTo.
0180      * getArgumentLimit() must be at most 2.
0181      *
0182      * @param value0 Value for argument {0}.
0183      * @param value1 Value for argument {1}.
0184      * @param appendTo Gets the formatted pattern and values appended.
0185      * @param errorCode ICU error code in/out parameter.
0186      *                  Must fulfill U_SUCCESS before the function call.
0187      * @return appendTo
0188      * @stable ICU 57
0189      */
0190     UnicodeString &format(
0191             const UnicodeString &value0,
0192             const UnicodeString &value1,
0193             UnicodeString &appendTo, UErrorCode &errorCode) const;
0194 
0195     /**
0196      * Formats the given values, appending to the appendTo builder.
0197      * An argument value must not be the same object as appendTo.
0198      * getArgumentLimit() must be at most 3.
0199      *
0200      * @param value0 Value for argument {0}.
0201      * @param value1 Value for argument {1}.
0202      * @param value2 Value for argument {2}.
0203      * @param appendTo Gets the formatted pattern and values appended.
0204      * @param errorCode ICU error code in/out parameter.
0205      *                  Must fulfill U_SUCCESS before the function call.
0206      * @return appendTo
0207      * @stable ICU 57
0208      */
0209     UnicodeString &format(
0210             const UnicodeString &value0,
0211             const UnicodeString &value1,
0212             const UnicodeString &value2,
0213             UnicodeString &appendTo, UErrorCode &errorCode) const;
0214 
0215     /**
0216      * Formats the given values, appending to the appendTo string.
0217      *
0218      * @param values The argument values.
0219      *               An argument value must not be the same object as appendTo.
0220      *               Can be nullptr if valuesLength==getArgumentLimit()==0.
0221      * @param valuesLength The length of the values array.
0222      *                     Must be at least getArgumentLimit().
0223      * @param appendTo Gets the formatted pattern and values appended.
0224      * @param offsets offsets[i] receives the offset of where
0225      *                values[i] replaced pattern argument {i}.
0226      *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
0227      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
0228      * @param offsetsLength The length of the offsets array.
0229      * @param errorCode ICU error code in/out parameter.
0230      *                  Must fulfill U_SUCCESS before the function call.
0231      * @return appendTo
0232      * @stable ICU 57
0233      */
0234     UnicodeString &formatAndAppend(
0235             const UnicodeString *const *values, int32_t valuesLength,
0236             UnicodeString &appendTo,
0237             int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
0238 
0239     /**
0240      * Formats the given values, replacing the contents of the result string.
0241      * May optimize by actually appending to the result if it is the same object
0242      * as the value corresponding to the initial argument in the pattern.
0243      *
0244      * @param values The argument values.
0245      *               An argument value may be the same object as result.
0246      *               Can be nullptr if valuesLength==getArgumentLimit()==0.
0247      * @param valuesLength The length of the values array.
0248      *                     Must be at least getArgumentLimit().
0249      * @param result Gets its contents replaced by the formatted pattern and values.
0250      * @param offsets offsets[i] receives the offset of where
0251      *                values[i] replaced pattern argument {i}.
0252      *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
0253      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
0254      * @param offsetsLength The length of the offsets array.
0255      * @param errorCode ICU error code in/out parameter.
0256      *                  Must fulfill U_SUCCESS before the function call.
0257      * @return result
0258      * @stable ICU 57
0259      */
0260     UnicodeString &formatAndReplace(
0261             const UnicodeString *const *values, int32_t valuesLength,
0262             UnicodeString &result,
0263             int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
0264 
0265     /**
0266      * Returns the pattern text with none of the arguments.
0267      * Like formatting with all-empty string values.
0268      * @stable ICU 57
0269      */
0270     UnicodeString getTextWithNoArguments() const {
0271         return getTextWithNoArguments(
0272             compiledPattern.getBuffer(),
0273             compiledPattern.length(),
0274             nullptr,
0275             0);
0276     }
0277 
0278 #ifndef U_HIDE_INTERNAL_API
0279     /**
0280      * Returns the pattern text with none of the arguments.
0281      * Like formatting with all-empty string values.
0282      *
0283      * TODO(ICU-20406): Replace this with an Iterator interface.
0284      *
0285      * @param offsets offsets[i] receives the offset of where {i} was located
0286      *                before it was replaced by an empty string.
0287      *                For example, "a{0}b{1}" produces offset 1 for i=0 and 2 for i=1.
0288      *                Can be nullptr if offsetsLength==0.
0289      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
0290      * @param offsetsLength The length of the offsets array.
0291      *
0292      * @internal
0293      */
0294     UnicodeString getTextWithNoArguments(int32_t *offsets, int32_t offsetsLength) const {
0295         return getTextWithNoArguments(
0296             compiledPattern.getBuffer(),
0297             compiledPattern.length(),
0298             offsets,
0299             offsetsLength);
0300     }
0301 #endif // U_HIDE_INTERNAL_API
0302 
0303 private:
0304     /**
0305      * Binary representation of the compiled pattern.
0306      * Index 0: One more than the highest argument number.
0307      * Followed by zero or more arguments or literal-text segments.
0308      *
0309      * An argument is stored as its number, less than ARG_NUM_LIMIT.
0310      * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
0311      * followed by that many chars.
0312      */
0313     UnicodeString compiledPattern;
0314 
0315     static inline int32_t getArgumentLimit(const char16_t *compiledPattern,
0316                                               int32_t compiledPatternLength) {
0317         return compiledPatternLength == 0 ? 0 : compiledPattern[0];
0318     }
0319 
0320     static UnicodeString getTextWithNoArguments(
0321         const char16_t *compiledPattern,
0322         int32_t compiledPatternLength,
0323         int32_t *offsets,
0324         int32_t offsetsLength);
0325 
0326     static UnicodeString &format(
0327             const char16_t *compiledPattern, int32_t compiledPatternLength,
0328             const UnicodeString *const *values,
0329             UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
0330             int32_t *offsets, int32_t offsetsLength,
0331             UErrorCode &errorCode);
0332 
0333     // Give access to internals to SimpleModifier for number formatting
0334     friend class number::impl::SimpleModifier;
0335 };
0336 
0337 U_NAMESPACE_END
0338 
0339 #endif /* U_SHOW_CPLUSPLUS_API */
0340 
0341 #endif  // __SIMPLEFORMATTER_H__