@react-native-ohos/react-native-text-input-mask 3.1.6-rc.1 → 3.1.6-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +21 -21
  2. package/README.OpenSource +10 -10
  3. package/README.md +15 -134
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/harmony/text_input_mask/BuildProfile.ets +16 -16
  6. package/harmony/text_input_mask/Index.ets +7 -7
  7. package/harmony/text_input_mask/build-profile.json5 +31 -31
  8. package/harmony/text_input_mask/hvigorfile.ts +6 -6
  9. package/harmony/text_input_mask/obfuscation-rules.txt +22 -22
  10. package/harmony/text_input_mask/oh-package.json5 +11 -11
  11. package/harmony/text_input_mask/src/main/cpp/CMakeLists.txt +9 -9
  12. package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +421 -415
  13. package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.h +93 -93
  14. package/harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h +31 -31
  15. package/harmony/text_input_mask/src/main/cpp/common/Compiler.h +174 -174
  16. package/harmony/text_input_mask/src/main/cpp/common/FormatError.h +22 -22
  17. package/harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h +230 -230
  18. package/harmony/text_input_mask/src/main/cpp/common/Mask.h +380 -377
  19. package/harmony/text_input_mask/src/main/cpp/common/RTLMask.h +78 -78
  20. package/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +57 -57
  21. package/harmony/text_input_mask/src/main/cpp/common/model/CaretString.h +75 -75
  22. package/harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h +58 -58
  23. package/harmony/text_input_mask/src/main/cpp/common/model/Next.h +24 -24
  24. package/harmony/text_input_mask/src/main/cpp/common/model/Notation.h +29 -24
  25. package/harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h +22 -22
  26. package/harmony/text_input_mask/src/main/cpp/common/model/State.h +302 -302
  27. package/harmony/text_input_mask/src/main/cpp/common/model/common.h +94 -94
  28. package/harmony/text_input_mask/src/main/ets/RNTextInputMaskPackage.ts +28 -28
  29. package/harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts +32 -32
  30. package/harmony/text_input_mask/src/main/module.json5 +11 -11
  31. package/harmony/text_input_mask/src/main/resources/base/element/string.json +8 -8
  32. package/harmony/text_input_mask/src/main/resources/en_US/element/string.json +8 -8
  33. package/harmony/text_input_mask/src/main/resources/zh_CN/element/string.json +8 -8
  34. package/harmony/text_input_mask/ts.ts +8 -8
  35. package/harmony/text_input_mask.har +0 -0
  36. package/index.tsx +258 -258
  37. package/package.json +48 -50
  38. package/src/RNNativeTextInputMask.ts +142 -142
  39. package/src/index.harmony.ts +147 -147
  40. package/src/index.ts +36 -36
