| 55 | } |
| 56 | |
| 57 | class Parser { |
| 58 | public: |
| 59 | explicit Parser() noexcept = default; |
| 60 | // sonic_force_inline Parser(JsonInput& input) : input_(input) {} |
| 61 | Parser(Parser &&other) noexcept = default; |
| 62 | sonic_force_inline Parser(const Parser &other) = delete; |
| 63 | sonic_force_inline Parser &operator=(const Parser &other) = delete; |
| 64 | sonic_force_inline Parser &operator=(Parser &&other) noexcept = default; |
| 65 | ~Parser() noexcept = default; |
| 66 | |
| 67 | template <unsigned parseFlags = kParseDefault, typename SAX> |
| 68 | sonic_force_inline ParseResult Parse(char *data, size_t len, SAX &sax) { |
| 69 | reset(); |
| 70 | json_buf_ = reinterpret_cast<uint8_t *>(data); |
| 71 | len_ = len; |
| 72 | parseImpl<parseFlags>(sax); |
| 73 | if (!err_ && hasTrailingChars()) { |
| 74 | err_ = kParseErrorInvalidChar; |
| 75 | } |
| 76 | return ParseResult{err_, static_cast<size_t>(pos_)}; |
| 77 | } |
| 78 | |
| 79 | // parseLazyImpl only mark the json positions, and not parse any more, even |
| 80 | // the keys. |
| 81 | template <typename LazySAX> |
| 82 | sonic_force_inline ParseResult ParseLazy(const uint8_t *data, size_t len, |
| 83 | LazySAX &sax) { |
| 84 | return parseLazyImpl(data, len, sax); |
| 85 | } |
| 86 | |
| 87 | private: |
| 88 | sonic_force_inline bool hasTrailingChars() { |
| 89 | while (pos_ < len_) { |
| 90 | if (!internal::IsSpace(json_buf_[pos_])) return true; |
| 91 | pos_++; |
| 92 | } |
| 93 | return false; |
| 94 | } |
| 95 | |
| 96 | sonic_force_inline void setParseError(SonicError err) { err_ = err; } |
| 97 | |
| 98 | template <typename SAX> |
| 99 | sonic_force_inline bool parseNull(SAX &sax) { |
| 100 | const static uint32_t kNullBin = 0x6c6c756e; |
| 101 | if (internal::EqBytes4(json_buf_ + pos_ - 1, kNullBin)) { |
| 102 | pos_ += 3; |
| 103 | return sax.Null(); |
| 104 | } |
| 105 | setParseError(kParseErrorInvalidChar); |
| 106 | return false; |
| 107 | } |
| 108 | |
| 109 | template <typename SAX> |
| 110 | sonic_force_inline bool parseFalse(SAX &sax) { |
| 111 | const static uint32_t kFalseBin = |
| 112 | 0x65736c61; // the binary of 'alse' in false |
| 113 | if (internal::EqBytes4(json_buf_ + pos_, kFalseBin)) { |
| 114 | pos_ += 4; |
nothing calls this directly
no outgoing calls
no test coverage detected