1#include "simdjson/base.h"
2#include "simdjson/internal/isadetection.h"
3
4namespace simdjson {
5namespace SIMDJSON_IMPLEMENTATION {
6
7// expectation: sizeof(open_container) = 64/8.
8struct 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
13static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits");
14
15class dom_parser_implementation final : public internal::dom_parser_implementation {
16public:
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;
42private:
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
50namespace simdjson {
51namespace SIMDJSON_IMPLEMENTATION {
52
53inline dom_parser_implementation::dom_parser_implementation() noexcept = default;
54inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default;
55inline 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
58inline 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
71inline 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