@@ -1,378 +1,381 @@
1
- /*
2
- * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3
- * Use of this source code is governed by a MIT license that can be
4
- * found in the LICENSE file.
5
- */
6
-
7
- #pragma once
8
- #include <string>
9
- #include <vector>
10
- #include <map>
11
- #include <memory>
12
- #include "model/CaretStringIterator.h"
13
- #include "model/common.h" // 假设这些头文件定义了相关类
14
- #include "Compiler.h"
15
- #include "model/State.h"
16
-
17
- namespace TinpMask {
18
-
19
- class Mask {
20
- protected:
21
- std::vector<Notation> customNotations;
22
-
23
- private:
24
- std::shared_ptr<State> initialState;
25
-
26
- private:
27
- std::string format;
28
-
29
- public:
30
- // 主构造函数
31
- Mask(const std::string &format, const std::vector<Notation> &customNotations) : customNotations(customNotations) {
32
- this->format = format;
33
- this->customNotations = customNotations;
34
- this->initialState = Compiler(customNotations).compile(format);
35
- }
36
-
37
- // 便利构造函数
38
- Mask(const std::string &format) : Mask(format, {}) { // 调用主构造函数,传入空的 customNotations
39
- std::vector<Notation> emptyVector;
40
- this->format = format;
41
- this->customNotations = emptyVector;
42
- this->initialState = Compiler(this->customNotations).compile(this->format);
43
- }
44
-
45
-
46
- class MaskFactory {
47
- public:
48
- static std::unordered_map<std::string, std::shared_ptr<Mask>> maskCache;
49
-
50
- public:
51
- /**
52
- * Factory constructor.
53
- *
54
- * Operates over own ``Mask`` cache where initialized ``Mask`` objects are stored under
55
- * corresponding format key: `[format : mask]`
56
- *
57
- * @returns Previously cached ``Mask`` object for requested format string. If such it
58
- * doesn't exist in cache, the object is constructed, cached and returned.
59
- */
60
- static std::shared_ptr<Mask> getOrCreate(const std::string &format,
61
- const std::vector<Notation> &customNotations) {
62
- auto cachedMask = maskCache.find(format);
63
- if (cachedMask == maskCache.end()) {
64
- auto newMask = std::make_shared<Mask>(format, customNotations);
65
- maskCache[format] = newMask;
66
- return newMask;
67
- }
68
- return cachedMask->second;
69
- }
70
-
71
- /**
72
- * Check your mask format is valid.
73
- *
74
- * @param format mask format.
75
- * @param customNotations a list of custom rules to compile square bracket `[]` groups of format symbols.
76
- *
77
- * @returns `true` if this format coupled with custom notations will compile into a working ``Mask`` object.
78
- * Otherwise `false`.
79
- */
80
- static bool isValid(const std::string &format, const std::vector<Notation> &customNotations) {
81
- try {
82
- Mask(format, customNotations);
83
- return true;
84
- } catch (const FormatError &) {
85
- return false;
86
- }
87
- }
88
- };
89
- /**
90
- * Apply mask to the user input string.
91
- *
92
- * @param text user input string with current cursor position
93
- *
94
- * @returns Formatted text with extracted value an adjusted cursor position.
95
- */
96
- virtual Result apply(const CaretString &text) {
97
- auto iterator = makeIterator(text); // Assume this function is defined
98
-
99
- int affinity = 0;
100
- std::string extractedValue;
101
- std::string modifiedString;
102
- int modifiedCaretPosition = text.caretPosition;
103
-
104
- std::shared_ptr<State> state = initialState;
105
- AutocompletionStack autocompletionStack;
106
-
107
- bool insertionAffectsCaret = iterator->insertionAffectsCaret();
108
- bool deletionAffectsCaret = iterator->deletionAffectsCaret();
109
- char character = iterator->next();
110
- while (character != '\0') {
111
- auto next = state->accept(character);
112
-
113
- if (next != nullptr) {
114
- if (deletionAffectsCaret) {
115
- auto opt = state->autocomplete();
116
- if (opt != nullptr) {
117
- autocompletionStack.push(*opt);
118
- }
119
- }
120
- state = next->state;
121
- if (next->insert == '\0') {
122
- modifiedString += "";
123
- } else {
124
- modifiedString += next->insert;
125
- }
126
- if (next->value == '\0') {
127
- extractedValue += "";
128
- } else {
129
- extractedValue += next->value;
130
- }
131
- if (next->pass) {
132
- insertionAffectsCaret = iterator->insertionAffectsCaret();
133
- deletionAffectsCaret = iterator->deletionAffectsCaret();
134
- character = iterator->next();
135
- affinity += 1;
136
- } else {
137
- if (insertionAffectsCaret && next->insert != '\0') {
138
- modifiedCaretPosition += 1;
139
- }
140
- affinity -= 1;
141
- }
142
- } else {
143
- if (deletionAffectsCaret) {
144
- modifiedCaretPosition -= 1;
145
- }
146
- insertionAffectsCaret = iterator->insertionAffectsCaret();
147
- deletionAffectsCaret = iterator->deletionAffectsCaret();
148
- character = iterator->next();
149
- affinity -= 1;
150
- }
151
- }
152
-
153
- while (text.caretGravity->autocomplete() && insertionAffectsCaret) {
154
- auto next = state->autocomplete();
155
- if (next == nullptr)
156
- break;
157
-
158
- state = next->state;
159
- if (next->insert == '\0') {
160
- modifiedString += "";
161
- } else {
162
- modifiedString += next->insert;
163
- }
164
- if (next->value == '\0') {
165
- extractedValue += "";
166
- } else {
167
- extractedValue += next->value;
168
- }
169
- if (next->insert == '\0') {
170
- modifiedCaretPosition += 1;
171
- }
172
- }
173
- std::shared_ptr<State> tailState = state;
174
- std::string tail;
175
- while (text.caretGravity->autoskip() && !autocompletionStack.isEmpty()) {
176
- auto skip = autocompletionStack.pop();
177
- if (modifiedString.length() == modifiedCaretPosition) {
178
- if (!skip->insert == '\0' && skip->insert == modifiedString.back()) {
179
- modifiedString.pop_back();
180
- modifiedCaretPosition -= 1;
181
- }
182
- if (skip.has_value() && skip.value().value == modifiedString.back()) {
183
- extractedValue.pop_back();
184
- }
185
- } else {
186
- if (!skip->insert == '\0') {
187
- modifiedCaretPosition -= 1;
188
- }
189
- }
190
- tailState = skip->state;
191
- tail += skip->insert;
192
- }
193
-
194
- std::string tailPlaceholder = appendPlaceholder(tailState.get(), tail); // Assume this function is defined
195
-
196
- return Result(CaretString(modifiedString, modifiedCaretPosition, text.caretGravity), extractedValue, affinity,
197
- noMandatoryCharactersLeftAfterState(state.get()), // Assume this function is defined
198
- tailPlaceholder);
199
- }
200
-
201
-
202
- public:
203
- std::shared_ptr<CaretStringIterator> makeIterator(const CaretString &text) const {
204
- return std::make_shared<CaretStringIterator>(text);
205
- }
206
-
207
- /**
208
- * Generate placeholder.
209
- *
210
- * @return Placeholder string.
211
- */
212
- public:
213
- std::string placeholder() { return appendPlaceholder(initialState.get(), ""); }
214
- /**
215
- * Minimal length of the text inside the field to fill all mandatory characters in the mask.
216
- *
217
- * @return Minimal satisfying count of characters inside the text field.
218
- */
219
- public:
220
- int acceptableTextLength() {
221
- std::shared_ptr<State> state = std::move(initialState);
222
- ;
223
- int length = 0;
224
-
225
- while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
226
- if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
227
- dynamic_cast<FreeState *>(state.get()) != nullptr ||
228
- dynamic_cast<ValueState *>(state.get()) != nullptr) {
229
- length += 1;
230
- }
231
- state = state->child; // 移动到下一个子状态
232
- }
233
-
234
- return length;
235
- }
236
-
237
-
238
- /**
239
- * Maximal length of the text inside the field.
240
- *
241
- * @return Total available count of mandatory and optional characters inside the text field.
242
- */
243
- public:
244
- int totalTextLength() const {
245
- std::shared_ptr<State> state = initialState;
246
- ;
247
- int length = 0;
248
-
249
- while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
250
- if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
251
- dynamic_cast<FreeState *>(state.get()) != nullptr ||
252
- dynamic_cast<ValueState *>(state.get()) != nullptr ||
253
- dynamic_cast<OptionalValueState *>(state.get()) != nullptr) {
254
- length += 1;
255
- }
256
- state = state->child; // 移动到下一个子状态
257
- }
258
-
259
- return length;
260
- }
261
- /**
262
- * Minimal length of the extracted value with all mandatory characters filled.\
263
- *
264
- * @return Minimal satisfying count of characters in extracted value.
265
- */
266
- public:
267
- int acceptableValueLength() const {
268
- std::shared_ptr<State> state = initialState;
269
- int length = 0;
270
- while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
271
- if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
272
- dynamic_cast<ValueState *>(state.get()) != nullptr) {
273
- length += 1;
274
- }
275
- state = state->child; // 移动到下一个子状态
276
- }
277
-
278
- return length;
279
- }
280
- /**
281
- * Maximal length of the extracted value.
282
- *
283
- * @return Total available count of mandatory and optional characters for extracted value.
284
- */
285
- public:
286
- int totalValueLength() const {
287
- std::shared_ptr<State> state = initialState;
288
- int length = 0;
289
- while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
290
- if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
291
- dynamic_cast<ValueState *>(state.get()) != nullptr ||
292
- dynamic_cast<OptionalValueState *>(state.get()) != nullptr) {
293
- length += 1;
294
- }
295
- state = state->child; // 移动到下一个子状态
296
- }
297
- return length;
298
- }
299
-
300
- private:
301
- std::string appendPlaceholder(State *state, const std::string &placeholder) const {
302
- if (state == nullptr) {
303
- return placeholder;
304
- }
305
-
306
- if (dynamic_cast<EOLState *>(state)) {
307
- return placeholder;
308
- }
309
-
310
- if (auto fixedState = dynamic_cast<FixedState *>(state)) {
311
- return appendPlaceholder(fixedState->child.get(), placeholder + fixedState->ownCharacter);
312
- }
313
-
314
- if (auto freeState = dynamic_cast<FreeState *>(state)) {
315
- return appendPlaceholder(freeState->child.get(), placeholder + freeState->ownCharacter);
316
- }
317
-
318
- if (auto optionalValueState = dynamic_cast<OptionalValueState *>(state)) {
319
- if (!state) {
320
- return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder
321
- }
322
- // 使用 if-else 替代 switch
323
- if (optionalValueState->type->getName() == StateTypeName::Numeric) {
324
- return appendPlaceholder(state->child.get(), placeholder + "0");
325
- } else if (optionalValueState->type->getName() == StateTypeName::Literal) {
326
- return appendPlaceholder(state->child.get(), placeholder + "a");
327
- } else if (optionalValueState->type->getName() == StateTypeName::AlphaNumeric) {
328
- return appendPlaceholder(state->child.get(), placeholder + "-");
329
- } else if (optionalValueState->type->getName() == StateTypeName::Custom) {
330
- auto customValueState = dynamic_cast<OptionalValueState *>(state);
331
- auto customStateType = dynamic_cast<OptionalValueState::Custom *>(customValueState->type.get());
332
- return appendPlaceholder(state->child.get(), placeholder + customStateType->character);
333
- } else {
334
- return placeholder; // 未知类型,返回原始 placeholder
335
- }
336
- }
337
-
338
- if (auto valueState = dynamic_cast<ValueState *>(state)) {
339
- if (!state) {
340
- return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder
341
- }
342
- // 使用 if-else 替代 switch
343
- if (valueState->type->getName() == StateTypeName::Numeric) {
344
- return appendPlaceholder(state->child.get(), placeholder + "0");
345
- } else if (valueState->type->getName() == StateTypeName::Literal) {
346
- return appendPlaceholder(state->child.get(), placeholder + "a");
347
- } else if (valueState->type->getName() == StateTypeName::AlphaNumeric) {
348
- return appendPlaceholder(state->child.get(), placeholder + "-");
349
- } else if (valueState->type->getName() == StateTypeName::Custom) {
350
- auto customValueState = dynamic_cast<ValueState *>(state);
351
- if (customValueState->type.get()) {
352
- auto customStateType = dynamic_cast<ValueState::Custom *>(customValueState->type.get());
353
- return appendPlaceholder(state->child.get(), placeholder + customStateType->character);
354
- }else {
355
- throw FormatError("appendPlaceholder customValueState type is null"); // 未找到匹配项,抛出异常
356
- }
357
-
358
- } else {
359
- return placeholder; // 未知类型,返回原始 placeholder
360
- }
361
- }
362
-
363
- return placeholder;
364
- }
365
-
366
- bool noMandatoryCharactersLeftAfterState(State *state) const {
367
- if (dynamic_cast<EOLState *>(state)) {
368
- return true;
369
- } else if (auto valueState = dynamic_cast<ValueState *>(state)) {
370
- return valueState->isElliptical();
371
- } else if (dynamic_cast<FixedState *>(state)) {
372
- return false;
373
- } else {
374
- return noMandatoryCharactersLeftAfterState(state->nextState().get());
375
- }
376
- }
377
- };
1
+ /*
2
+ * Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3
+ * Use of this source code is governed by a MIT license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ #pragma once
8
+ #include <string>
9
+ #include <vector>
10
+ #include <map>
11
+ #include <memory>
12
+ #include "model/CaretStringIterator.h"
13
+ #include "model/common.h" // 假设这些头文件定义了相关类
14
+ #include "Compiler.h"
15
+ #include "model/State.h"
16
+
17
+ namespace TinpMask {
18
+
19
+ class Mask {
20
+ protected:
21
+ std::vector<Notation> customNotations;
22
+
23
+ private:
24
+ std::shared_ptr<State> initialState;
25
+
26
+ private:
27
+ std::string format;
28
+
29
+ public:
30
+ // 主构造函数
31
+ Mask(const std::string &format, const std::vector<Notation> &customNotations) : customNotations(customNotations) {
32
+ this->format = format;
33
+ this->customNotations = customNotations;
34
+ this->initialState = Compiler(customNotations).compile(format);
35
+ }
36
+
37
+ // 便利构造函数
38
+ Mask(const std::string &format) : Mask(format, {}) { // 调用主构造函数,传入空的 customNotations
39
+ std::vector<Notation> emptyVector;
40
+ this->format = format;
41
+ this->customNotations = emptyVector;
42
+ this->initialState = Compiler(this->customNotations).compile(this->format);
43
+ }
44
+
45
+ bool hasSameCustomNotations(const std::vector<Notation>& targetNotations) const {
46
+ return this->customNotations == targetNotations;
47
+ }
48
+
49
+ class MaskFactory {
50
+ public:
51
+ static std::unordered_map<std::string, std::shared_ptr<Mask>> maskCache;
52
+
53
+ public:
54
+ /**
55
+ * Factory constructor.
56
+ *
57
+ * Operates over own ``Mask`` cache where initialized ``Mask`` objects are stored under
58
+ * corresponding format key: `[format : mask]`
59
+ *
60
+ * @returns Previously cached ``Mask`` object for requested format string. If such it
61
+ * doesn't exist in cache, the object is constructed, cached and returned.
62
+ */
63
+ static std::shared_ptr<Mask> getOrCreate(const std::string &format,
64
+ const std::vector<Notation> &customNotations) {
65
+ auto cachedMask = maskCache.find(format);
66
+ if (cachedMask == maskCache.end() || !cachedMask->second->hasSameCustomNotations(customNotations)) {
67
+ auto newMask = std::make_shared<Mask>(format, customNotations);
68
+ maskCache[format] = newMask;
69
+ return newMask;
70
+ }
71
+ return cachedMask->second;
72
+ }
73
+
74
+ /**
75
+ * Check your mask format is valid.
76
+ *
77
+ * @param format mask format.
78
+ * @param customNotations a list of custom rules to compile square bracket `[]` groups of format symbols.
79
+ *
80
+ * @returns `true` if this format coupled with custom notations will compile into a working ``Mask`` object.
81
+ * Otherwise `false`.
82
+ */
83
+ static bool isValid(const std::string &format, const std::vector<Notation> &customNotations) {
84
+ try {
85
+ Mask(format, customNotations);
86
+ return true;
87
+ } catch (const FormatError &) {
88
+ return false;
89
+ }
90
+ }
91
+ };
92
+ /**
93
+ * Apply mask to the user input string.
94
+ *
95
+ * @param text user input string with current cursor position
96
+ *
97
+ * @returns Formatted text with extracted value an adjusted cursor position.
98
+ */
99
+ virtual Result apply(const CaretString &text) {
100
+ auto iterator = makeIterator(text); // Assume this function is defined
101
+
102
+ int affinity = 0;
103
+ std::string extractedValue;
104
+ std::string modifiedString;
105
+ int modifiedCaretPosition = text.caretPosition;
106
+
107
+ std::shared_ptr<State> state = initialState;
108
+ AutocompletionStack autocompletionStack;
109
+
110
+ bool insertionAffectsCaret = iterator->insertionAffectsCaret();
111
+ bool deletionAffectsCaret = iterator->deletionAffectsCaret();
112
+ char character = iterator->next();
113
+ while (character != '\0') {
114
+ auto next = state->accept(character);
115
+
116
+ if (next != nullptr) {
117
+ if (deletionAffectsCaret) {
118
+ auto opt = state->autocomplete();
119
+ if (opt != nullptr) {
120
+ autocompletionStack.push(*opt);
121
+ }
122
+ }
123
+ state = next->state;
124
+ if (next->insert == '\0') {
125
+ modifiedString += "";
126
+ } else {
127
+ modifiedString += next->insert;
128
+ }
129
+ if (next->value == '\0') {
130
+ extractedValue += "";
131
+ } else {
132
+ extractedValue += next->value;
133
+ }
134
+ if (next->pass) {
135
+ insertionAffectsCaret = iterator->insertionAffectsCaret();
136
+ deletionAffectsCaret = iterator->deletionAffectsCaret();
137
+ character = iterator->next();
138
+ affinity += 1;
139
+ } else {
140
+ if (insertionAffectsCaret && next->insert != '\0') {
141
+ modifiedCaretPosition += 1;
142
+ }
143
+ affinity -= 1;
144
+ }
145
+ } else {
146
+ if (deletionAffectsCaret) {
147
+ modifiedCaretPosition -= 1;
148
+ }
149
+ insertionAffectsCaret = iterator->insertionAffectsCaret();
150
+ deletionAffectsCaret = iterator->deletionAffectsCaret();
151
+ character = iterator->next();
152
+ affinity -= 1;
153
+ }
154
+ }
155
+
156
+ while (text.caretGravity->autocomplete() && insertionAffectsCaret) {
157
+ auto next = state->autocomplete();
158
+ if (next == nullptr)
159
+ break;
160
+
161
+ state = next->state;
162
+ if (next->insert == '\0') {
163
+ modifiedString += "";
164
+ } else {
165
+ modifiedString += next->insert;
166
+ }
167
+ if (next->value == '\0') {
168
+ extractedValue += "";
169
+ } else {
170
+ extractedValue += next->value;
171
+ }
172
+ if (next->insert == '\0') {
173
+ modifiedCaretPosition += 1;
174
+ }
175
+ }
176
+ std::shared_ptr<State> tailState = state;
177
+ std::string tail;
178
+ while (text.caretGravity->autoskip() && !autocompletionStack.isEmpty()) {
179
+ auto skip = autocompletionStack.pop();
180
+ if (modifiedString.length() == modifiedCaretPosition) {
181
+ if (!skip->insert == '\0' && skip->insert == modifiedString.back()) {
182
+ modifiedString.pop_back();
183
+ modifiedCaretPosition -= 1;
184
+ }
185
+ if (skip.has_value() && skip.value().value == modifiedString.back()) {
186
+ extractedValue.pop_back();
187
+ }
188
+ } else {
189
+ if (!skip->insert == '\0') {
190
+ modifiedCaretPosition -= 1;
191
+ }
192
+ }
193
+ tailState = skip->state;
194
+ tail += skip->insert;
195
+ }
196
+
197
+ std::string tailPlaceholder = appendPlaceholder(tailState.get(), tail); // Assume this function is defined
198
+
199
+ return Result(CaretString(modifiedString, modifiedCaretPosition, text.caretGravity), extractedValue, affinity,
200
+ noMandatoryCharactersLeftAfterState(state.get()), // Assume this function is defined
201
+ tailPlaceholder);
202
+ }
203
+
204
+
205
+ public:
206
+ std::shared_ptr<CaretStringIterator> makeIterator(const CaretString &text) const {
207
+ return std::make_shared<CaretStringIterator>(text);
208
+ }
209
+
210
+ /**
211
+ * Generate placeholder.
212
+ *
213
+ * @return Placeholder string.
214
+ */
215
+ public:
216
+ std::string placeholder() { return appendPlaceholder(initialState.get(), ""); }
217
+ /**
218
+ * Minimal length of the text inside the field to fill all mandatory characters in the mask.
219
+ *
220
+ * @return Minimal satisfying count of characters inside the text field.
221
+ */
222
+ public:
223
+ int acceptableTextLength() {
224
+ std::shared_ptr<State> state = std::move(initialState);
225
+ ;
226
+ int length = 0;
227
+
228
+ while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
229
+ if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
230
+ dynamic_cast<FreeState *>(state.get()) != nullptr ||
231
+ dynamic_cast<ValueState *>(state.get()) != nullptr) {
232
+ length += 1;
233
+ }
234
+ state = state->child; // 移动到下一个子状态
235
+ }
236
+
237
+ return length;
238
+ }
239
+
240
+
241
+ /**
242
+ * Maximal length of the text inside the field.
243
+ *
244
+ * @return Total available count of mandatory and optional characters inside the text field.
245
+ */
246
+ public:
247
+ int totalTextLength() const {
248
+ std::shared_ptr<State> state = initialState;
249
+ ;
250
+ int length = 0;
251
+
252
+ while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
253
+ if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
254
+ dynamic_cast<FreeState *>(state.get()) != nullptr ||
255
+ dynamic_cast<ValueState *>(state.get()) != nullptr ||
256
+ dynamic_cast<OptionalValueState *>(state.get()) != nullptr) {
257
+ length += 1;
258
+ }
259
+ state = state->child; // 移动到下一个子状态
260
+ }
261
+
262
+ return length;
263
+ }
264
+ /**
265
+ * Minimal length of the extracted value with all mandatory characters filled.\
266
+ *
267
+ * @return Minimal satisfying count of characters in extracted value.
268
+ */
269
+ public:
270
+ int acceptableValueLength() const {
271
+ std::shared_ptr<State> state = initialState;
272
+ int length = 0;
273
+ while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
274
+ if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
275
+ dynamic_cast<ValueState *>(state.get()) != nullptr) {
276
+ length += 1;
277
+ }
278
+ state = state->child; // 移动到下一个子状态
279
+ }
280
+
281
+ return length;
282
+ }
283
+ /**
284
+ * Maximal length of the extracted value.
285
+ *
286
+ * @return Total available count of mandatory and optional characters for extracted value.
287
+ */
288
+ public:
289
+ int totalValueLength() const {
290
+ std::shared_ptr<State> state = initialState;
291
+ int length = 0;
292
+ while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
293
+ if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
294
+ dynamic_cast<ValueState *>(state.get()) != nullptr ||
295
+ dynamic_cast<OptionalValueState *>(state.get()) != nullptr) {
296
+ length += 1;
297
+ }
298
+ state = state->child; // 移动到下一个子状态
299
+ }
300
+ return length;
301
+ }
302
+
303
+ private:
304
+ std::string appendPlaceholder(State *state, const std::string &placeholder) const {
305
+ if (state == nullptr) {
306
+ return placeholder;
307
+ }
308
+
309
+ if (dynamic_cast<EOLState *>(state)) {
310
+ return placeholder;
311
+ }
312
+
313
+ if (auto fixedState = dynamic_cast<FixedState *>(state)) {
314
+ return appendPlaceholder(fixedState->child.get(), placeholder + fixedState->ownCharacter);
315
+ }
316
+
317
+ if (auto freeState = dynamic_cast<FreeState *>(state)) {
318
+ return appendPlaceholder(freeState->child.get(), placeholder + freeState->ownCharacter);
319
+ }
320
+
321
+ if (auto optionalValueState = dynamic_cast<OptionalValueState *>(state)) {
322
+ if (!state) {
323
+ return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder
324
+ }
325
+ // 使用 if-else 替代 switch
326
+ if (optionalValueState->type->getName() == StateTypeName::Numeric) {
327
+ return appendPlaceholder(state->child.get(), placeholder + "0");
328
+ } else if (optionalValueState->type->getName() == StateTypeName::Literal) {
329
+ return appendPlaceholder(state->child.get(), placeholder + "a");
330
+ } else if (optionalValueState->type->getName() == StateTypeName::AlphaNumeric) {
331
+ return appendPlaceholder(state->child.get(), placeholder + "-");
332
+ } else if (optionalValueState->type->getName() == StateTypeName::Custom) {
333
+ auto customValueState = dynamic_cast<OptionalValueState *>(state);
334
+ auto customStateType = dynamic_cast<OptionalValueState::Custom *>(customValueState->type.get());
335
+ return appendPlaceholder(state->child.get(), placeholder + customStateType->character);
336
+ } else {
337
+ return placeholder; // 未知类型,返回原始 placeholder
338
+ }
339
+ }
340
+
341
+ if (auto valueState = dynamic_cast<ValueState *>(state)) {
342
+ if (!state) {
343
+ return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder
344
+ }
345
+ // 使用 if-else 替代 switch
346
+ if (valueState->type->getName() == StateTypeName::Numeric) {
347
+ return appendPlaceholder(state->child.get(), placeholder + "0");
348
+ } else if (valueState->type->getName() == StateTypeName::Literal) {
349
+ return appendPlaceholder(state->child.get(), placeholder + "a");
350
+ } else if (valueState->type->getName() == StateTypeName::AlphaNumeric) {
351
+ return appendPlaceholder(state->child.get(), placeholder + "-");
352
+ } else if (valueState->type->getName() == StateTypeName::Custom) {
353
+ auto customValueState = dynamic_cast<ValueState *>(state);
354
+ if (customValueState->type.get()) {
355
+ auto customStateType = dynamic_cast<ValueState::Custom *>(customValueState->type.get());
356
+ return appendPlaceholder(state->child.get(), placeholder + customStateType->character);
357
+ }else {
358
+ throw FormatError("appendPlaceholder customValueState type is null"); // 未找到匹配项,抛出异常
359
+ }
360
+
361
+ } else {
362
+ return placeholder; // 未知类型,返回原始 placeholder
363
+ }
364
+ }
365
+
366
+ return placeholder;
367
+ }
368
+
369
+ bool noMandatoryCharactersLeftAfterState(State *state) const {
370
+ if (dynamic_cast<EOLState *>(state)) {
371
+ return true;
372
+ } else if (auto valueState = dynamic_cast<ValueState *>(state)) {
373
+ return valueState->isElliptical();
374
+ } else if (dynamic_cast<FixedState *>(state)) {
375
+ return false;
376
+ } else {
377
+ return noMandatoryCharactersLeftAfterState(state->nextState().get());
378
+ }
379
+ }
380
+ };
378
381
  } // namespace TinpMask