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

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.OpenSource +11 -0
  3. package/README.md +134 -0
  4. package/dist/babel.config.d.ts +7 -0
  5. package/dist/babel.config.js +16 -0
  6. package/dist/babel.config.js.map +1 -0
  7. package/dist/index.d.ts +138 -0
  8. package/dist/index.js +92 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/src/RNNativeTextInputMask.d.ts +129 -0
  11. package/dist/src/RNNativeTextInputMask.js +8 -0
  12. package/dist/src/RNNativeTextInputMask.js.map +1 -0
  13. package/dist/src/index.d.ts +8 -0
  14. package/dist/src/index.harmony.d.ts +127 -0
  15. package/dist/src/index.harmony.js +23 -0
  16. package/dist/src/index.harmony.js.map +1 -0
  17. package/dist/src/index.js +27 -0
  18. package/dist/src/index.js.map +1 -0
  19. package/dist/tsconfig.tsbuildinfo +1 -0
  20. package/harmony/text_input_mask/BuildProfile.ets +17 -0
  21. package/harmony/text_input_mask/Index.ets +7 -0
  22. package/harmony/text_input_mask/build-profile.json5 +31 -0
  23. package/harmony/text_input_mask/consumer-rules.txt +0 -0
  24. package/harmony/text_input_mask/hvigorfile.ts +6 -0
  25. package/harmony/text_input_mask/obfuscation-rules.txt +23 -0
  26. package/harmony/text_input_mask/oh-package.json5 +11 -0
  27. package/harmony/text_input_mask/src/main/cpp/CMakeLists.txt +9 -0
  28. package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +415 -0
  29. package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.h +93 -0
  30. package/harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h +32 -0
  31. package/harmony/text_input_mask/src/main/cpp/common/Compiler.h +175 -0
  32. package/harmony/text_input_mask/src/main/cpp/common/FormatError.h +23 -0
  33. package/harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h +231 -0
  34. package/harmony/text_input_mask/src/main/cpp/common/Mask.h +378 -0
  35. package/harmony/text_input_mask/src/main/cpp/common/RTLMask.h +79 -0
  36. package/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +58 -0
  37. package/harmony/text_input_mask/src/main/cpp/common/model/CaretString.h +76 -0
  38. package/harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h +58 -0
  39. package/harmony/text_input_mask/src/main/cpp/common/model/Next.h +25 -0
  40. package/harmony/text_input_mask/src/main/cpp/common/model/Notation.h +25 -0
  41. package/harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h +23 -0
  42. package/harmony/text_input_mask/src/main/cpp/common/model/State.h +302 -0
  43. package/harmony/text_input_mask/src/main/cpp/common/model/common.h +95 -0
  44. package/harmony/text_input_mask/src/main/ets/RNTextInputMaskPackage.ts +29 -0
  45. package/harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts +33 -0
  46. package/harmony/text_input_mask/src/main/module.json5 +11 -0
  47. package/harmony/text_input_mask/src/main/resources/base/element/string.json +8 -0
  48. package/harmony/text_input_mask/src/main/resources/en_US/element/string.json +8 -0
  49. package/harmony/text_input_mask/src/main/resources/zh_CN/element/string.json +8 -0
  50. package/harmony/text_input_mask/ts.ts +8 -0
  51. package/harmony/text_input_mask.har +0 -0
  52. package/index.tsx +258 -0
  53. package/package.json +50 -0
  54. package/src/RNNativeTextInputMask.ts +143 -0
  55. package/src/index.harmony.ts +147 -0
  56. package/src/index.ts +36 -0
