/src/icu/source/i18n/number_padding.cpp
Line  | Count  | Source (jump to first uncovered line)  | 
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  | 0  |                  UErrorCode &status) { | 
22  | 0  |     for (int32_t i = 0; i < requiredPadding; i++) { | 
23  |  |         // TODO: If appending to the end, this will cause actual insertion operations. Improve.  | 
24  | 0  |         string.insertCodePoint(index, paddingCp, kUndefinedField, status);  | 
25  | 0  |     }  | 
26  | 0  |     return U16_LENGTH(paddingCp) * requiredPadding;  | 
27  | 0  | }  | 
28  |  |  | 
29  |  | }  | 
30  |  |  | 
31  | 0  | Padder::Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position) : fWidth(width) { | 
32  |  |     // TODO(13034): Consider making this a string instead of code point.  | 
33  | 0  |     fUnion.padding.fCp = cp;  | 
34  | 0  |     fUnion.padding.fPosition = position;  | 
35  | 0  | }  | 
36  |  |  | 
37  | 0  | Padder::Padder(int32_t width) : fWidth(width) {} | 
38  |  |  | 
39  | 0  | Padder Padder::none() { | 
40  | 0  |     return {-1}; | 
41  | 0  | }  | 
42  |  |  | 
43  | 0  | Padder Padder::codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position) { | 
44  |  |     // TODO: Validate the code point?  | 
45  | 0  |     if (targetWidth >= 0) { | 
46  | 0  |         return {cp, targetWidth, position}; | 
47  | 0  |     } else { | 
48  | 0  |         return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR}; | 
49  | 0  |     }  | 
50  | 0  | }  | 
51  |  |  | 
52  | 0  | Padder Padder::forProperties(const DecimalFormatProperties& properties) { | 
53  | 0  |     UChar32 padCp;  | 
54  | 0  |     if (properties.padString.length() > 0) { | 
55  | 0  |         padCp = properties.padString.char32At(0);  | 
56  | 0  |     } else { | 
57  | 0  |         padCp = kFallbackPaddingString[0];  | 
58  | 0  |     }  | 
59  | 0  |     return {padCp, properties.formatWidth, properties.padPosition.getOrDefault(UNUM_PAD_BEFORE_PREFIX)}; | 
60  | 0  | }  | 
61  |  |  | 
62  |  | int32_t Padder::padAndApply(const Modifier &mod1, const Modifier &mod2,  | 
63  |  |                             FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,  | 
64  | 0  |                             UErrorCode &status) const { | 
65  | 0  |     int32_t modLength = mod1.getCodePointCount() + mod2.getCodePointCount();  | 
66  | 0  |     int32_t requiredPadding = fWidth - modLength - string.codePointCount();  | 
67  | 0  |     U_ASSERT(leftIndex == 0 &&  | 
68  | 0  |              rightIndex == string.length()); // fix the previous line to remove this assertion  | 
69  |  | 
  | 
70  | 0  |     int length = 0;  | 
71  | 0  |     if (requiredPadding <= 0) { | 
72  |  |         // Padding is not required.  | 
73  | 0  |         length += mod1.apply(string, leftIndex, rightIndex, status);  | 
74  | 0  |         length += mod2.apply(string, leftIndex, rightIndex + length, status);  | 
75  | 0  |         return length;  | 
76  | 0  |     }  | 
77  |  |  | 
78  | 0  |     PadPosition position = fUnion.padding.fPosition;  | 
79  | 0  |     UChar32 paddingCp = fUnion.padding.fCp;  | 
80  | 0  |     if (position == UNUM_PAD_AFTER_PREFIX) { | 
81  | 0  |         length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status);  | 
82  | 0  |     } else if (position == UNUM_PAD_BEFORE_SUFFIX) { | 
83  | 0  |         length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status);  | 
84  | 0  |     }  | 
85  | 0  |     length += mod1.apply(string, leftIndex, rightIndex + length, status);  | 
86  | 0  |     length += mod2.apply(string, leftIndex, rightIndex + length, status);  | 
87  | 0  |     if (position == UNUM_PAD_BEFORE_PREFIX) { | 
88  | 0  |         length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status);  | 
89  | 0  |     } else if (position == UNUM_PAD_AFTER_SUFFIX) { | 
90  | 0  |         length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status);  | 
91  | 0  |     }  | 
92  |  | 
  | 
93  | 0  |     return length;  | 
94  | 0  | }  | 
95  |  |  | 
96  |  | #endif /* #if !UCONFIG_NO_FORMATTING */  |