tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

simpleformatter.h (12898B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 ******************************************************************************
      5 * Copyright (C) 2014-2016, International Business Machines
      6 * Corporation and others.  All Rights Reserved.
      7 ******************************************************************************
      8 * simpleformatter.h
      9 */
     10 
     11 #ifndef __SIMPLEFORMATTER_H__
     12 #define __SIMPLEFORMATTER_H__
     13 
     14 /**
     15 * \file
     16 * \brief C++ API: Simple formatter, minimal subset of MessageFormat.
     17 */
     18 
     19 #include "unicode/utypes.h"
     20 
     21 #if U_SHOW_CPLUSPLUS_API
     22 
     23 #include "unicode/unistr.h"
     24 
     25 U_NAMESPACE_BEGIN
     26 
     27 // Forward declaration:
     28 namespace number::impl {
     29 class SimpleModifier;
     30 }
     31 
     32 /**
     33 * Formats simple patterns like "{1} was born in {0}".
     34 * Minimal subset of MessageFormat; fast, simple, minimal dependencies.
     35 * Supports only numbered arguments with no type nor style parameters,
     36 * and formats only string values.
     37 * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
     38 *
     39 * Factory methods set error codes for syntax errors
     40 * and for too few or too many arguments/placeholders.
     41 *
     42 * SimpleFormatter objects are thread-safe except for assignment and applying new patterns.
     43 *
     44 * Example:
     45 * <pre>
     46 * UErrorCode errorCode = U_ZERO_ERROR;
     47 * SimpleFormatter fmt("{1} '{born}' in {0}", errorCode);
     48 * UnicodeString result;
     49 *
     50 * // Output: "paul {born} in england"
     51 * fmt.format("england", "paul", result, errorCode);
     52 * </pre>
     53 *
     54 * This class is not intended for public subclassing.
     55 *
     56 * @see MessageFormat
     57 * @see UMessagePatternApostropheMode
     58 * @stable ICU 57
     59 */
     60 class U_COMMON_API SimpleFormatter final : public UMemory {
     61 public:
     62    /**
     63     * Default constructor.
     64     * @stable ICU 57
     65     */
     66    SimpleFormatter() : compiledPattern(static_cast<char16_t>(0)) {}
     67 
     68    /**
     69     * Constructs a formatter from the pattern string.
     70     *
     71     * @param pattern The pattern string.
     72     * @param errorCode ICU error code in/out parameter.
     73     *                  Must fulfill U_SUCCESS before the function call.
     74     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
     75     * @stable ICU 57
     76     */
     77    SimpleFormatter(const UnicodeString& pattern, UErrorCode &errorCode) {
     78        applyPattern(pattern, errorCode);
     79    }
     80 
     81    /**
     82     * Constructs a formatter from the pattern string.
     83     * The number of arguments checked against the given limits is the
     84     * highest argument number plus one, not the number of occurrences of arguments.
     85     *
     86     * @param pattern The pattern string.
     87     * @param min The pattern must have at least this many arguments.
     88     * @param max The pattern must have at most this many arguments.
     89     * @param errorCode ICU error code in/out parameter.
     90     *                  Must fulfill U_SUCCESS before the function call.
     91     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
     92     *                  too few or too many arguments.
     93     * @stable ICU 57
     94     */
     95    SimpleFormatter(const UnicodeString& pattern, int32_t min, int32_t max,
     96                    UErrorCode &errorCode) {
     97        applyPatternMinMaxArguments(pattern, min, max, errorCode);
     98    }
     99 
    100    /**
    101     * Copy constructor.
    102     * @stable ICU 57
    103     */
    104    SimpleFormatter(const SimpleFormatter& other)
    105            : compiledPattern(other.compiledPattern) {}
    106 
    107    /**
    108     * Assignment operator.
    109     * @stable ICU 57
    110     */
    111    SimpleFormatter &operator=(const SimpleFormatter& other);
    112 
    113    /**
    114     * Destructor.
    115     * @stable ICU 57
    116     */
    117    ~SimpleFormatter();
    118 
    119    /**
    120     * Changes this object according to the new pattern.
    121     *
    122     * @param pattern The pattern string.
    123     * @param errorCode ICU error code in/out parameter.
    124     *                  Must fulfill U_SUCCESS before the function call.
    125     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
    126     * @return true if U_SUCCESS(errorCode).
    127     * @stable ICU 57
    128     */
    129    UBool applyPattern(const UnicodeString &pattern, UErrorCode &errorCode) {
    130        return applyPatternMinMaxArguments(pattern, 0, INT32_MAX, errorCode);
    131    }
    132 
    133    /**
    134     * Changes this object according to the new pattern.
    135     * The number of arguments checked against the given limits is the
    136     * highest argument number plus one, not the number of occurrences of arguments.
    137     *
    138     * @param pattern The pattern string.
    139     * @param min The pattern must have at least this many arguments.
    140     * @param max The pattern must have at most this many arguments.
    141     * @param errorCode ICU error code in/out parameter.
    142     *                  Must fulfill U_SUCCESS before the function call.
    143     *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
    144     *                  too few or too many arguments.
    145     * @return true if U_SUCCESS(errorCode).
    146     * @stable ICU 57
    147     */
    148    UBool applyPatternMinMaxArguments(const UnicodeString &pattern,
    149                                      int32_t min, int32_t max, UErrorCode &errorCode);
    150 
    151    /**
    152     * @return The max argument number + 1.
    153     * @stable ICU 57
    154     */
    155    int32_t getArgumentLimit() const {
    156        return getArgumentLimit(compiledPattern.getBuffer(), compiledPattern.length());
    157    }
    158 
    159    /**
    160     * Formats the given value, appending to the appendTo builder.
    161     * The argument value must not be the same object as appendTo.
    162     * getArgumentLimit() must be at most 1.
    163     *
    164     * @param value0 Value for argument {0}.
    165     * @param appendTo Gets the formatted pattern and value appended.
    166     * @param errorCode ICU error code in/out parameter.
    167     *                  Must fulfill U_SUCCESS before the function call.
    168     * @return appendTo
    169     * @stable ICU 57
    170     */
    171    UnicodeString &format(
    172            const UnicodeString &value0,
    173            UnicodeString &appendTo, UErrorCode &errorCode) const;
    174 
    175    /**
    176     * Formats the given values, appending to the appendTo builder.
    177     * An argument value must not be the same object as appendTo.
    178     * getArgumentLimit() must be at most 2.
    179     *
    180     * @param value0 Value for argument {0}.
    181     * @param value1 Value for argument {1}.
    182     * @param appendTo Gets the formatted pattern and values appended.
    183     * @param errorCode ICU error code in/out parameter.
    184     *                  Must fulfill U_SUCCESS before the function call.
    185     * @return appendTo
    186     * @stable ICU 57
    187     */
    188    UnicodeString &format(
    189            const UnicodeString &value0,
    190            const UnicodeString &value1,
    191            UnicodeString &appendTo, UErrorCode &errorCode) const;
    192 
    193    /**
    194     * Formats the given values, appending to the appendTo builder.
    195     * An argument value must not be the same object as appendTo.
    196     * getArgumentLimit() must be at most 3.
    197     *
    198     * @param value0 Value for argument {0}.
    199     * @param value1 Value for argument {1}.
    200     * @param value2 Value for argument {2}.
    201     * @param appendTo Gets the formatted pattern and values appended.
    202     * @param errorCode ICU error code in/out parameter.
    203     *                  Must fulfill U_SUCCESS before the function call.
    204     * @return appendTo
    205     * @stable ICU 57
    206     */
    207    UnicodeString &format(
    208            const UnicodeString &value0,
    209            const UnicodeString &value1,
    210            const UnicodeString &value2,
    211            UnicodeString &appendTo, UErrorCode &errorCode) const;
    212 
    213    /**
    214     * Formats the given values, appending to the appendTo string.
    215     *
    216     * @param values The argument values.
    217     *               An argument value must not be the same object as appendTo.
    218     *               Can be nullptr if valuesLength==getArgumentLimit()==0.
    219     * @param valuesLength The length of the values array.
    220     *                     Must be at least getArgumentLimit().
    221     * @param appendTo Gets the formatted pattern and values appended.
    222     * @param offsets offsets[i] receives the offset of where
    223     *                values[i] replaced pattern argument {i}.
    224     *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
    225     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
    226     * @param offsetsLength The length of the offsets array.
    227     * @param errorCode ICU error code in/out parameter.
    228     *                  Must fulfill U_SUCCESS before the function call.
    229     * @return appendTo
    230     * @stable ICU 57
    231     */
    232    UnicodeString &formatAndAppend(
    233            const UnicodeString *const *values, int32_t valuesLength,
    234            UnicodeString &appendTo,
    235            int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
    236 
    237    /**
    238     * Formats the given values, replacing the contents of the result string.
    239     * May optimize by actually appending to the result if it is the same object
    240     * as the value corresponding to the initial argument in the pattern.
    241     *
    242     * @param values The argument values.
    243     *               An argument value may be the same object as result.
    244     *               Can be nullptr if valuesLength==getArgumentLimit()==0.
    245     * @param valuesLength The length of the values array.
    246     *                     Must be at least getArgumentLimit().
    247     * @param result Gets its contents replaced by the formatted pattern and values.
    248     * @param offsets offsets[i] receives the offset of where
    249     *                values[i] replaced pattern argument {i}.
    250     *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
    251     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
    252     * @param offsetsLength The length of the offsets array.
    253     * @param errorCode ICU error code in/out parameter.
    254     *                  Must fulfill U_SUCCESS before the function call.
    255     * @return result
    256     * @stable ICU 57
    257     */
    258    UnicodeString &formatAndReplace(
    259            const UnicodeString *const *values, int32_t valuesLength,
    260            UnicodeString &result,
    261            int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
    262 
    263    /**
    264     * Returns the pattern text with none of the arguments.
    265     * Like formatting with all-empty string values.
    266     * @stable ICU 57
    267     */
    268    UnicodeString getTextWithNoArguments() const {
    269        return getTextWithNoArguments(
    270            compiledPattern.getBuffer(),
    271            compiledPattern.length(),
    272            nullptr,
    273            0);
    274    }
    275 
    276 #ifndef U_HIDE_INTERNAL_API
    277    /**
    278     * Returns the pattern text with none of the arguments.
    279     * Like formatting with all-empty string values.
    280     *
    281     * TODO(ICU-20406): Replace this with an Iterator interface.
    282     *
    283     * @param offsets offsets[i] receives the offset of where {i} was located
    284     *                before it was replaced by an empty string.
    285     *                For example, "a{0}b{1}" produces offset 1 for i=0 and 2 for i=1.
    286     *                Can be nullptr if offsetsLength==0.
    287     *                If there is no {i} in the pattern, then offsets[i] is set to -1.
    288     * @param offsetsLength The length of the offsets array.
    289     *
    290     * @internal
    291     */
    292    UnicodeString getTextWithNoArguments(int32_t *offsets, int32_t offsetsLength) const {
    293        return getTextWithNoArguments(
    294            compiledPattern.getBuffer(),
    295            compiledPattern.length(),
    296            offsets,
    297            offsetsLength);
    298    }
    299 #endif // U_HIDE_INTERNAL_API
    300 
    301 private:
    302    /**
    303     * Binary representation of the compiled pattern.
    304     * Index 0: One more than the highest argument number.
    305     * Followed by zero or more arguments or literal-text segments.
    306     *
    307     * An argument is stored as its number, less than ARG_NUM_LIMIT.
    308     * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
    309     * followed by that many chars.
    310     */
    311    UnicodeString compiledPattern;
    312 
    313    static inline int32_t getArgumentLimit(const char16_t *compiledPattern,
    314                                              int32_t compiledPatternLength) {
    315        return compiledPatternLength == 0 ? 0 : compiledPattern[0];
    316    }
    317 
    318    static UnicodeString getTextWithNoArguments(
    319        const char16_t *compiledPattern,
    320        int32_t compiledPatternLength,
    321        int32_t *offsets,
    322        int32_t offsetsLength);
    323 
    324    static UnicodeString &format(
    325            const char16_t *compiledPattern, int32_t compiledPatternLength,
    326            const UnicodeString *const *values,
    327            UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
    328            int32_t *offsets, int32_t offsetsLength,
    329            UErrorCode &errorCode);
    330 
    331    // Give access to internals to SimpleModifier for number formatting
    332    friend class number::impl::SimpleModifier;
    333 };
    334 
    335 U_NAMESPACE_END
    336 
    337 #endif /* U_SHOW_CPLUSPLUS_API */
    338 
    339 #endif  // __SIMPLEFORMATTER_H__