diff --git a/src/commit_request.cpp b/src/commit_request.cpp index 258796a..bef08aa 100644 --- a/src/commit_request.cpp +++ b/src/commit_request.cpp @@ -75,23 +75,18 @@ void CommitRequest::on_begin_object(void *userdata) { if (ctx.parse_error) return; - if (ctx.state_stack.empty()) { - ctx.parse_error = "Unexpected object start - empty state stack"; - return; - } - - ParseState current_state = ctx.state_stack.top(); + ParseState current_state = ctx.current_state; switch (current_state) { case ParseState::Root: // Expected - this is the main object break; case ParseState::PreconditionsArray: - ctx.state_stack.push(ParseState::PreconditionObject); + ctx.current_state = ParseState::PreconditionObject; ctx.current_precondition = PreconditionParseState{}; break; case ParseState::OperationsArray: - ctx.state_stack.push(ParseState::OperationObject); + ctx.current_state = ParseState::OperationObject; ctx.current_operation = OperationParseState{}; break; default: @@ -104,15 +99,18 @@ void CommitRequest::on_end_object(void *userdata) { auto *self = static_cast(userdata); auto &ctx = self->parser_context_; - if (ctx.parse_error || ctx.state_stack.empty()) { - if (!ctx.parse_error) { - ctx.parse_error = "Unexpected object end - empty state stack"; - } + if (ctx.parse_error) { return; } - ParseState current_state = ctx.state_stack.top(); - ctx.state_stack.pop(); + ParseState current_state = ctx.current_state; + + // Handle state transitions on object end + if (current_state == ParseState::PreconditionObject) { + ctx.current_state = ParseState::PreconditionsArray; + } else if (current_state == ParseState::OperationObject) { + ctx.current_state = ParseState::OperationsArray; + } switch (current_state) { case ParseState::Root: @@ -227,10 +225,10 @@ void CommitRequest::on_begin_array(void *userdata) { if (ctx.current_key == "preconditions") { ctx.current_key.clear(); - ctx.state_stack.push(ParseState::PreconditionsArray); + ctx.current_state = ParseState::PreconditionsArray; } else if (ctx.current_key == "operations") { ctx.current_key.clear(); - ctx.state_stack.push(ParseState::OperationsArray); + ctx.current_state = ParseState::OperationsArray; } else { ctx.parse_error = "Invalid array field - only 'preconditions' and " "'operations' arrays are allowed"; @@ -241,14 +239,15 @@ void CommitRequest::on_end_array(void *userdata) { auto *self = static_cast(userdata); auto &ctx = self->parser_context_; - if (ctx.parse_error || ctx.state_stack.empty()) { - if (!ctx.parse_error) { - ctx.parse_error = "Unexpected array end - empty state stack"; - } + if (ctx.parse_error) { return; } - ctx.state_stack.pop(); + // Transition back to Root state when arrays end + if (ctx.current_state == ParseState::PreconditionsArray || + ctx.current_state == ParseState::OperationsArray) { + ctx.current_state = ParseState::Root; + } } void CommitRequest::on_number_data(void *userdata, const char *buf, int len, @@ -285,12 +284,7 @@ void CommitRequest::on_null_literal(void *) { void CommitRequest::handle_completed_string(std::string_view s) { auto &ctx = parser_context_; - if (ctx.state_stack.empty()) { - ctx.parse_error = "String value received with empty state stack"; - return; - } - - ParseState current_state = ctx.state_stack.top(); + ParseState current_state = ctx.current_state; switch (current_state) { case ParseState::Root: @@ -363,12 +357,7 @@ void CommitRequest::handle_completed_string(std::string_view s) { void CommitRequest::handle_completed_number(std::string_view s) { auto &ctx = parser_context_; - if (ctx.state_stack.empty()) { - ctx.parse_error = "Number value received with empty state stack"; - return; - } - - ParseState current_state = ctx.state_stack.top(); + ParseState current_state = ctx.current_state; switch (current_state) { case ParseState::Root: diff --git a/src/commit_request.hpp b/src/commit_request.hpp index 194a795..83a1712 100644 --- a/src/commit_request.hpp +++ b/src/commit_request.hpp @@ -64,9 +64,6 @@ public: // Parser state enum class ParseState { Root, - RequestId, - LeaderId, - ReadVersion, PreconditionsArray, PreconditionObject, OperationsArray, @@ -82,12 +79,9 @@ public: struct ParserContext { using ArenaString = std::basic_string, ArenaStlAllocator>; - using ArenaStateStack = - std::stack>>; ArenaAllocator arena; - ArenaStateStack state_stack; + ParseState current_state = ParseState::Root; ArenaString current_key; ArenaString current_string; ArenaString current_number; @@ -105,8 +99,7 @@ public: // Constructor to initialize arena-allocated containers explicit ParserContext() - : state_stack(ArenaStateStack::container_type( - ArenaStlAllocator(&arena))), + : current_key(ArenaStlAllocator(&arena)), current_string(ArenaStlAllocator(&arena)), current_number(ArenaStlAllocator(&arena)), @@ -122,8 +115,7 @@ public: current_operation = {}; precondition_type = ArenaString{ArenaStlAllocator(&arena)}; operation_type = ArenaString{ArenaStlAllocator(&arena)}; - state_stack = ArenaStateStack{ArenaStateStack::container_type( - ArenaStlAllocator(&arena))}; + current_state = ParseState::Root; } }; @@ -313,7 +305,7 @@ public: WeaselJsonParser_reset(json_parser_); } parser_context_.reset_arena_memory(); - parser_context_.state_stack.push(ParseState::Root); + parser_context_.current_state = ParseState::Root; parser_context_.parse_error = nullptr; parser_context_.parse_complete = false; }