]>
Commit | Line | Data |
---|---|---|
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 | #ifndef __NUMBER_STRINGBUILDER_H__ | |
8 | #define __NUMBER_STRINGBUILDER_H__ | |
9 | ||
10 | ||
11 | #include <cstdint> | |
12 | #include "unicode/numfmt.h" | |
13 | #include "unicode/ustring.h" | |
14 | #include "cstring.h" | |
15 | #include "uassert.h" | |
16 | #include "number_types.h" | |
17 | #include "fphdlimp.h" | |
18 | ||
19 | U_NAMESPACE_BEGIN namespace number { | |
20 | namespace impl { | |
21 | ||
22 | class U_I18N_API NumberStringBuilder : public UMemory { | |
23 | private: | |
24 | static const int32_t DEFAULT_CAPACITY = 40; | |
25 | ||
26 | template<typename T> | |
27 | union ValueOrHeapArray { | |
28 | T value[DEFAULT_CAPACITY]; | |
29 | struct { | |
30 | T *ptr; | |
31 | int32_t capacity; | |
32 | } heap; | |
33 | }; | |
34 | ||
35 | public: | |
36 | NumberStringBuilder(); | |
37 | ||
38 | ~NumberStringBuilder(); | |
39 | ||
40 | NumberStringBuilder(const NumberStringBuilder &other); | |
41 | ||
42 | NumberStringBuilder &operator=(const NumberStringBuilder &other); | |
43 | ||
44 | int32_t length() const; | |
45 | ||
46 | int32_t codePointCount() const; | |
47 | ||
48 | inline char16_t charAt(int32_t index) const { | |
49 | U_ASSERT(index >= 0); | |
50 | U_ASSERT(index < fLength); | |
51 | return getCharPtr()[fZero + index]; | |
52 | } | |
53 | ||
54 | inline Field fieldAt(int32_t index) const { | |
55 | U_ASSERT(index >= 0); | |
56 | U_ASSERT(index < fLength); | |
57 | return getFieldPtr()[fZero + index]; | |
58 | } | |
59 | ||
60 | UChar32 getFirstCodePoint() const; | |
61 | ||
62 | UChar32 getLastCodePoint() const; | |
63 | ||
64 | UChar32 codePointAt(int32_t index) const; | |
65 | ||
66 | UChar32 codePointBefore(int32_t index) const; | |
67 | ||
68 | NumberStringBuilder &clear(); | |
69 | ||
70 | int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status); | |
71 | ||
72 | int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status); | |
73 | ||
74 | int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status); | |
75 | ||
76 | int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status); | |
77 | ||
78 | int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field, | |
79 | UErrorCode &status); | |
80 | ||
81 | int32_t splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr, | |
82 | int32_t startOther, int32_t endOther, Field field, UErrorCode& status); | |
83 | ||
84 | int32_t append(const NumberStringBuilder &other, UErrorCode &status); | |
85 | ||
86 | int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status); | |
87 | ||
88 | void writeTerminator(UErrorCode& status); | |
89 | ||
90 | /** | |
91 | * Gets a "safe" UnicodeString that can be used even after the NumberStringBuilder is destructed. | |
92 | * */ | |
93 | UnicodeString toUnicodeString() const; | |
94 | ||
95 | /** | |
96 | * Gets an "unsafe" UnicodeString that is valid only as long as the NumberStringBuilder is alive and | |
97 | * unchanged. Slightly faster than toUnicodeString(). | |
98 | */ | |
99 | const UnicodeString toTempUnicodeString() const; | |
100 | ||
101 | UnicodeString toDebugString() const; | |
102 | ||
103 | const char16_t *chars() const; | |
104 | ||
105 | bool contentEquals(const NumberStringBuilder &other) const; | |
106 | ||
107 | bool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const; | |
108 | ||
109 | void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; | |
110 | ||
111 | bool nextPosition(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& status) const; | |
112 | ||
113 | bool containsField(Field field) const; | |
114 | ||
115 | private: | |
116 | bool fUsingHeap = false; | |
117 | ValueOrHeapArray<char16_t> fChars; | |
118 | ValueOrHeapArray<Field> fFields; | |
119 | int32_t fZero = DEFAULT_CAPACITY / 2; | |
120 | int32_t fLength = 0; | |
121 | ||
122 | inline char16_t *getCharPtr() { | |
123 | return fUsingHeap ? fChars.heap.ptr : fChars.value; | |
124 | } | |
125 | ||
126 | inline const char16_t *getCharPtr() const { | |
127 | return fUsingHeap ? fChars.heap.ptr : fChars.value; | |
128 | } | |
129 | ||
130 | inline Field *getFieldPtr() { | |
131 | return fUsingHeap ? fFields.heap.ptr : fFields.value; | |
132 | } | |
133 | ||
134 | inline const Field *getFieldPtr() const { | |
135 | return fUsingHeap ? fFields.heap.ptr : fFields.value; | |
136 | } | |
137 | ||
138 | inline int32_t getCapacity() const { | |
139 | return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY; | |
140 | } | |
141 | ||
142 | int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status); | |
143 | ||
144 | int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status); | |
145 | ||
146 | int32_t remove(int32_t index, int32_t count); | |
147 | ||
148 | static bool isIntOrGroup(Field field); | |
149 | ||
150 | static bool isNumericField(Field field); | |
151 | ||
152 | int32_t trimBack(int32_t limit) const; | |
153 | ||
154 | int32_t trimFront(int32_t start) const; | |
155 | }; | |
156 | ||
157 | } // namespace impl | |
158 | } // namespace number | |
159 | U_NAMESPACE_END | |
160 | ||
161 | ||
162 | #endif //__NUMBER_STRINGBUILDER_H__ | |
163 | ||
164 | #endif /* #if !UCONFIG_NO_FORMATTING */ |