NDDEM
xml.hpp
Go to the documentation of this file.
1 
3 /*
4  Copyright (c) 2014, Randolph Voorhies, Shane Grant
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in the
13  documentation and/or other materials provided with the distribution.
14  * Neither the name of the copyright holder nor the
15  names of its contributors may be used to endorse or promote products
16  derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
22  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #ifndef CEREAL_ARCHIVES_XML_HPP_
30 #define CEREAL_ARCHIVES_XML_HPP_
31 #include "cereal/cereal.hpp"
32 #include "cereal/details/util.hpp"
33 
37 
38 #include <sstream>
39 #include <stack>
40 #include <vector>
41 #include <limits>
42 #include <string>
43 #include <cstring>
44 #include <cmath>
45 
46 namespace cereal
47 {
48  namespace xml_detail
49  {
50  #ifndef CEREAL_XML_STRING_VALUE
52 
54  #define CEREAL_XML_STRING_VALUE "cereal"
55  #endif // CEREAL_XML_STRING_VALUE
56 
59 
61  inline bool isWhitespace( char c )
62  {
63  return c == ' ' || c == '\t' || c == '\n' || c == '\r';
64  }
65  }
66 
67  // ######################################################################
69 
96  class XMLOutputArchive : public OutputArchive<XMLOutputArchive>, public traits::TextArchive
97  {
98  public:
102 
104 
106  class Options
107  {
108  public:
110  static Options Default(){ return Options(); }
111 
113 
117  explicit Options( int precision_ = std::numeric_limits<double>::max_digits10,
118  bool indent_ = true,
119  bool outputType_ = false,
120  bool sizeAttributes_ = true ) :
121  itsPrecision( precision_ ),
122  itsIndent( indent_ ),
123  itsOutputType( outputType_ ),
124  itsSizeAttributes( sizeAttributes_ )
125  { }
126 
138 
140  Options & precision( int value ){ itsPrecision = value; return * this; }
142  Options & indent( bool enable ){ itsIndent = enable; return *this; }
144  Options & outputType( bool enable ){ itsOutputType = enable; return *this; }
146  Options & sizeAttributes( bool enable ){ itsSizeAttributes = enable; return *this; }
147 
149 
150  private:
151  friend class XMLOutputArchive;
153  bool itsIndent;
156  };
157 
159 
163  XMLOutputArchive( std::ostream & stream, Options const & options = Options::Default() ) :
165  itsStream(stream),
166  itsOutputType( options.itsOutputType ),
167  itsIndent( options.itsIndent ),
169  {
170  // rapidxml will delete all allocations when xml_document is cleared
172  node->append_attribute( itsXML.allocate_attribute( "version", "1.0" ) );
173  node->append_attribute( itsXML.allocate_attribute( "encoding", "utf-8" ) );
174  itsXML.append_node( node );
175 
176  // allocate root node
178  itsXML.append_node( root );
179  itsNodes.emplace( root );
180 
181  // set attributes on the streams
182  itsStream << std::boolalpha;
183  itsStream.precision( options.itsPrecision );
184  itsOS << std::boolalpha;
185  itsOS.precision( options.itsPrecision );
186  }
187 
190  {
191  const int flags = itsIndent ? 0x0 : rapidxml::print_no_indenting;
192  rapidxml::print( itsStream, itsXML, flags );
193  itsXML.clear();
194  }
195 
197 
200  void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
201  {
202  itsNodes.top().name = name;
203 
204  startNode();
205 
206  auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
207  saveValue( base64string );
208 
209  if( itsOutputType )
210  itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "type", "cereal binary data" ) );
211 
212  finishNode();
213  }
214 
216 
220 
222 
227  void startNode()
228  {
229  // generate a name for this new node
230  const auto nameString = itsNodes.top().getValueName();
231 
232  // allocate strings for all of the data in the XML object
233  auto namePtr = itsXML.allocate_string( nameString.data(), nameString.length() + 1 );
234 
235  // insert into the XML
236  auto node = itsXML.allocate_node( rapidxml::node_element, namePtr, nullptr, nameString.size() );
237  itsNodes.top().node->append_node( node );
238  itsNodes.emplace( node );
239  }
240 
242  void finishNode()
243  {
244  itsNodes.pop();
245  }
246 
248  void setNextName( const char * name )
249  {
250  itsNodes.top().name = name;
251  }
252 
254 
257  template <class T> inline
258  void saveValue( T const & value )
259  {
260  itsOS.clear(); itsOS.seekp( 0, std::ios::beg );
261  itsOS << value << std::ends;
262 
263  auto strValue = itsOS.str();
264 
265  // itsOS.str() may contain data from previous calls after the first '\0' that was just inserted
266  // and this data is counted in the length call. We make sure to remove that section so that the
267  // whitespace validation is done properly
268  strValue.resize(std::strlen(strValue.c_str()));
269 
270  // If the first or last character is a whitespace, add xml:space attribute
271  const auto len = strValue.length();
272  if ( len > 0 && ( xml_detail::isWhitespace( strValue[0] ) || xml_detail::isWhitespace( strValue[len - 1] ) ) )
273  {
274  itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "xml:space", "preserve" ) );
275  }
276 
277  // allocate strings for all of the data in the XML object
278  auto dataPtr = itsXML.allocate_string(strValue.c_str(), strValue.length() + 1 );
279 
280  // insert into the XML
281  itsNodes.top().node->append_node( itsXML.allocate_node( rapidxml::node_data, nullptr, dataPtr ) );
282  }
283 
285  void saveValue( uint8_t const & value )
286  {
287  saveValue( static_cast<uint32_t>( value ) );
288  }
289 
291  void saveValue( int8_t const & value )
292  {
293  saveValue( static_cast<int32_t>( value ) );
294  }
295 
297  template <class T> inline
298  void insertType()
299  {
300  if( !itsOutputType )
301  return;
302 
303  // generate a name for this new node
304  const auto nameString = util::demangledName<T>();
305 
306  // allocate strings for all of the data in the XML object
307  auto namePtr = itsXML.allocate_string( nameString.data(), nameString.length() + 1 );
308 
309  itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "type", namePtr ) );
310  }
311 
313  void appendAttribute( const char * name, const char * value )
314  {
315  auto namePtr = itsXML.allocate_string( name );
316  auto valuePtr = itsXML.allocate_string( value );
317  itsNodes.top().node->append_attribute( itsXML.allocate_attribute( namePtr, valuePtr ) );
318  }
319 
320  bool hasSizeAttributes() const { return itsSizeAttributes; }
321 
322  protected:
324  struct NodeInfo
325  {
327  const char * nm = nullptr ) :
328  node( n ),
329  counter( 0 ),
330  name( nm )
331  { }
332 
334  size_t counter;
335  const char * name;
336 
338 
341  std::string getValueName()
342  {
343  if( name )
344  {
345  auto n = name;
346  name = nullptr;
347  return {n};
348  }
349  else
350  return "value" + std::to_string( counter++ ) + "\0";
351  }
352  }; // NodeInfo
353 
355 
356  private:
357  std::ostream & itsStream;
359  std::stack<NodeInfo> itsNodes;
360  std::ostringstream itsOS;
362  bool itsIndent;
364  }; // XMLOutputArchive
365 
366  // ######################################################################
368 
405  class XMLInputArchive : public InputArchive<XMLInputArchive>, public traits::TextArchive
406  {
407  public:
411 
413 
417  XMLInputArchive( std::istream & stream ) :
418  InputArchive<XMLInputArchive>( this ),
419  itsData( std::istreambuf_iterator<char>( stream ), std::istreambuf_iterator<char>() )
420  {
421  try
422  {
423  itsData.push_back('\0'); // rapidxml will do terrible things without the data being null terminated
425  }
426  catch( rapidxml::parse_error const & )
427  {
428  //std::cerr << "-----Original-----" << std::endl;
429  //stream.seekg(0);
430  //std::cout << std::string( std::istreambuf_iterator<char>( stream ), std::istreambuf_iterator<char>() ) << std::endl;
431 
432  //std::cerr << "-----Error-----" << std::endl;
433  //std::cerr << e.what() << std::endl;
434  //std::cerr << e.where<char>() << std::endl;
435  throw Exception("XML Parsing failed - likely due to invalid characters or invalid naming");
436  }
437 
438  // Parse the root
440  if( root == nullptr )
441  throw Exception("Could not detect cereal root node - likely due to empty or invalid input");
442  else
443  itsNodes.emplace( root );
444  }
445 
447 
449 
454  void loadBinaryValue( void * data, size_t size, const char * name = nullptr )
455  {
456  setNextName( name );
457  startNode();
458 
459  std::string encoded;
460  loadValue( encoded );
461 
462  auto decoded = base64::decode( encoded );
463 
464  if( size != decoded.size() )
465  throw Exception("Decoded binary data size does not match specified size");
466 
467  std::memcpy( data, decoded.data(), decoded.size() );
468 
469  finishNode();
470  }
471 
473 
477 
479 
488  void startNode()
489  {
490  auto next = itsNodes.top().child; // By default we would move to the next child node
491  auto const expectedName = itsNodes.top().name; // this is the expected name from the NVP, if provided
492 
493  // If we were given an NVP name, look for it in the current level of the document.
494  // We only need to do this if either we have exhausted the siblings of the current level or
495  // the NVP name does not match the name of the node we would normally read next
496  if( expectedName && ( next == nullptr || std::strcmp( next->name(), expectedName ) != 0 ) )
497  {
498  next = itsNodes.top().search( expectedName );
499 
500  if( next == nullptr )
501  throw Exception("XML Parsing failed - provided NVP (" + std::string(expectedName) + ") not found");
502  }
503 
504  itsNodes.emplace( next );
505  }
506 
508  void finishNode()
509  {
510  // remove current
511  itsNodes.pop();
512 
513  // advance parent
514  itsNodes.top().advance();
515 
516  // Reset name
517  itsNodes.top().name = nullptr;
518  }
519 
522  const char * getNodeName() const
523  {
524  return itsNodes.top().getChildName();
525  }
526 
528  void setNextName( const char * name )
529  {
530  itsNodes.top().name = name;
531  }
532 
536  void loadValue( T & value )
537  {
538  std::istringstream is( itsNodes.top().node->value() );
539  is.setf( std::ios::boolalpha );
540  is >> value;
541  }
542 
546  sizeof(T) == sizeof(char)> = traits::sfinae> inline
547  void loadValue( T & value )
548  {
549  value = *reinterpret_cast<T*>( itsNodes.top().node->value() );
550  }
551 
554  {
555  int32_t val; loadValue( val ); value = static_cast<int8_t>( val );
556  }
557 
560  {
561  uint32_t val; loadValue( val ); value = static_cast<uint8_t>( val );
562  }
563 
569  sizeof(T) < sizeof(long long)> = traits::sfinae> inline
570  void loadValue( T & value )
571  {
572  value = static_cast<T>( std::stoul( itsNodes.top().node->value() ) );
573  }
574 
578  sizeof(T) >= sizeof(long long)> = traits::sfinae> inline
579  void loadValue( T & value )
580  {
581  value = static_cast<T>( std::stoull( itsNodes.top().node->value() ) );
582  }
583 
587  sizeof(T) <= sizeof(int)> = traits::sfinae> inline
588  void loadValue( T & value )
589  {
590  value = static_cast<T>( std::stoi( itsNodes.top().node->value() ) );
591  }
592 
595  (sizeof(T) > sizeof(int)),
596  sizeof(T) <= sizeof(long)> = traits::sfinae> inline
597  void loadValue( T & value )
598  {
599  value = static_cast<T>( std::stol( itsNodes.top().node->value() ) );
600  }
601 
604  (sizeof(T) > sizeof(long)),
605  sizeof(T) <= sizeof(long long)> = traits::sfinae> inline
606  void loadValue( T & value )
607  {
608  value = static_cast<T>( std::stoll( itsNodes.top().node->value() ) );
609  }
610 
612  void loadValue( float & value )
613  {
614  try
615  {
616  value = std::stof( itsNodes.top().node->value() );
617  }
618  catch( std::out_of_range const & )
619  {
620  // special case for denormalized values
621  std::istringstream is( itsNodes.top().node->value() );
622  is >> value;
623  if( std::fpclassify( value ) != FP_SUBNORMAL )
624  throw;
625  }
626  }
627 
629  void loadValue( double & value )
630  {
631  try
632  {
633  value = std::stod( itsNodes.top().node->value() );
634  }
635  catch( std::out_of_range const & )
636  {
637  // special case for denormalized values
638  std::istringstream is( itsNodes.top().node->value() );
639  is >> value;
640  if( std::fpclassify( value ) != FP_SUBNORMAL )
641  throw;
642  }
643  }
644 
646  void loadValue( long double & value )
647  {
648  try
649  {
650  value = std::stold( itsNodes.top().node->value() );
651  }
652  catch( std::out_of_range const & )
653  {
654  // special case for denormalized values
655  std::istringstream is( itsNodes.top().node->value() );
656  is >> value;
657  if( std::fpclassify( value ) != FP_SUBNORMAL )
658  throw;
659  }
660  }
661 
663  template<class CharT, class Traits, class Alloc> inline
664  void loadValue( std::basic_string<CharT, Traits, Alloc> & str )
665  {
666  std::basic_istringstream<CharT, Traits> is( itsNodes.top().node->value() );
667 
668  str.assign( std::istreambuf_iterator<CharT, Traits>( is ),
669  std::istreambuf_iterator<CharT, Traits>() );
670  }
671 
673  template <class T> inline
674  void loadSize( T & value )
675  {
676  value = getNumChildren( itsNodes.top().node );
677  }
678 
679  protected:
681  static size_t getNumChildren( rapidxml::xml_node<> * node )
682  {
683  size_t size = 0;
684  node = node->first_node(); // get first child
685 
686  while( node != nullptr )
687  {
688  ++size;
689  node = node->next_sibling();
690  }
691 
692  return size;
693  }
694 
696 
698  struct NodeInfo
699  {
700  NodeInfo( rapidxml::xml_node<> * n = nullptr ) :
701  node( n ),
702  child( n->first_node() ),
704  name( nullptr )
705  { }
706 
708 
709  void advance()
710  {
711  if( size > 0 )
712  {
713  --size;
714  child = child->next_sibling();
715  }
716  }
717 
719 
721  rapidxml::xml_node<> * search( const char * searchName )
722  {
723  if( searchName )
724  {
725  size_t new_size = XMLInputArchive::getNumChildren( node );
726  const size_t name_size = rapidxml::internal::measure( searchName );
727 
728  for( auto new_child = node->first_node(); new_child != nullptr; new_child = new_child->next_sibling() )
729  {
730  if( rapidxml::internal::compare( new_child->name(), new_child->name_size(), searchName, name_size, true ) )
731  {
732  size = new_size;
733  child = new_child;
734 
735  return new_child;
736  }
737  --new_size;
738  }
739  }
740 
741  return nullptr;
742  }
743 
745  const char * getChildName() const
746  {
747  return child ? child->name() : nullptr;
748  }
749 
752  size_t size;
753  const char * name;
754  }; // NodeInfo
755 
757 
758  private:
759  std::vector<char> itsData;
761  std::stack<NodeInfo> itsNodes;
762  };
763 
764  // ######################################################################
765  // XMLArchive prologue and epilogue functions
766  // ######################################################################
767 
768  // ######################################################################
770 
771  template <class T> inline
773  { }
774 
776  template <class T> inline
778  { }
779 
780  // ######################################################################
782 
783  template <class T> inline
785  { }
786 
788  template <class T> inline
790  { }
791 
792  // ######################################################################
794 
795  template <class T> inline
797  { }
798 
800  template <class T> inline
802  { }
803 
804  // ######################################################################
806 
807  template <class T> inline
809  { }
810 
812 
813  template <class T> inline
815  { }
816 
817  // ######################################################################
819 
820  template <class T> inline
821  void prologue( XMLOutputArchive & ar, SizeTag<T> const & )
822  {
823  if (ar.hasSizeAttributes())
824  {
825  ar.appendAttribute("size", "dynamic");
826  }
827  }
828 
829  template <class T> inline
831  { }
832 
834 
835  template <class T> inline
837  { }
838 
839  template <class T> inline
841  { }
842 
843  // ######################################################################
845 
851  void prologue( XMLOutputArchive & ar, T const & )
852  {
853  ar.startNode();
854  ar.insertType<T>();
855  }
856 
860  void prologue( XMLInputArchive & ar, T const & )
861  {
862  ar.startNode();
863  }
864 
865  // ######################################################################
867 
872  void epilogue( XMLOutputArchive & ar, T const & )
873  {
874  ar.finishNode();
875  }
876 
880  void epilogue( XMLInputArchive & ar, T const & )
881  {
882  ar.finishNode();
883  }
884 
885  // ######################################################################
886  // Common XMLArchive serialization functions
887  // ######################################################################
888 
890  template <class T> inline
892  {
893  ar.setNextName( t.name );
894  ar( t.value );
895  }
896 
898  template <class T> inline
900  {
901  ar.setNextName( t.name );
902  ar( t.value );
903  }
904 
905  // ######################################################################
907  template <class T> inline
909  { }
910 
912  template <class T> inline
914  {
915  ar.loadSize( st.size );
916  }
917 
918  // ######################################################################
922  {
923  ar.saveValue( t );
924  }
925 
929  {
930  ar.loadValue( t );
931  }
932 
933  // ######################################################################
935  template<class CharT, class Traits, class Alloc> inline
936  void CEREAL_SAVE_FUNCTION_NAME(XMLOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
937  {
938  ar.saveValue( str );
939  }
940 
942  template<class CharT, class Traits, class Alloc> inline
943  void CEREAL_LOAD_FUNCTION_NAME(XMLInputArchive & ar, std::basic_string<CharT, Traits, Alloc> & str)
944  {
945  ar.loadValue( str );
946  }
947 } // namespace cereal
948 
949 // register archives for polymorphic support
952 
953 // tie input and output archives together
955 
956 #endif // CEREAL_ARCHIVES_XML_HPP_
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25318
Main cereal functionality.
#define CEREAL_REGISTER_ARCHIVE(Archive)
Registers a specific Archive type with cereal.
Definition: cereal.hpp:195
A wrapper around data that should be serialized after all non-deferred data.
Definition: helpers.hpp:233
The base input archive class.
Definition: cereal.hpp:711
For holding name value pairs.
Definition: helpers.hpp:140
char const * name
Definition: helpers.hpp:167
Type value
Definition: helpers.hpp:168
The base output archive class.
Definition: cereal.hpp:319
A wrapper around size metadata.
Definition: helpers.hpp:313
Type size
Definition: helpers.hpp:326
An output archive designed to load data from XML.
Definition: xml.hpp:406
void finishNode()
Finishes reading the current node.
Definition: xml.hpp:508
static size_t getNumChildren(rapidxml::xml_node<> *node)
Gets the number of children (usually interpreted as size) for the specified node.
Definition: xml.hpp:681
std::stack< NodeInfo > itsNodes
A stack of nodes read from the document.
Definition: xml.hpp:761
void loadValue(int8_t &value)
Load an int8_t from the current top node (ensures we parse entire number)
Definition: xml.hpp:553
void setNextName(const char *name)
Sets the name for the next node created with startNode.
Definition: xml.hpp:528
const char * getNodeName() const
Definition: xml.hpp:522
void loadValue(std::basic_string< CharT, Traits, Alloc > &str)
Loads a string from the current node from the current top node.
Definition: xml.hpp:664
void loadValue(long double &value)
Loads a type best represented as a long double from the current top node.
Definition: xml.hpp:646
void startNode()
Prepares to start reading the next node.
Definition: xml.hpp:488
void loadBinaryValue(void *data, size_t size, const char *name=nullptr)
Loads some binary data, encoded as a base64 string, optionally specified by some name.
Definition: xml.hpp:454
XMLInputArchive(std::istream &stream)
Construct, reading in from the provided stream.
Definition: xml.hpp:417
std::vector< char > itsData
The raw data loaded.
Definition: xml.hpp:759
rapidxml::xml_document itsXML
The XML document.
Definition: xml.hpp:760
value
Loads a type best represented as an int from the current top node.
Definition: xml.hpp:639
void loadValue(T &value)
Loads a bool from the current top node.
Definition: xml.hpp:536
void loadSize(T &value)
Loads the size of the current top node.
Definition: xml.hpp:674
~XMLInputArchive() CEREAL_NOEXCEPT=default
void loadValue(uint8_t &value)
Load a uint8_t from the current top node (ensures we parse entire number)
Definition: xml.hpp:559
A class containing various advanced options for the XML archive.
Definition: xml.hpp:107
bool itsOutputType
Definition: xml.hpp:154
bool itsIndent
Definition: xml.hpp:153
Options & precision(int value)
Sets the precision used for floating point numbers.
Definition: xml.hpp:140
Options & sizeAttributes(bool enable)
Whether dynamically sized containers (e.g. vector) output the size=dynamic attribute.
Definition: xml.hpp:146
int itsPrecision
Definition: xml.hpp:152
Options & outputType(bool enable)
Whether to output the type of each serialized object as an attribute.
Definition: xml.hpp:144
Options & indent(bool enable)
Whether to indent each line of XML.
Definition: xml.hpp:142
static Options Default()
Default options.
Definition: xml.hpp:110
Options(int precision_=std::numeric_limits< double >::max_digits10, bool indent_=true, bool outputType_=false, bool sizeAttributes_=true)
Specify specific options for the XMLOutputArchive.
Definition: xml.hpp:117
bool itsSizeAttributes
Definition: xml.hpp:155
An output archive designed to save data to XML.
Definition: xml.hpp:97
rapidxml::xml_document itsXML
The XML document.
Definition: xml.hpp:358
void saveValue(int8_t const &value)
Overload for int8_t prevents them from being serialized as characters.
Definition: xml.hpp:291
bool itsSizeAttributes
Controls whether lists have a size attribute.
Definition: xml.hpp:363
~XMLOutputArchive() CEREAL_NOEXCEPT
Destructor, flushes the XML.
Definition: xml.hpp:189
void saveBinaryValue(const void *data, size_t size, const char *name=nullptr)
Saves some binary data, encoded as a base64 string, with an optional name.
Definition: xml.hpp:200
void saveValue(uint8_t const &value)
Overload for uint8_t prevents them from being serialized as characters.
Definition: xml.hpp:285
XMLOutputArchive(std::ostream &stream, Options const &options=Options::Default())
Construct, outputting to the provided stream upon destruction.
Definition: xml.hpp:163
void startNode()
Creates a new node that is a child of the node at the top of the stack.
Definition: xml.hpp:227
std::ostream & itsStream
The output stream.
Definition: xml.hpp:357
void insertType()
Causes the type to be appended as an attribute to the most recently made node if output type is set t...
Definition: xml.hpp:298
std::stack< NodeInfo > itsNodes
A stack of nodes added to the document.
Definition: xml.hpp:359
bool hasSizeAttributes() const
Definition: xml.hpp:320
bool itsOutputType
Controls whether type information is printed.
Definition: xml.hpp:361
std::ostringstream itsOS
Used to format strings internally.
Definition: xml.hpp:360
void saveValue(T const &value)
Saves some data, encoded as a string, into the current top level node.
Definition: xml.hpp:258
void setNextName(const char *name)
Sets the name for the next node created with startNode.
Definition: xml.hpp:248
void finishNode()
Designates the most recently added node as finished.
Definition: xml.hpp:242
bool itsIndent
Controls whether indenting is used.
Definition: xml.hpp:362
void appendAttribute(const char *name, const char *value)
Appends an attribute to the current top level node.
Definition: xml.hpp:313
xml_node< Ch > * allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
Definition: rapidxml.hpp:428
Ch * allocate_string(const Ch *source=0, std::size_t size=0)
Definition: rapidxml.hpp:489
xml_attribute< Ch > * allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
Definition: rapidxml.hpp:460
Definition: rapidxml.hpp:75
Ch * name() const
Definition: rapidxml.hpp:686
Definition: rapidxml.hpp:1372
void clear()
Definition: rapidxml.hpp:1428
void parse(Ch *text)
Definition: rapidxml.hpp:1394
Definition: rapidxml.hpp:904
void append_attribute(xml_attribute< Ch > *attribute)
Definition: rapidxml.hpp:1230
xml_node< Ch > * next_sibling(const Ch *name_=0, std::size_t name_size_=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1017
void append_node(xml_node< Ch > *child)
Definition: rapidxml.hpp:1110
xml_node< Ch > * first_node(const Ch *name_=0, std::size_t name_size_=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:949
#define CEREAL_NOEXCEPT
Defines the CEREAL_NOEXCEPT macro to use instead of noexcept.
Definition: macros.hpp:130
std::string decode(std::string const &encoded_string)
Definition: base64.hpp:89
std::string encode(unsigned char const *bytes_to_encode, size_t in_len)
Definition: base64.hpp:48
const int parse_no_data_nodes
Definition: rapidxml.hpp:168
const int print_no_indenting
Printer flag instructing the printer to suppress indenting of XML. See print() function.
Definition: rapidxml_print.hpp:23
@ node_declaration
A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalon...
Definition: rapidxml.hpp:155
@ node_data
A data node. Name is empty. Value contains data text.
Definition: rapidxml.hpp:152
@ node_element
An element node. Name contains element name. Value contains text of first data node.
Definition: rapidxml.hpp:151
const int parse_trim_whitespace
Definition: rapidxml.hpp:243
OutIt print(OutIt out, const xml_node< Ch > &node, int flags=0)
Definition: rapidxml_print.hpp:394
const int parse_declaration_node
Definition: rapidxml.hpp:205
bool isWhitespace(char c)
Returns true if the character is whitespace.
Definition: xml.hpp:61
static const char * CEREAL_XML_STRING
The name given to the root node in a cereal xml archive.
Definition: xml.hpp:58
in certain simple scenarios. They should probably not be used if maximizing performance is the main o...
Definition: access.hpp:42
void epilogue(JSONOutputArchive &, NameValuePair< T > const &)
Epilogue for NVPs for JSON archives.
Definition: json.hpp:780
std::enable_if< std::is_arithmetic< T >::value, void >::type CEREAL_LOAD_FUNCTION_NAME(BinaryInputArchive &ar, T &t)
Loading for POD types from binary.
Definition: binary.hpp:126
std::enable_if< std::is_arithmetic< T >::value, void >::type CEREAL_SAVE_FUNCTION_NAME(BinaryOutputArchive &ar, T const &t)
Saving for POD types to binary.
Definition: binary.hpp:118
void prologue(JSONOutputArchive &, NameValuePair< T > const &)
Prologue for NVPs for JSON archives.
Definition: json.hpp:768
Definition: json.hpp:5678
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
unsigned int uint32_t
Definition: stdint.h:126
signed int int32_t
Definition: stdint.h:123
unsigned char uint8_t
Definition: stdint.h:124
signed char int8_t
Definition: stdint.h:121
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:49
A struct that contains metadata about a node.
Definition: xml.hpp:699
size_t size
The remaining number of children for this node.
Definition: xml.hpp:752
rapidxml::xml_node * child
A pointer to its current child.
Definition: xml.hpp:751
rapidxml::xml_node * search(const char *searchName)
Searches for a child with the given name in this node.
Definition: xml.hpp:721
const char * name
The NVP name for next child node.
Definition: xml.hpp:753
void advance()
Advances to the next sibling node of the child.
Definition: xml.hpp:709
rapidxml::xml_node * node
A pointer to this node.
Definition: xml.hpp:750
NodeInfo(rapidxml::xml_node<> *n=nullptr)
Definition: xml.hpp:700
const char * getChildName() const
Returns the actual name of the next child node, if it exists.
Definition: xml.hpp:745
A struct that contains metadata about a node.
Definition: xml.hpp:325
rapidxml::xml_node * node
A pointer to this node.
Definition: xml.hpp:333
std::string getValueName()
Gets the name for the next child node created from this node.
Definition: xml.hpp:341
const char * name
The name for the next child node.
Definition: xml.hpp:335
size_t counter
The counter for naming child nodes.
Definition: xml.hpp:334
NodeInfo(rapidxml::xml_node<> *n=nullptr, const char *nm=nullptr)
Definition: xml.hpp:326
Type traits only struct used to mark an archive as human readable (text based)
Definition: traits.hpp:1321
#define CEREAL_SETUP_ARCHIVE_TRAITS(InputArchive, OutputArchive)
Sets up traits that relate an input archive to an output archive.
Definition: traits.hpp:169
static const detail::sfinae sfinae
Used as the default value for EnableIf and DisableIf template parameters.
Definition: traits.hpp:88
Internal misc utilities.
#define CEREAL_XML_STRING_VALUE
The default name for the root node in a cereal xml archive.
Definition: xml.hpp:54
#define const
Definition: zconf.h:233