| 1 | #include "simdjson/base.h" |
| 2 | #include "simdjson/internal/isadetection.h" |
| 3 | |
| 4 | namespace simdjson { |
| 5 | namespace SIMDJSON_IMPLEMENTATION { |
| 6 | |
| 7 | // expectation: sizeof(open_container) = 64/8. |
| 8 | struct open_container { |
| 9 | uint32_t tape_index; // where, on the tape, does the scope ([,{) begins |
| 10 | uint32_t count; // how many elements in the scope |
| 11 | }; // struct open_container |
| 12 | |
| 13 | static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits" ); |
| 14 | |
| 15 | class dom_parser_implementation final : public internal::dom_parser_implementation { |
| 16 | public: |
| 17 | /** Tape location of each open { or [ */ |
| 18 | std::unique_ptr<open_container[]> open_containers{}; |
| 19 | /** Whether each open container is a [ or { */ |
| 20 | std::unique_ptr<bool[]> is_array{}; |
| 21 | /** Buffer passed to stage 1 */ |
| 22 | const uint8_t *buf{}; |
| 23 | /** Length passed to stage 1 */ |
| 24 | size_t len{0}; |
| 25 | /** Document passed to stage 2 */ |
| 26 | dom::document *doc{}; |
| 27 | |
| 28 | inline dom_parser_implementation() noexcept; |
| 29 | inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; |
| 30 | inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept; |
| 31 | dom_parser_implementation(const dom_parser_implementation &) = delete; |
| 32 | dom_parser_implementation &operator=(const dom_parser_implementation &) = delete; |
| 33 | |
| 34 | simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final; |
| 35 | simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final; |
| 36 | simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final; |
| 37 | simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final; |
| 38 | simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept final; |
| 39 | simdjson_warn_unused uint8_t *parse_wobbly_string(const uint8_t *src, uint8_t *dst) const noexcept final; |
| 40 | inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final; |
| 41 | inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final; |
| 42 | private: |
| 43 | simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity); |
| 44 | |
| 45 | }; |
| 46 | |
| 47 | } // namespace SIMDJSON_IMPLEMENTATION |
| 48 | } // namespace simdjson |
| 49 | |
| 50 | namespace simdjson { |
| 51 | namespace SIMDJSON_IMPLEMENTATION { |
| 52 | |
| 53 | inline dom_parser_implementation::dom_parser_implementation() noexcept = default; |
| 54 | inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default; |
| 55 | inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default; |
| 56 | |
| 57 | // Leaving these here so they can be inlined if so desired |
| 58 | inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept { |
| 59 | if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; } |
| 60 | // Stage 1 index output |
| 61 | size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7; |
| 62 | structural_indexes.reset( p: new (std::nothrow) uint32_t[max_structures] ); |
| 63 | if (!structural_indexes) { _capacity = 0; return MEMALLOC; } |
| 64 | structural_indexes[0] = 0; |
| 65 | n_structural_indexes = 0; |
| 66 | |
| 67 | _capacity = capacity; |
| 68 | return SUCCESS; |
| 69 | } |
| 70 | |
| 71 | inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept { |
| 72 | // Stage 2 stacks |
| 73 | open_containers.reset(p: new (std::nothrow) open_container[max_depth]); |
| 74 | is_array.reset(p: new (std::nothrow) bool[max_depth]); |
| 75 | if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; } |
| 76 | |
| 77 | _max_depth = max_depth; |
| 78 | return SUCCESS; |
| 79 | } |
| 80 | |
| 81 | } // namespace SIMDJSON_IMPLEMENTATION |
| 82 | } // namespace simdjson |
| 83 | |