Initial go at out of order loading working

This commit is contained in:
Shane Grant
2013-08-30 11:24:09 -07:00
parent c6b485ea69
commit 0a35bd3dc8
2 changed files with 75 additions and 2 deletions

View File

@@ -309,7 +309,23 @@ namespace cereal
//! Prepares to start reading the next node //! Prepares to start reading the next node
void startNode() void startNode()
{ {
itsNodes.emplace( itsNodes.top().child ); auto next = itsNodes.top().child;
auto const expectedName = itsNodes.top().name;
std::cerr << "Expected name was " << expectedName << ", actual name was: " << next->name() << std::endl;
// If the expected name does not match the loaded name, try to load the NVP name
// If we can't find the NVP name, throw an exception
if( expectedName && std::strcmp( next->name(), expectedName ) != 0 )
{
std::cerr << "Loading " << expectedName << std::endl;
next = itsXML.first_node( expectedName );
if( next == nullptr )
throw Exception("XML Parsing failed - provided NVP not found");
}
itsNodes.emplace( next );
//itsNodes.emplace( itsNodes.top().child );
} }
//! Finishes reading the current node //! Finishes reading the current node
@@ -320,6 +336,16 @@ namespace cereal
// advance parent // advance parent
itsNodes.top().advance(); itsNodes.top().advance();
// Reset name
itsNodes.top().name = nullptr;
}
//! Sets the name for the next node created with startNode
void setNextName( const char * name )
{
std::cerr << "Setting next name to be " << name << std::endl;
itsNodes.top().name = name;
} }
//! Loads a bool //! Loads a bool
@@ -450,7 +476,8 @@ namespace cereal
NodeInfo( rapidxml::xml_node<> * n = nullptr ) : NodeInfo( rapidxml::xml_node<> * n = nullptr ) :
node( n ), node( n ),
child( n ? n->first_node() : nullptr ), child( n ? n->first_node() : nullptr ),
size( XMLInputArchive::getNumChildren( n ) ) size( XMLInputArchive::getNumChildren( n ) ),
name( nullptr )
{ } { }
void advance() void advance()
@@ -465,6 +492,7 @@ namespace cereal
rapidxml::xml_node<> * node; //!< A pointer to this node rapidxml::xml_node<> * node; //!< A pointer to this node
rapidxml::xml_node<> * child; //!< A pointer to its current child rapidxml::xml_node<> * child; //!< A pointer to its current child
size_t size; size_t size;
const char * name; //!< The NVP name for next next child node
}; // NodeInfo }; // NodeInfo
private: private:
@@ -574,6 +602,7 @@ namespace cereal
template <class T> inline template <class T> inline
void load( XMLInputArchive & ar, NameValuePair<T> & t ) void load( XMLInputArchive & ar, NameValuePair<T> & t )
{ {
ar.setNextName( t.name );
ar( t.value ); ar( t.value );
} }

View File

@@ -500,6 +500,50 @@ int main()
std::remove("endian.out"); std::remove("endian.out");
} }
{
std::ofstream ss("xml_ordering.out");
cereal::XMLOutputArchive ar(ss);
double one = 1;
double two = 2;
double three = 3;
std::vector<int> four = {1, 2, 3, 4};
// Output is ordered 3 2 1 4
ar( three, CEREAL_NVP(two), one, cereal::make_nvp("five", four) );
}
{
std::ifstream ss("xml_ordering.out");
cereal::XMLInputArchive ar(ss);
// Output prodered out of order, try to load in order 1 2 3 4
double one;
double two;
double three;
std::vector<int> four;
ar( one ); // cereal can only give warnings if you used an NVP!
ar( CEREAL_NVP( two ) );
ar( three );
try
{
ar( CEREAL_NVP( three ) );
}
catch( cereal::Exception const & e )
{
std::cout << e.what() << std::endl;
std::cout << "Looked for three but we didn't use an NVP when saving" << std::endl;
}
ar( cereal::make_nvp("five", four) );
std::cout << one << std::endl;
std::cout << two << std::endl;
std::cout << three << std::endl;
for( auto i : four ) std::cout << i << " ";
std::cout << std::endl;
}
return 0; return 0;