aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/i18n/number_padding.cpp
blob: 52fff0497bd1b73330b05d17d2a41809cd589c60 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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 */