tor-browser

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

number_padding.cpp (3490B)


      1 // © 2017 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 
      4 #include "unicode/utypes.h"
      5 
      6 #if !UCONFIG_NO_FORMATTING
      7 
      8 #include "unicode/numberformatter.h"
      9 #include "number_types.h"
     10 #include "formatted_string_builder.h"
     11 #include "number_decimfmtprops.h"
     12 
     13 using namespace icu;
     14 using namespace icu::number;
     15 using namespace icu::number::impl;
     16 
     17 namespace {
     18 
     19 int32_t
     20 addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, FormattedStringBuilder &string, int32_t index,
     21                 UErrorCode &status) {
     22    for (int32_t i = 0; i < requiredPadding; i++) {
     23        // TODO: If appending to the end, this will cause actual insertion operations. Improve.
     24        string.insertCodePoint(index, paddingCp, kUndefinedField, status);
     25    }
     26    return U16_LENGTH(paddingCp) * requiredPadding;
     27 }
     28 
     29 }
     30 
     31 Padder::Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position) : fWidth(width) {
     32    // TODO(13034): Consider making this a string instead of code point.
     33    fUnion.padding.fCp = cp;
     34    fUnion.padding.fPosition = position;
     35 }
     36 
     37 Padder::Padder(int32_t width) : fWidth(width) {}
     38 
     39 Padder Padder::none() {
     40    return {-1};
     41 }
     42 
     43 Padder Padder::codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position) {
     44    // TODO: Validate the code point?
     45    if (targetWidth >= 0) {
     46        return {cp, targetWidth, position};
     47    } else {
     48        return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
     49    }
     50 }
     51 
     52 Padder Padder::forProperties(const DecimalFormatProperties& properties) {
     53    UChar32 padCp;
     54    if (properties.padString.length() > 0) {
     55        padCp = properties.padString.char32At(0);
     56    } else {
     57        padCp = kFallbackPaddingString[0];
     58    }
     59    return {padCp, properties.formatWidth, properties.padPosition.getOrDefault(UNUM_PAD_BEFORE_PREFIX)};
     60 }
     61 
     62 int32_t Padder::padAndApply(const Modifier &mod1, const Modifier &mod2,
     63                            FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
     64                            UErrorCode &status) const {
     65    int32_t modLength = mod1.getCodePointCount() + mod2.getCodePointCount();
     66    int32_t requiredPadding = fWidth - modLength - string.codePointCount();
     67    U_ASSERT(leftIndex == 0 &&
     68             rightIndex == string.length()); // fix the previous line to remove this assertion
     69 
     70    int length = 0;
     71    if (requiredPadding <= 0) {
     72        // Padding is not required.
     73        length += mod1.apply(string, leftIndex, rightIndex, status);
     74        length += mod2.apply(string, leftIndex, rightIndex + length, status);
     75        return length;
     76    }
     77 
     78    PadPosition position = fUnion.padding.fPosition;
     79    UChar32 paddingCp = fUnion.padding.fCp;
     80    if (position == UNUM_PAD_AFTER_PREFIX) {
     81        length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status);
     82    } else if (position == UNUM_PAD_BEFORE_SUFFIX) {
     83        length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status);
     84    }
     85    length += mod1.apply(string, leftIndex, rightIndex + length, status);
     86    length += mod2.apply(string, leftIndex, rightIndex + length, status);
     87    if (position == UNUM_PAD_BEFORE_PREFIX) {
     88        length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status);
     89    } else if (position == UNUM_PAD_AFTER_SUFFIX) {
     90        length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status);
     91    }
     92 
     93    return length;
     94 }
     95 
     96 #endif /* #if !UCONFIG_NO_FORMATTING */