summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/i18n/number_padding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'intl/icu/source/i18n/number_padding.cpp')
-rw-r--r--intl/icu/source/i18n/number_padding.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/intl/icu/source/i18n/number_padding.cpp b/intl/icu/source/i18n/number_padding.cpp
new file mode 100644
index 0000000000..c320c3ffb6
--- /dev/null
+++ b/intl/icu/source/i18n/number_padding.cpp
@@ -0,0 +1,96 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/numberformatter.h"
+#include "number_types.h"
+#include "formatted_string_builder.h"
+#include "number_decimfmtprops.h"
+
+using namespace icu;
+using namespace icu::number;
+using namespace icu::number::impl;
+
+namespace {
+
+int32_t
+addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, FormattedStringBuilder &string, int32_t index,
+ UErrorCode &status) {
+ for (int32_t i = 0; i < requiredPadding; i++) {
+ // TODO: If appending to the end, this will cause actual insertion operations. Improve.
+ string.insertCodePoint(index, paddingCp, kUndefinedField, status);
+ }
+ return U16_LENGTH(paddingCp) * requiredPadding;
+}
+
+}
+
+Padder::Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position) : fWidth(width) {
+ // TODO(13034): Consider making this a string instead of code point.
+ fUnion.padding.fCp = cp;
+ fUnion.padding.fPosition = position;
+}
+
+Padder::Padder(int32_t width) : fWidth(width) {}
+
+Padder Padder::none() {
+ return {-1};
+}
+
+Padder Padder::codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position) {
+ // TODO: Validate the code point?
+ if (targetWidth >= 0) {
+ return {cp, targetWidth, position};
+ } else {
+ return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
+ }
+}
+
+Padder Padder::forProperties(const DecimalFormatProperties& properties) {
+ UChar32 padCp;
+ if (properties.padString.length() > 0) {
+ padCp = properties.padString.char32At(0);
+ } else {
+ padCp = kFallbackPaddingString[0];
+ }
+ return {padCp, properties.formatWidth, properties.padPosition.getOrDefault(UNUM_PAD_BEFORE_PREFIX)};
+}
+
+int32_t Padder::padAndApply(const Modifier &mod1, const Modifier &mod2,
+ FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
+ UErrorCode &status) const {
+ int32_t modLength = mod1.getCodePointCount() + mod2.getCodePointCount();
+ int32_t requiredPadding = fWidth - modLength - string.codePointCount();
+ U_ASSERT(leftIndex == 0 &&
+ rightIndex == string.length()); // fix the previous line to remove this assertion
+
+ int length = 0;
+ if (requiredPadding <= 0) {
+ // Padding is not required.
+ length += mod1.apply(string, leftIndex, rightIndex, status);
+ length += mod2.apply(string, leftIndex, rightIndex + length, status);
+ return length;
+ }
+
+ PadPosition position = fUnion.padding.fPosition;
+ UChar32 paddingCp = fUnion.padding.fCp;
+ if (position == UNUM_PAD_AFTER_PREFIX) {
+ length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status);
+ } else if (position == UNUM_PAD_BEFORE_SUFFIX) {
+ length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status);
+ }
+ length += mod1.apply(string, leftIndex, rightIndex + length, status);
+ length += mod2.apply(string, leftIndex, rightIndex + length, status);
+ if (position == UNUM_PAD_BEFORE_PREFIX) {
+ length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status);
+ } else if (position == UNUM_PAD_AFTER_SUFFIX) {
+ length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status);
+ }
+
+ return length;
+}
+
+#endif /* #if !UCONFIG_NO_FORMATTING */