diff --git a/src/commit_request.cpp b/src/commit_request.cpp index 830fc1f..3199d87 100644 --- a/src/commit_request.cpp +++ b/src/commit_request.cpp @@ -495,23 +495,28 @@ CommitRequest::ParseStatus CommitRequest::parse_chunk(char *data, size_t len) { } CommitRequest::ParseStatus CommitRequest::finish_streaming_parse() { + + CommitRequest::ParseStatus result; if (!json_parser_) { - return ParseStatus::Error; - } - - if (parser_context_.parse_error) { - return ParseStatus::Error; - } - - // Signal end of input - WeaselJsonStatus status = WeaselJsonParser_parse(json_parser_, nullptr, 0); - - if (status == WeaselJson_OK && parser_context_.parse_complete && - !parser_context_.parse_error) { - return ParseStatus::Complete; + result = ParseStatus::Error; + } else if (parser_context_.parse_error) { + result = ParseStatus::Error; } else { - parser_context_.parse_error = - "JSON parsing incomplete or failed during finalization"; - return ParseStatus::Error; + + // Signal end of input + WeaselJsonStatus status = WeaselJsonParser_parse(json_parser_, nullptr, 0); + + if (status == WeaselJson_OK && parser_context_.parse_complete && + !parser_context_.parse_error) { + result = ParseStatus::Complete; + } else { + parser_context_.parse_error = + "JSON parsing incomplete or failed during finalization"; + result = ParseStatus::Error; + } } + // Clear the memory used only during parsing + parser_context_.reset_arena_memory(); + + return result; } diff --git a/src/commit_request.hpp b/src/commit_request.hpp index 9339573..77dc7d7 100644 --- a/src/commit_request.hpp +++ b/src/commit_request.hpp @@ -42,6 +42,7 @@ class CommitRequest { struct PreconditionParseState { Precondition::Type type; std::optional version; + // These are owned by CommitRequest::arena std::optional key; std::optional begin; std::optional end; @@ -52,6 +53,7 @@ class CommitRequest { */ struct OperationParseState { Operation::Type type; + // These are owned by CommitRequest::arena std::optional key; std::optional value; std::optional begin; @@ -83,6 +85,7 @@ public: using ArenaStateStack = std::stack>>; + ArenaAllocator arena; ArenaStateStack state_stack; ArenaString current_key; @@ -101,14 +104,27 @@ public: ArenaString operation_type; // Constructor to initialize arena-allocated containers - explicit ParserContext(ArenaAllocator *arena) + explicit ParserContext() : state_stack(ArenaStateStack::container_type( - ArenaStlAllocator(arena))), - current_key(ArenaStlAllocator(arena)), - current_string(ArenaStlAllocator(arena)), - current_number(ArenaStlAllocator(arena)), - precondition_type(ArenaStlAllocator(arena)), - operation_type(ArenaStlAllocator(arena)) {} + ArenaStlAllocator(&arena))), + current_key(ArenaStlAllocator(&arena)), + current_string(ArenaStlAllocator(&arena)), + current_number(ArenaStlAllocator(&arena)), + precondition_type(ArenaStlAllocator(&arena)), + operation_type(ArenaStlAllocator(&arena)) {} + void reset_arena_memory() { + arena.reset(); + current_key = ArenaString{ArenaStlAllocator(&arena)}; + current_string = ArenaString{ArenaStlAllocator(&arena)}; + current_number = ArenaString{ArenaStlAllocator(&arena)}; + in_key = false; + current_precondition = {}; + current_operation = {}; + precondition_type = ArenaString{ArenaStlAllocator(&arena)}; + operation_type = ArenaString{ArenaStlAllocator(&arena)}; + state_stack = ArenaStateStack{ArenaStateStack::container_type( + ArenaStlAllocator(&arena))}; + } }; private: @@ -131,8 +147,7 @@ public: */ explicit CommitRequest() : arena_(), preconditions_(ArenaStlAllocator(&arena_)), - operations_(ArenaStlAllocator(&arena_)), - parser_context_(&arena_) {} + operations_(ArenaStlAllocator(&arena_)), parser_context_() {} /** * @brief Destructor - cleans up any active parser. @@ -297,8 +312,10 @@ public: if (json_parser_) { WeaselJsonParser_reset(json_parser_); } - parser_context_ = ParserContext(&arena_); + parser_context_.reset_arena_memory(); parser_context_.state_stack.push(ParseState::Root); + parser_context_.parse_error = nullptr; + parser_context_.parse_complete = false; } // Weaseljson callbacks (public for global callbacks)