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 | |