• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "styled_number_format.h"
17 
18 #include <unordered_map>
19 #include "unicode/formattedvalue.h"
20 #include "i18n_hilog.h"
21 
22 namespace OHOS {
23 namespace Global {
24 namespace I18n {
StyledNumberFormat(bool isNumberFormat,std::shared_ptr<NumberFormat> numberFormat,std::shared_ptr<SimpleNumberFormat> simpleNumberFormat)25 StyledNumberFormat::StyledNumberFormat(bool isNumberFormat, std::shared_ptr<NumberFormat> numberFormat,
26     std::shared_ptr<SimpleNumberFormat> simpleNumberFormat)
27     : isNumberFormat(isNumberFormat), numberFormat(numberFormat), simpleNumberFormat(simpleNumberFormat)
28 {
29 }
30 
Format(double number)31 std::string StyledNumberFormat::Format(double number)
32 {
33     if (isNumberFormat && numberFormat) {
34         return numberFormat->Format(number);
35     }
36     if (!isNumberFormat && simpleNumberFormat) {
37         return simpleNumberFormat->Format(number);
38     }
39     return "";
40 }
41 
ParseToParts(double number)42 std::vector<StyledNumberFormat::NumberPart> StyledNumberFormat::ParseToParts(double number)
43 {
44     if (isNumberFormat && numberFormat) {
45         if (numberFormat->IsRelativeTimeFormat(number)) {
46             icu::FormattedRelativeDateTime formattedValue = numberFormat->FormatToFormattedRelativeDateTime(number);
47             return ParseToParts(formattedValue);
48         } else {
49             icu::number::FormattedNumber formattedValue = numberFormat->FormatToFormattedNumber(number);
50             return ParseToParts(formattedValue);
51         }
52     }
53     if (!isNumberFormat && simpleNumberFormat) {
54         icu::number::FormattedNumber formattedValue = simpleNumberFormat->FormatToFormattedNumber(number);
55         return ParseToParts(formattedValue);
56     }
57     return {};
58 }
59 
ParseToParts(icu::number::FormattedNumber & formattedValue)60 std::vector<StyledNumberFormat::NumberPart> StyledNumberFormat::ParseToParts(
61     icu::number::FormattedNumber &formattedValue)
62 {
63     std::vector<NumberPart> result;
64     UErrorCode status = U_ZERO_ERROR;
65     icu::ConstrainedFieldPosition constrainedPos;
66     constrainedPos.constrainCategory(UFIELD_CATEGORY_NUMBER);
67     while (formattedValue.nextPosition(constrainedPos, status)) {
68         if (U_FAILURE(status)) {
69             HILOG_ERROR_I18N("StyledNumberFormat::ParseToParts get nextPosition faild");
70             break;
71         }
72         size_t startIndex = (size_t)constrainedPos.getStart();
73         if (constrainedPos.getCategory() != UFIELD_CATEGORY_NUMBER) {
74             continue;
75         }
76         switch (constrainedPos.getField()) {
77             case UNUM_PERCENT_FIELD:
78             case UNUM_PERMILL_FIELD:
79             case UNUM_MEASURE_UNIT_FIELD:
80             case UNUM_CURRENCY_FIELD: {
81                 result.push_back({"unit", startIndex,
82                     static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
83                 break;
84             }
85             case UNUM_DECIMAL_SEPARATOR_FIELD: {
86                 result.push_back({"decimal", startIndex,
87                     static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
88                 break;
89             }
90             case UNUM_EXPONENT_SYMBOL_FIELD:
91             case UNUM_EXPONENT_SIGN_FIELD:
92             case UNUM_EXPONENT_FIELD:
93             case UNUM_SIGN_FIELD:
94             case UNUM_COMPACT_FIELD:
95             case UNUM_INTEGER_FIELD: {
96                 result.push_back({"integer", startIndex,
97                     static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
98                 break;
99             }
100             case UNUM_FRACTION_FIELD: {
101                 result.push_back({"fraction", startIndex,
102                     static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
103                 break;
104             }
105             default:
106                 break;
107         }
108     }
109     return result;
110 }
111 
ParseToParts(icu::FormattedRelativeDateTime & formattedValue)112 std::vector<StyledNumberFormat::NumberPart> StyledNumberFormat::ParseToParts(
113     icu::FormattedRelativeDateTime &formattedValue)
114 {
115     std::vector<NumberPart> result;
116     UErrorCode status = U_ZERO_ERROR;
117     icu::UnicodeString formatResult = formattedValue.toString(status);
118     if (U_FAILURE(status)) {
119         HILOG_ERROR_I18N("StyledNumberFormat::ParseToParts toString faild");
120         return result;
121     }
122     std::string numberStr;
123     formatResult.toUTF8String(numberStr);
124     icu::ConstrainedFieldPosition constrainedPos;
125     constrainedPos.constrainCategory(UFIELD_CATEGORY_NUMBER);
126     size_t prevIndex = 0;
127     size_t length = numberStr.length();
128     while (formattedValue.nextPosition(constrainedPos, status)) {
129         if (U_FAILURE(status)) {
130             HILOG_ERROR_I18N("StyledNumberFormat::ParseToParts get nextPosition faild");
131             break;
132         }
133         size_t startIndex = (size_t)constrainedPos.getStart();
134         if (constrainedPos.getCategory() != UFIELD_CATEGORY_NUMBER ||
135             constrainedPos.getField() == UNUM_GROUPING_SEPARATOR_FIELD) {
136             continue;
137         }
138         if (constrainedPos.getField() == UNUM_DECIMAL_SEPARATOR_FIELD) {
139             result.push_back({"decimal", startIndex, static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
140         }
141         if (constrainedPos.getField() == UNUM_INTEGER_FIELD) {
142             result.push_back({"integer", startIndex, static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
143         }
144         if (constrainedPos.getField() == UNUM_FRACTION_FIELD) {
145             result.push_back({"fraction", startIndex, static_cast<size_t>(constrainedPos.getLimit() - startIndex)});
146         }
147         if (startIndex > prevIndex) {
148             result.push_back({"unit", prevIndex, startIndex - prevIndex});
149         }
150         prevIndex = (size_t)constrainedPos.getLimit();
151     }
152     if (prevIndex < length) {
153         result.push_back({"unit", prevIndex, length - prevIndex});
154     }
155     return result;
156 }
157 } // namespace I18n
158 } // namespace Global
159 } // namespace OHOS