* Parse data from a string / buffer. * * There are generally four operations for each data type: * - Peek: Check and return validity and value. Do not advance read position. * - TryRead: Check and return validity and value. Advance reader, if valid. * - Read: Check validity, return value or fallback-value. Advance reader, even if value is invalid, to avoid deadlocks/stalling. * - Skip: Disca
| 25 | * - Skip: Discard value. Advance reader, even if value is invalid, to avoid deadlocks/stalling. |
| 26 | */ |
| 27 | class StringConsumer { |
| 28 | public: |
| 29 | using size_type = std::string_view::size_type; |
| 30 | |
| 31 | /** |
| 32 | * Special value for "end of data". |
| 33 | */ |
| 34 | static constexpr size_type npos = std::string_view::npos; |
| 35 | |
| 36 | /** |
| 37 | * ASCII whitespace characters, excluding new-line. |
| 38 | * Usable in FindChar(In|NotIn), (Peek|Read|Skip)(If|Until)Char(In|NotIn) |
| 39 | */ |
| 40 | static const std::string_view WHITESPACE_NO_NEWLINE; |
| 41 | /** |
| 42 | * ASCII whitespace characters, including new-line. |
| 43 | * Usable in FindChar(In|NotIn), (Peek|Read|Skip)(If|Until)Char(In|NotIn) |
| 44 | */ |
| 45 | static const std::string_view WHITESPACE_OR_NEWLINE; |
| 46 | |
| 47 | private: |
| 48 | std::string_view src; |
| 49 | size_type position = 0; |
| 50 | |
| 51 | static void LogError(std::string &&msg); |
| 52 | |
| 53 | public: |
| 54 | /** |
| 55 | * Construct parser with data from string. |
| 56 | */ |
| 57 | explicit StringConsumer(std::string_view src) : src(src) {} |
| 58 | /** |
| 59 | * Construct parser with data from string. |
| 60 | */ |
| 61 | explicit StringConsumer(const std::string &src) : src(src) {} |
| 62 | /** |
| 63 | * Construct parser with data from span. |
| 64 | */ |
| 65 | explicit StringConsumer(std::span<const char> src) : src(src.data(), src.size()) {} |
| 66 | |
| 67 | /** |
| 68 | * Check whether any bytes left to read. |
| 69 | */ |
| 70 | [[nodiscard]] bool AnyBytesLeft() const noexcept { return this->position < this->src.size(); } |
| 71 | /** |
| 72 | * Get number of bytes left to read. |
| 73 | */ |
| 74 | [[nodiscard]] size_type GetBytesLeft() const noexcept { return this->src.size() - this->position; } |
| 75 | |
| 76 | /** |
| 77 | * Check whether any bytes were already read. |
| 78 | */ |
| 79 | [[nodiscard]] bool AnyBytesRead() const noexcept { return this->position > 0; } |
| 80 | /** |
| 81 | * Get number of already read bytes. |
| 82 | */ |
| 83 | [[nodiscard]] size_type GetBytesRead() const noexcept { return this->position; } |
| 84 |