U_FORMAT_INEXACT_ERROR, /**< Cannot format a number exactly and rounding mode is ROUND_UNNECESSARY @stable ICU 4.8 */
#ifndef U_HIDE_DRAFT_API
U_NUMBER_ARG_OUTOFBOUNDS_ERROR, /**< The argument to a NumberFormatter helper method was out of bounds; the bounds are usually 0 to 999. @draft ICU 61 */
+ U_NUMBER_SKELETON_SYNTAX_ERROR, /**< The number skeleton passed to C++ NumberFormatter or C UNumberFormatter was invalid or contained a syntax error. @draft ICU 62 */
#endif // U_HIDE_DRAFT_API
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal formatting API error code.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
- U_FMT_PARSE_ERROR_LIMIT = 0x10113,
+ U_FMT_PARSE_ERROR_LIMIT = 0x10114,
#endif // U_HIDE_DEPRECATED_API
/*
"U_DEFAULT_KEYWORD_MISSING",
"U_DECIMAL_NUMBER_SYNTAX_ERROR",
"U_FORMAT_INEXACT_ERROR",
- "U_NUMBER_ARG_OUTOFBOUNDS_ERROR"
+ "U_NUMBER_ARG_OUTOFBOUNDS_ERROR",
+ "U_NUMBER_SKELETON_SYNTAX_ERROR",
};
static const char * const
return result->string.length();
}
- return result->string.toUnicodeString().extract(buffer, bufferCapacity, *ec);
+ return result->string.toTempUnicodeString().extract(buffer, bufferCapacity, *ec);
}
U_CAPI void U_EXPORT2
blueprint_helpers::parseExponentSignOption(const StringSegment& segment, MacroProps& macros, UErrorCode&) {
// Get the sign display type out of the CharsTrie data structure.
UCharsTrie tempStemTrie(kSerializedStemTrie);
- UStringTrieResult result = tempStemTrie.next(segment.toUnicodeString().getBuffer(), segment.length());
+ UStringTrieResult result = tempStemTrie.next(
+ segment.toTempUnicodeString().getBuffer(),
+ segment.length());
if (result != USTRINGTRIE_INTERMEDIATE_VALUE && result != USTRINGTRIE_FINAL_VALUE) {
return false;
}
void blueprint_helpers::parseCurrencyOption(const StringSegment& segment, MacroProps& macros,
UErrorCode& status) {
+ // Can't use toTempUnicodeString() because getTerminatedBuffer is non-const
const UChar* currencyCode = segment.toUnicodeString().getTerminatedBuffer();
UErrorCode localStatus = U_ZERO_ERROR;
CurrencyUnit currency(currencyCode, localStatus);
void blueprint_helpers::parseMeasureUnitOption(const StringSegment& segment, MacroProps& macros,
UErrorCode& status) {
- UnicodeString stemString = segment.toUnicodeString();
+ const UnicodeString stemString = segment.toTempUnicodeString();
// NOTE: The category (type) of the unit is guaranteed to be a valid subtag (alphanumeric)
// http://unicode.org/reports/tr35/#Validity_Data
UErrorCode& status) {
// Need to do char <-> UChar conversion...
CharString buffer;
- SKELETON_UCHAR_TO_CHAR(buffer, segment.toUnicodeString(), 0, segment.length(), status);
+ SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status);
// Utilize DecimalQuantity/decNumber to parse this for us.
DecimalQuantity dq;
UErrorCode& status) {
// Need to do char <-> UChar conversion...
CharString buffer;
- SKELETON_UCHAR_TO_CHAR(buffer, segment.toUnicodeString(), 0, segment.length(), status);
+ SKELETON_UCHAR_TO_CHAR(buffer, segment.toTempUnicodeString(), 0, segment.length(), status);
NumberingSystem* ns = NumberingSystem::createInstanceByName(buffer.data(), status);
if (ns == nullptr) {
U_NAMESPACE_BEGIN namespace number {
namespace impl {
-static constexpr UErrorCode U_NUMBER_SKELETON_SYNTAX_ERROR = U_ILLEGAL_ARGUMENT_ERROR;
-
// Forward-declaration
struct SeenMacroProps;
}
UnicodeString NumberStringBuilder::toUnicodeString() const {
+ return UnicodeString(getCharPtr() + fZero, fLength);
+}
+
+const UnicodeString NumberStringBuilder::toTempUnicodeString() const {
// Readonly-alias constructor:
return UnicodeString(FALSE, getCharPtr() + fZero, fLength);
}
int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status);
+ /**
+ * Gets a "safe" UnicodeString that can be used even after the NumberStringBuilder is destructed.
+ * */
UnicodeString toUnicodeString() const;
+ /**
+ * Gets an "unsafe" UnicodeString that is valid only as long as the NumberStringBuilder is alive and
+ * unchanged. Slightly faster than toUnicodeString().
+ */
+ const UnicodeString toTempUnicodeString() const;
+
UnicodeString toDebugString() const;
const char16_t *chars() const;
}
}
+ /**
+ * Gets a "safe" UnicodeString that can be used even after the CharSequence is destructed.
+ * */
virtual UnicodeString toUnicodeString() const = 0;
+
+ /**
+ * Gets an "unsafe" UnicodeString that is valid only as long as the CharSequence is alive and
+ * unchanged. Slightly faster than toUnicodeString().
+ */
+ virtual const UnicodeString toTempUnicodeString() const = 0;
};
class U_I18N_API AffixPatternProvider {
}
UnicodeString toUnicodeString() const U_OVERRIDE {
- // Allocate a UnicodeString of the correct length
- UnicodeString output(length(), 0, -1);
- for (int32_t i = 0; i < length(); i++) {
- output.append(charAt(i));
- }
- return output;
+ // Performs a copy:
+ return fStr;
+ }
+
+ const UnicodeString toTempUnicodeString() const U_OVERRIDE {
+ // Readonly alias:
+ return UnicodeString().fastCopyFrom(fStr);
}
private:
return false;
}
- // NOTE: This requires a new UnicodeString to be allocated, instead of using the StringSegment.
- // This should be fixed with #13584.
- UnicodeString segmentString = segment.toUnicodeString();
+ // NOTE: This call site should be improved with #13584.
+ const UnicodeString segmentString = segment.toTempUnicodeString();
// Try to parse the currency
ParsePosition ppos(0);
}
UnicodeString StringSegment::toUnicodeString() const {
+ return UnicodeString(fStr.getBuffer() + fStart, fEnd - fStart);
+}
+
+const UnicodeString StringSegment::toTempUnicodeString() const {
// Use the readonly-aliasing constructor for efficiency.
return UnicodeString(FALSE, fStr.getBuffer() + fStart, fEnd - fStart);
}
}
bool StringSegment::operator==(const UnicodeString& other) const {
- return toUnicodeString() == other;
+ return toTempUnicodeString() == other;
}
UnicodeString toUnicodeString() const override;
+ const UnicodeString toTempUnicodeString() const override;
+
/**
* Returns the first code point in the string segment, or -1 if the string starts with an invalid
* code point.
/**
* \file
- * \brief C API: NumberFormat
+ * \brief C API: Compatibility APIs for number formatting.
*
* <h2> Number Format C API </h2>
*
- * <p><strong>IMPORTANT:</strong> New users with C++ capabilities are
- * strongly encouraged to see if numberformatter.h fits their use case.
+ * <p><strong>IMPORTANT:</strong> New users with are strongly encouraged to
+ * see if unumberformatter.h fits their use case. Although not deprecated,
+ * this header is provided for backwards compatibility only.
*
* Number Format C API Provides functions for
* formatting and parsing a number. Also provides methods for
* number format is opened using the given pattern, which must conform
* to the syntax described in DecimalFormat or RuleBasedNumberFormat,
* respectively.
+ *
+ * <p><strong>NOTE::</strong> New users with are strongly encouraged to
+ * use unumf_openWithSkeletonAndLocale instead of unum_open.
+ *
* @param pattern A pattern specifying the format to use.
* This parameter is ignored unless the style is
* UNUM_PATTERN_DECIMAL or UNUM_PATTERN_RULEBASED.
AffixUtils::unescape(UnicodeStringCharSequence(input), sb, 0, provider, status);
assertSuccess("Spot 1", status);
assertEquals(input, expected, sb.toUnicodeString());
+ assertEquals(input, expected, sb.toTempUnicodeString());
}
// Test insertion position
void StringSegmentTest::testCharAt() {
StringSegment segment(SAMPLE_STRING, 0);
assertEquals("Initial", SAMPLE_STRING, segment.toUnicodeString());
+ assertEquals("Initial", SAMPLE_STRING, segment.toTempUnicodeString());
segment.adjustOffset(3);
assertEquals("After adjust-offset", UnicodeString(u"radio 📻"), segment.toUnicodeString());
+ assertEquals("After adjust-offset", UnicodeString(u"radio 📻"), segment.toTempUnicodeString());
segment.setLength(5);
assertEquals("After adjust-length", UnicodeString(u"radio"), segment.toUnicodeString());
+ assertEquals("After adjust-length", UnicodeString(u"radio"), segment.toTempUnicodeString());
}
void StringSegmentTest::testGetCodePoint() {