• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2018 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 // Allow implicit conversion from char16_t* to UnicodeString for this file:
9 // Helpful in toString methods and elsewhere.
10 #define UNISTR_FROM_STRING_EXPLICIT
11 
12 #include "number_decnum.h"
13 #include "number_types.h"
14 #include "number_multiplier.h"
15 #include "numparse_validators.h"
16 #include "number_utils.h"
17 #include "decNumber.h"
18 
19 using namespace icu;
20 using namespace icu::number;
21 using namespace icu::number::impl;
22 using namespace icu::numparse::impl;
23 
24 
Scale(int32_t magnitude,DecNum * arbitraryToAdopt)25 Scale::Scale(int32_t magnitude, DecNum* arbitraryToAdopt)
26         : fMagnitude(magnitude), fArbitrary(arbitraryToAdopt), fError(U_ZERO_ERROR) {
27     if (fArbitrary != nullptr) {
28         // Attempt to convert the DecNum to a magnitude multiplier.
29         fArbitrary->normalize();
30         if (fArbitrary->getRawDecNumber()->digits == 1 && fArbitrary->getRawDecNumber()->lsu[0] == 1 &&
31             !fArbitrary->isNegative()) {
32             // Success!
33             fMagnitude += fArbitrary->getRawDecNumber()->exponent;
34             delete fArbitrary;
35             fArbitrary = nullptr;
36         }
37     }
38 }
39 
Scale(const Scale & other)40 Scale::Scale(const Scale& other)
41         : fMagnitude(other.fMagnitude), fArbitrary(nullptr), fError(other.fError) {
42     if (other.fArbitrary != nullptr) {
43         UErrorCode localStatus = U_ZERO_ERROR;
44         fArbitrary = new DecNum(*other.fArbitrary, localStatus);
45     }
46 }
47 
operator =(const Scale & other)48 Scale& Scale::operator=(const Scale& other) {
49     fMagnitude = other.fMagnitude;
50     if (other.fArbitrary != nullptr) {
51         UErrorCode localStatus = U_ZERO_ERROR;
52         fArbitrary = new DecNum(*other.fArbitrary, localStatus);
53     } else {
54         fArbitrary = nullptr;
55     }
56     fError = other.fError;
57     return *this;
58 }
59 
Scale(Scale && src)60 Scale::Scale(Scale&& src) U_NOEXCEPT
61         : fMagnitude(src.fMagnitude), fArbitrary(src.fArbitrary), fError(src.fError) {
62     // Take ownership away from src if necessary
63     src.fArbitrary = nullptr;
64 }
65 
operator =(Scale && src)66 Scale& Scale::operator=(Scale&& src) U_NOEXCEPT {
67     fMagnitude = src.fMagnitude;
68     fArbitrary = src.fArbitrary;
69     fError = src.fError;
70     // Take ownership away from src if necessary
71     src.fArbitrary = nullptr;
72     return *this;
73 }
74 
~Scale()75 Scale::~Scale() {
76     delete fArbitrary;
77 }
78 
79 
none()80 Scale Scale::none() {
81     return {0, nullptr};
82 }
83 
powerOfTen(int32_t power)84 Scale Scale::powerOfTen(int32_t power) {
85     return {power, nullptr};
86 }
87 
byDecimal(StringPiece multiplicand)88 Scale Scale::byDecimal(StringPiece multiplicand) {
89     UErrorCode localError = U_ZERO_ERROR;
90     LocalPointer<DecNum> decnum(new DecNum(), localError);
91     if (U_FAILURE(localError)) {
92         return {localError};
93     }
94     decnum->setTo(multiplicand, localError);
95     if (U_FAILURE(localError)) {
96         return {localError};
97     }
98     return {0, decnum.orphan()};
99 }
100 
byDouble(double multiplicand)101 Scale Scale::byDouble(double multiplicand) {
102     UErrorCode localError = U_ZERO_ERROR;
103     LocalPointer<DecNum> decnum(new DecNum(), localError);
104     if (U_FAILURE(localError)) {
105         return {localError};
106     }
107     decnum->setTo(multiplicand, localError);
108     if (U_FAILURE(localError)) {
109         return {localError};
110     }
111     return {0, decnum.orphan()};
112 }
113 
byDoubleAndPowerOfTen(double multiplicand,int32_t power)114 Scale Scale::byDoubleAndPowerOfTen(double multiplicand, int32_t power) {
115     UErrorCode localError = U_ZERO_ERROR;
116     LocalPointer<DecNum> decnum(new DecNum(), localError);
117     if (U_FAILURE(localError)) {
118         return {localError};
119     }
120     decnum->setTo(multiplicand, localError);
121     if (U_FAILURE(localError)) {
122         return {localError};
123     }
124     return {power, decnum.orphan()};
125 }
126 
applyTo(impl::DecimalQuantity & quantity) const127 void Scale::applyTo(impl::DecimalQuantity& quantity) const {
128     quantity.adjustMagnitude(fMagnitude);
129     if (fArbitrary != nullptr) {
130         UErrorCode localStatus = U_ZERO_ERROR;
131         quantity.multiplyBy(*fArbitrary, localStatus);
132     }
133 }
134 
applyReciprocalTo(impl::DecimalQuantity & quantity) const135 void Scale::applyReciprocalTo(impl::DecimalQuantity& quantity) const {
136     quantity.adjustMagnitude(-fMagnitude);
137     if (fArbitrary != nullptr) {
138         UErrorCode localStatus = U_ZERO_ERROR;
139         quantity.divideBy(*fArbitrary, localStatus);
140     }
141 }
142 
143 
144 void
setAndChain(const Scale & multiplier,const MicroPropsGenerator * parent)145 MultiplierFormatHandler::setAndChain(const Scale& multiplier, const MicroPropsGenerator* parent) {
146     fMultiplier = multiplier;
147     fParent = parent;
148 }
149 
processQuantity(DecimalQuantity & quantity,MicroProps & micros,UErrorCode & status) const150 void MultiplierFormatHandler::processQuantity(DecimalQuantity& quantity, MicroProps& micros,
151                                               UErrorCode& status) const {
152     fParent->processQuantity(quantity, micros, status);
153     fMultiplier.applyTo(quantity);
154 }
155 
156 #endif /* #if !UCONFIG_NO_FORMATTING */
157