diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-20 01:51:05 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-20 01:51:05 +0200 |
| commit | 40d9a1d5c3e85486aea964c1446402a3be6ec05a (patch) | |
| tree | 7af82c46a459afc99156e5a6022946b43e35a3de /source/util | |
| parent | bc228753bfb4a2faea540cddb20fc39ebd265db5 (diff) | |
feat(import): parse otpauth URIs and unencrypted Aegis JSON in resumable steps
Streaming JSON tokenizer with depth and length limits and native skipping
of long strings; Aegis reader for database versions 1-3 with groups and
encrypted-export detection; otpauth parser with ';' separators and Steam;
import job with Replace mode, duplicate and replacement checks, a sealed
multi-part buffer and a report. Google Authenticator exports deferred.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/util')
| -rw-r--r-- | source/util/Text.mc | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/source/util/Text.mc b/source/util/Text.mc new file mode 100644 index 0000000..9af7b32 --- /dev/null +++ b/source/util/Text.mc @@ -0,0 +1,56 @@ +// Author: cirakg & claude ai +// Summary: Small string helpers for parsing: trimming, clipping for messages, integer parsing, case-insensitive search. + +import Toybox.Lang; + +module Text { + + // Text without leading and trailing spaces, tabs and line breaks. + function trim(text as String) as String { + var chars = text.toCharArray(); + var start = 0; + var end = chars.size(); + while (start < end && isSpace(chars[start])) { + start++; + } + while (end > start && isSpace(chars[end - 1])) { + end--; + } + return start == 0 && end == chars.size() ? text : text.substring(start, end) as String; + } + + function isSpace(c as Char) as Boolean { + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; + } + + // At most maxChars characters, with "…" when shortened (for messages that + // quote user input). + function clip(text as String, maxChars as Number) as String { + return text.length() <= maxChars ? text : (text.substring(0, maxChars) as String) + "…"; + } + + // A non-negative decimal integer (at most 18 digits), or null. + function parseLong(text as String) as Long? { + var chars = text.toCharArray(); + if (chars.size() == 0 || chars.size() > 18) { + return null; + } + var value = 0l; + for (var i = 0; i < chars.size(); i++) { + var c = chars[i]; + if (c < '0' || c > '9') { + return null; + } + value = value * 10 + (c.toNumber() - 48); + } + return value; + } + + // Index of needle in haystack ignoring ASCII case, from `from`, or -1. + function findIgnoreCase(haystack as String, needle as String, from as Number) as Number { + var lower = haystack.toLower(); + var rest = from == 0 ? lower : lower.substring(from, lower.length()) as String; + var at = rest.find(needle.toLower()); + return at == null ? -1 : at + from; + } +} |