@@ -0,0 +1,378 @@
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
+ };
378
+ } // namespace TinpMask
@@ -0,0 +1,79 @@
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 "common/Mask.h"
9
+ #include "common/model/CaretString.h"
10
+ #include "common/model/Notation.h"
11
+ #include "common/model/common.h"
12
+ namespace TinpMask {
13
+ class RTLMask : public Mask {
14
+
15
+ public:
16
+ static std::unordered_map<std::string, std::shared_ptr<RTLMask>> cache ;
17
+ RTLMask(const std::string& format, const std::vector<Notation>& customNotations)
18
+ : Mask(reversedFormat(format), customNotations) {}
19
+
20
+ static std::shared_ptr<RTLMask> getOrCreate(const std::string& format, const std::vector<Notation>& customNotations) {
21
+ std::string reversed = reversedFormat(format);
22
+ auto it = cache.find(reversed);
23
+ if (it != cache.end()) {
24
+ return it->second; // Return cached instance
25
+ }
26
+
27
+ // Create new instance and cache it
28
+ auto newMask = std::make_shared<RTLMask>(format, customNotations);
29
+ cache[reversed] = newMask;
30
+ return newMask;
31
+ }
32
+
33
+ Result apply(const CaretString& text) override {
34
+ return Mask::apply(text.reversed()).reversed(); // Assuming the Result class has a reversed method
35
+ }
36
+
37
+
38
+ private:
39
+
40
+
41
+ static std::string reversedFormat(const std::string& format) {
42
+ std::string reversed = std::string(format.rbegin(), format.rend());
43
+
44
+ // Replace logic (equivalent to Kotlin's replace)
45
+ size_t pos = 0;
46
+ while ((pos = reversed.find("\\[", pos)) != std::string::npos) {
47
+ reversed.replace(pos, 2, "\\");
48
+ pos += 1; // Advance position to prevent infinite loop
49
+ }
50
+ pos = 0;
51
+ while ((pos = reversed.find("]\\", pos)) != std::string::npos) {
52
+ reversed.replace(pos, 2, "\\[");
53
+ pos += 1;
54
+ }
55
+ pos = 0;
56
+ while ((pos = reversed.find("\\{", pos)) != std::string::npos) {
57
+ reversed.replace(pos, 2, "\\}");
58
+ pos += 1;
59
+ }
60
+ pos = 0;
61
+ while ((pos = reversed.find("}\\", pos)) != std::string::npos) {
62
+ reversed.replace(pos, 2, "\\{");
63
+ pos += 1;
64
+ }
65
+
66
+ // Map logic for brackets
67
+ for (char& ch : reversed) {
68
+ switch (ch) {
69
+ case '[': ch = ']'; break;
70
+ case ']': ch = '['; break;
71
+ case '{': ch = '}'; break;
72
+ case '}': ch = '{'; break;
73
+ default: break;
74
+ }
75
+ }
76
+ return reversed;
77
+ }
78
+ };
79
+ }
@@ -0,0 +1,58 @@
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 <stdexcept>
10
+ #include <limits>
11
+ #include "../Mask.h" // 确保包含 Mask 头文件
12
+ #include "CaretString.h" // 确保包含 CaretString 头文件
13
+
14
+ namespace TinpMask {
15
+
16
+ enum class AffinityCalculationStrategy { WHOLE_STRING, PREFIX, CAPACITY, EXTRACTED_VALUE_CAPACITY };
17
+
18
+ class AffinityCalculator {
19
+ public:
20
+ static int calculateAffinityOfMask(AffinityCalculationStrategy strategy, Mask &mask,
21
+ const CaretString &text) {
22
+ switch (strategy) {
23
+ case AffinityCalculationStrategy::WHOLE_STRING:
24
+ return mask.apply(text).affinity;
25
+
26
+ case AffinityCalculationStrategy::PREFIX:
27
+ return prefixIntersection(mask.apply(text).formattedText.string, text.string).length();
28
+
29
+ case AffinityCalculationStrategy::CAPACITY:
30
+ return text.string.length() > mask.totalTextLength() ? std::numeric_limits<int>::min()
31
+ : text.string.length() - mask.totalTextLength();
32
+
33
+ case AffinityCalculationStrategy::EXTRACTED_VALUE_CAPACITY: {
34
+ const auto &extractedValue = mask.apply(text).extractedValue;
35
+ return extractedValue.length() > mask.totalValueLength()
36
+ ? std::numeric_limits<int>::min()
37
+ : extractedValue.length() - mask.totalValueLength();
38
+ }
39
+ default:
40
+ throw std::invalid_argument("Unknown AffinityCalculationStrategy");
41
+ }
42
+ }
43
+
44
+ private:
45
+ // Helper function to find prefix intersection
46
+ static std::string prefixIntersection(const std::string &str1, const std::string &str2) {
47
+ size_t endIndex = 0;
48
+ while (endIndex < str1.length() && endIndex < str2.length()) {
49
+ if (str1[endIndex] == str2[endIndex]) {
50
+ endIndex += 1;
51
+ } else {
52
+ return str1.substr(0, endIndex);
53
+ }
54
+ }
55
+ return str1.substr(0, endIndex);
56
+ }
57
+ };
58
+ } // namespace TinpMask
@@ -0,0 +1,76 @@
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 <memory>
10
+
11
+ namespace TinpMask {
12
+
13
+ class CaretString {
14
+ // 光标重力基类
15
+ public:
16
+ class CaretGravity {
17
+ public:
18
+ virtual ~CaretGravity() = default; // 虚析构函数
19
+
20
+ // 获取自动完成值
21
+ virtual bool autocomplete() const { return false; }
22
+ // 获取自动跳过值
23
+ virtual bool autoskip() const { return false; }
24
+ };
25
+
26
+ // 向前的光标重力
27
+ class Forward : public CaretGravity {
28
+ public:
29
+ Forward(bool autoCompleteValue) : autocompleteValue(autoCompleteValue) {}
30
+
31
+ bool autocomplete() const override { return autocompleteValue; }
32
+
33
+ private:
34
+ bool autocompleteValue; // 自动完成值
35
+ };
36
+
37
+ // 向后的光标重力
38
+ class Backward : public CaretGravity {
39
+ public:
40
+ Backward(bool autoSkipValue) : autoskipValue(autoSkipValue) {}
41
+
42
+ bool autoskip() const override { return autoskipValue; }
43
+
44
+ private:
45
+ bool autoskipValue; // 自动跳过值
46
+ };
47
+
48
+ public:
49
+ // 构造函数
50
+ CaretString(const std::string &str, int caretPos, std::shared_ptr<CaretGravity> caretGrav)
51
+ : string(str), caretPosition(caretPos), caretGravity(caretGrav) {}
52
+
53
+ // 反转字符串并返回新的 CaretString 对象
54
+ CaretString reversed() const {
55
+ // 创建一个反转后的字符串
56
+ std::string reversedStr(string.rbegin(), string.rend());
57
+ // 计算新的 caretPosition
58
+ int newCaretPos = string.length() - caretPosition;
59
+ return CaretString(reversedStr, newCaretPos, caretGravity);
60
+ }
61
+
62
+ // 获取字符串
63
+ const std::string &getString() const { return string; }
64
+ // 获取光标位置
65
+ int getCaretPosition() const { return caretPosition; }
66
+ // 获取光标重力
67
+ std::shared_ptr<CaretGravity> getCaretGravity() const { return caretGravity; }
68
+
69
+
70
+ public:
71
+ std::string string; // 字符串内容
72
+ int caretPosition; // 光标位置
73
+ std::shared_ptr<CaretGravity> caretGravity; // 光标重力
74
+ };
75
+
76
+ } // namespace TinpMask
@@ -0,0 +1,58 @@
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 <memory>
10
+ #include <string>
11
+ #include <memory>
12
+ #include "CaretString.h"
13
+
14
+ namespace TinpMask {
15
+
16
+ class CaretStringIterator {
17
+ protected:
18
+ CaretString caretString; // 关联的 CaretString 对象
19
+ int currentIndex; // 当前索引
20
+
21
+ public:
22
+ // 构造函数
23
+ CaretStringIterator(const CaretString &caretStr, int index = 0) : caretString(caretStr), currentIndex(index) {}
24
+
25
+ // 插入是否影响光标位置
26
+ virtual bool insertionAffectsCaret() {
27
+
28
+ if (dynamic_cast<CaretString::Backward *>(caretString.caretGravity.get())) {
29
+ return currentIndex < caretString.getCaretPosition();
30
+ } else if (dynamic_cast<CaretString::Forward *>(caretString.caretGravity.get())) {
31
+ return currentIndex <= caretString.getCaretPosition() ||
32
+ (currentIndex == 0 && caretString.getCaretPosition() == 0);
33
+ }
34
+ return false;
35
+ }
36
+
37
+ // 删除是否影响光标位置
38
+ virtual bool deletionAffectsCaret() { return currentIndex < caretString.getCaretPosition(); }
39
+
40
+ /**
41
+ * 遍历 CaretString.string
42
+ * @postcondition: 迭代器位置移到下一个符号。
43
+ * @returns 当前符号。如果迭代器到达字符串末尾,返回 nullptr。
44
+ */
45
+ virtual char next() {
46
+ if (currentIndex >= caretString.getString().length()) {
47
+ return '\0'; // 返回空指针表示到达字符串末尾
48
+ }
49
+
50
+ // char *charPtr = new char; // 创建一个字符指针
51
+ auto charPtr = caretString.getString()[currentIndex]; // 获取当前字符
52
+ currentIndex += 1; // 移动到下一个索引
53
+ return charPtr; // 返回当前字符
54
+ }
55
+ };
56
+
57
+
58
+ } // namespace TinpMask
@@ -0,0 +1,25 @@
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 <memory>
9
+ #include "State.h"
10
+
11
+ namespace TinpMask {
12
+
13
+ class State;
14
+ class Next {
15
+ public:
16
+ std::shared_ptr<State> state; // 存储状态的智能指针
17
+ char insert; // 可插入的字符
18
+ bool pass; // 是否通过
19
+ char value; // 值字符,可选
20
+
21
+ // 构造函数
22
+ Next(std::shared_ptr<State> state, char insert, bool pass, char value)
23
+ : state(state), insert(insert), pass(pass), value(value) {}
24
+ };
25
+ } // namespace TinpMask