@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.
- package/LICENSE +21 -21
- package/README.OpenSource +10 -10
- package/README.md +15 -134
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/harmony/text_input_mask/BuildProfile.ets +16 -16
- package/harmony/text_input_mask/Index.ets +7 -7
- package/harmony/text_input_mask/build-profile.json5 +31 -31
- package/harmony/text_input_mask/hvigorfile.ts +6 -6
- package/harmony/text_input_mask/obfuscation-rules.txt +22 -22
- package/harmony/text_input_mask/oh-package.json5 +11 -11
- package/harmony/text_input_mask/src/main/cpp/CMakeLists.txt +9 -9
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +421 -415
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.h +93 -93
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h +31 -31
- package/harmony/text_input_mask/src/main/cpp/common/Compiler.h +174 -174
- package/harmony/text_input_mask/src/main/cpp/common/FormatError.h +22 -22
- package/harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h +230 -230
- package/harmony/text_input_mask/src/main/cpp/common/Mask.h +380 -377
- package/harmony/text_input_mask/src/main/cpp/common/RTLMask.h +78 -78
- package/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +57 -57
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretString.h +75 -75
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h +58 -58
- package/harmony/text_input_mask/src/main/cpp/common/model/Next.h +24 -24
- package/harmony/text_input_mask/src/main/cpp/common/model/Notation.h +29 -24
- package/harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h +22 -22
- package/harmony/text_input_mask/src/main/cpp/common/model/State.h +302 -302
- package/harmony/text_input_mask/src/main/cpp/common/model/common.h +94 -94
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskPackage.ts +28 -28
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts +32 -32
- package/harmony/text_input_mask/src/main/module.json5 +11 -11
- package/harmony/text_input_mask/src/main/resources/base/element/string.json +8 -8
- package/harmony/text_input_mask/src/main/resources/en_US/element/string.json +8 -8
- package/harmony/text_input_mask/src/main/resources/zh_CN/element/string.json +8 -8
- package/harmony/text_input_mask/ts.ts +8 -8
- package/harmony/text_input_mask.har +0 -0
- package/index.tsx +258 -258
- package/package.json +48 -50
- package/src/RNNativeTextInputMask.ts +142 -142
- package/src/index.harmony.ts +147 -147
- 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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
public:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* @
|
|
78
|
-
*
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
int
|
|
103
|
-
|
|
104
|
-
std::
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|