diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
commit | 8dd16259287f58f9273002717ec4d27e97127719 (patch) | |
tree | 3863e62a53829a84037444beab3abd4ed9dfc7d0 /xpcom/ds/Tokenizer.h | |
parent | Releasing progress-linux version 126.0.1-1~progress7.99u1. (diff) | |
download | firefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz firefox-8dd16259287f58f9273002717ec4d27e97127719.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xpcom/ds/Tokenizer.h')
-rw-r--r-- | xpcom/ds/Tokenizer.h | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/xpcom/ds/Tokenizer.h b/xpcom/ds/Tokenizer.h index 713b63f269..6a4ec89d51 100644 --- a/xpcom/ds/Tokenizer.h +++ b/xpcom/ds/Tokenizer.h @@ -439,6 +439,66 @@ class TTokenizer : public TokenizerBase<TChar> { } /** + * This is an hexadecimal read helper. It returns false and doesn't move the + * read cursor when any of the following happens: + * - the token at the read cursor is not 0, and it's not followed by x + * - the token(s) that follow don't make a valid hexadecimal number + * - the final number doesn't fit the T type + * Otherwise true is returned, aValue is filled with the integral number + * and the cursor is moved forward. + */ + template <typename T> + [[nodiscard]] bool ReadHexadecimal(T* aValue, bool aPrefixed = true) { + MOZ_RELEASE_ASSERT(aValue); + + typename base::TAString::const_char_iterator rollback = mRollback; + typename base::TAString::const_char_iterator cursor = base::mCursor; + auto revert = MakeScopeExit([&] { + // Move to a state as if Check() call has failed + mRollback = rollback; + base::mCursor = cursor; + base::mHasFailed = true; + }); + + if (aPrefixed) { + typename base::Token t; + if (!Check(base::TOKEN_INTEGER, t) && t.AsInteger() != 0) { + return false; + } + + if (!CheckChar([](const TChar aChar) { return aChar == 'x'; })) { + return false; + } + } + + TChar c = 'z'; + mozilla::CheckedInt<T> resultingNumber = 0; + while (ReadChar( + [](const TChar aChar) { + return (aChar >= '0' && aChar <= '9') || + (aChar >= 'A' && aChar <= 'F') || + (aChar >= 'a' && aChar <= 'f'); + }, + &c)) { + resultingNumber *= 16; + if (c <= '9') { + resultingNumber += static_cast<uint64_t>(c - '0'); + } else if (c <= 'F') { + resultingNumber += static_cast<uint64_t>(c - 'A') + 0xa; + } else { + resultingNumber += static_cast<uint64_t>(c - 'a') + 0xa; + } + } + if (c == 'z' || !resultingNumber.isValid()) { + return false; + } + + *aValue = resultingNumber.value(); + revert.release(); + return true; + } + + /** * Returns the read cursor position back as it was before the last call of any * parsing method of TTokenizer (Next, Check*, Skip*, Read*) so that the last * operation can be repeated. Rollback cannot be used multiple times, it only |