From a8bd58a6280c0b7f0cf7a553f1b4a3c7b9a83cf4 Mon Sep 17 00:00:00 2001 From: EmilianC Date: Sat, 20 Jul 2024 23:23:55 -0400 Subject: [PATCH] Added lookAhead() utility to JSONInputArchive - This allows checking for JSON nodes without throwing exceptions --- include/cereal/archives/json.hpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/include/cereal/archives/json.hpp b/include/cereal/archives/json.hpp index f86bcd40..d55edd38 100644 --- a/include/cereal/archives/json.hpp +++ b/include/cereal/archives/json.hpp @@ -489,6 +489,8 @@ namespace cereal class Iterator { public: + static constexpr size_t INVALID_INDEX = static_cast(-1); + Iterator() : itsIndex( 0 ), itsType(Null_) {} Iterator(MemberIterator begin, MemberIterator end) : @@ -535,9 +537,9 @@ namespace cereal return nullptr; } - //! Adjust our position such that we are at the node with the given name - /*! @throws Exception if no such named node exists */ - inline void search( const char * searchName ) + //! Check if an upcoming node exists, without changing state + //! This provides an exception-free option to search ahead + inline size_t lookAhead( const char * searchName ) const { const auto len = std::strlen( searchName ); size_t index = 0; @@ -547,11 +549,24 @@ namespace cereal if( ( std::strncmp( searchName, currentName, len ) == 0 ) && ( std::strlen( currentName ) == len ) ) { - itsIndex = index; - return; + return index; } } + return INVALID_INDEX; + } + + //! Adjust our position such that we are at the node with the given name + /*! @throws Exception if no such named node exists */ + inline void search( const char * searchName ) + { + const size_t index = lookAhead( searchName ); + if (index != INVALID_INDEX) + { + itsIndex = index; + return; + } + throw Exception("JSON Parsing failed - provided NVP (" + std::string(searchName) + ") not found"); } @@ -624,6 +639,12 @@ namespace cereal return itsIteratorStack.back().name(); } + //! Returns whether or not the given searchName apears as an upcoming json node + bool lookAhead( const char * searchName ) const + { + return itsIteratorStack.back().lookAhead( searchName ) != Iterator::INVALID_INDEX; + } + //! Sets the name for the next node created with startNode void setNextName( const char * name ) {