00001 // data_node.h 00002 // License: Public Domain 00003 // Author: stephan@s11n.net 00004 00005 00006 // EVERYTHING IN THIS FILE IS EXPERIMENTAL. 00007 // EVERYTHING IN THIS FILE IS EXPERIMENTAL. 00008 // EVERYTHING IN THIS FILE IS EXPERIMENTAL. 00009 // EVERYTHING IN THIS FILE IS EXPERIMENTAL. 00010 // EVERYTHING IN THIS FILE IS EXPERIMENTAL. 00011 // EVERYTHING IN THIS FILE IS EXPERIMENTAL. 00012 00013 #ifndef s11n_DATA_NODE_H_INCLUDED 00014 #define s11n_DATA_NODE_H_INCLUDED 00015 00016 #include <string> 00017 #include <map> 00018 00019 #define CHILDREN_USE_LIST 0 00020 #if CHILDREN_USE_LIST 00021 # include <list> 00022 #else 00023 # include <vector> 00024 #endif // CHILDREN_USE_LIST 00025 00026 #include <cassert> 00027 #include <typeinfo> 00028 00029 // #include <functional> // equal_to 00030 // #include <algorithm> // for_each() and friends 00031 00032 00033 #include <s11n/to_string.h> // to/from_string() 00034 #include <s11n/functor.h> // some helpful functors 00035 00036 namespace s11n { 00037 00038 // // template <typename P, typename L> struct basic_data_node; 00039 // template < 00040 // typename PropMapType = std::map<std::string,std::string>, 00041 // typename ChildListType = std::list< basic_data_node<PropMapType,ChildListType> *> 00042 // > 00043 // class basic_data_node 00044 // { 00045 // public: 00046 00047 // /** 00048 // The map type this object uses to store items 00049 // internally. 00050 // */ 00051 // typedef PropMapType map_type; 00052 00053 // /** 00054 // The pair type used to store key/value properties 00055 // internally. 00056 // */ 00057 // typedef typename map_type::value_type property_type; 00058 00059 // /** For compatibility with std::map */ 00060 // typedef typename map_type::key_type key_type; 00061 00062 // /** For compatibility with std::map */ 00063 // typedef typename map_type::mapped_type mapped_type; 00064 00065 // typedef typename map_type::iterator iterator; 00066 // typedef typename map_type::const_iterator const_iterator; 00067 00068 // typedef basic_data_node<map_type> this_type; 00069 00070 // typedef this_type child_type; 00071 00072 // typedef ChildListType child_list_type; 00073 00074 // basic_data_node() : m_name("s11nnode") {} 00075 // basic_data_node( const std::string & name ) : m_name(name) {} 00076 // ~basic_data_node() { this->clear(); } 00077 00078 // data_node( const data_node & rhs ) 00079 // { 00080 // this->copy( rhs ); 00081 // } 00082 // data_node & operator=( const data_node & rhs ) 00083 // { 00084 // if( &rhs == this ) return *this; 00085 // this->copy( rhs ); 00086 // return *this; 00087 // } 00088 00089 // child_list_type & children() 00090 // { 00091 // return this->m_children; 00092 // } 00093 00094 // const child_list_type & children() const 00095 // { 00096 // return this->m_children; 00097 // } 00098 00099 // /** 00100 // Removes all properties and deletes all child objects. 00101 // */ 00102 // void clear() 00103 // { 00104 // this->m_map.clear(); 00105 // free_list_entries( this->children().begin() ); 00106 // this->children().clear(); 00107 // } 00108 // /** Copies rhs's properties and deep-copies rhs's child pointers. */ 00109 // void copy( const data_node & rhs ) 00110 // { 00111 // if ( &rhs == this ) return; 00112 // this->clear(); 00113 // this->name( rhs.name() ); 00114 // this->impl_class( rhs.impl_class() ); 00115 // std::copy( rhs.begin(), rhs.end(), 00116 // std::insert_iterator<map_type>( this->m_map, this->m_map.begin() ) 00117 // ); 00118 // std::for_each( rhs.children().begin(), 00119 // rhs.children().end(), 00120 // child_pointer_deep_copier<child_list_type>( this->children() ) 00121 // ); 00122 // } 00123 00124 // void impl_class( const std::string & n ) 00125 // { 00126 // this->m_implclass = n; 00127 // } 00128 // std::string impl_class() const 00129 // { 00130 // return this->m_implclass; 00131 // } 00132 00133 // void name( const std::string & n ) 00134 // { 00135 // this->m_name = n; 00136 // } 00137 00138 // std::string name() const 00139 // { 00140 // return this->m_name; 00141 // } 00142 00143 00144 00145 // void insert( iterator propit ) 00146 // { 00147 // this->m_map.insert( propit ); 00148 // } 00149 // void insert( child_type * child ) 00150 // { 00151 // if( ! child ) return; 00152 // this->children().push_back( child ); 00153 // } 00154 // void insert( child_list_type::iterator childit ) 00155 // { 00156 // if( ! (*childit) ) return; 00157 // this->children().insert( childit ); 00158 // } 00159 00160 00161 // // std::string get_string( const key_type & key, const mapped_type & defaultVal = mapped_type() ) const; 00162 // // void set_string( const key_type & key, const std::string & val ); 00163 00164 // void set( const key_type & key, const mapped_type & val ) 00165 // { 00166 // this->m_map[key] = val; 00167 // } 00168 // template < typename T > void set( const key_type & key, const T & val ) 00169 // { 00170 // this->set( key, from_string( to_string( val ), val ); 00171 // } 00172 00173 // mapped_type get( const key_type & key, const mapped_type & defaultval ) const 00174 // { 00175 // const_iterator mit = this->m_map.find( key ); 00176 // const_iterator met = this->m_map.end(); 00177 // if( met == mit ) return defaultval; 00178 // return (*mit).second; 00179 // } 00180 00181 // template < typename T > T get( const key_type & key, const T & defaultval ) const 00182 // { 00183 // return this->get( key, from_string( to_string( defaultval ), defaultval ); 00184 // } 00185 00186 // private: 00187 // map_type m_map; 00188 // child_list_type m_children; 00189 // std::string m_implclass; 00190 // std::string m_name; 00191 // }; // basic_data_node 00192 00193 00194 /** 00195 00196 data_node is the next generation of 00197 s11n::s11n_node. It is a pure container, without 00198 and de/serialization-related methods. It is 00199 non-polymorphic, in contrast to s11n_node. 00200 00201 It is purely experimental at this point. 00202 00203 This type is a reference implementation for the 00204 functionality required of data nodes by the s11n core 00205 framework. Any type which conforms to this class' 00206 interface/conventions should be usable by 00207 s11n::serialize() and related functions. 00208 00209 Common conventions for types "convetionally compatible" 00210 with data_node are listed below. 00211 00212 - Should not throw exceptions, especially in the 00213 ctors/dtor. 00214 00215 - Each node must have a name, accessible via name(), which 00216 "should" conform to common element naming conventions 00217 (alphanumeric/underscore). 00218 00219 - Must be default constructable via new() and it must be 00220 safely deletable via delete(). 00221 00222 - Must support deep copy operations, though specific 00223 optimizations (e.g. copy-on-write) are not excluded as long 00224 as their operation is transparent to client code. 00225 00226 - Owns all of it's child pointers, or at least does not require 00227 client code to delete them. 00228 00229 - Structured like a DOM element, with an arbitrary number 00230 of unique key/value pairs and an arbitrary number of child 00231 data_node objects (of the same base type as the parent 00232 node). 00233 00234 - Property key and value types must be i/ostreamable, so as 00235 to inherently support easy conversion between strings and 00236 arbitrary types such as PODs and std::string, as well 00237 as user-defined streamable types. 00238 00239 - Each node must have a proper impl_class() (documented at 00240 length elsewhere). 00241 00242 - Should follow common std::map-style conventions for getting/setting 00243 properties, in addition to any other (convenience) interface. 00244 The type should provide begin()/end() iterator accessors for 00245 the properties. 00246 00247 - Should support common std::list-style conventions for 00248 traversing child nodes. The conventional function for 00249 accessing the children list is named children(). 00250 00251 - Need not be polymorphic, but it may be so. 00252 00253 - Data nodes are not, by their nature, also Serializable 00254 (as such). Indeed, their whole purpose is store data for 00255 Serializable types. They ARE "serializable" in the sense 00256 that their key/value sets must be eventually convertable to 00257 some "external representation" (i.e., strings). 00258 00259 - Should not be implemented as template types, for 00260 usability and maintenance reasons. One exception might be 00261 to go STL-style, and define it as a class template, but 00262 provide a typedef or subclass/specialization for the 00263 "standard" variant (as is the case for std::string). The 00264 first prototype of this library thought it would be clever 00265 to use s11n_node<SerializableType>, but i can promise 00266 you that causes Coding Hell down the road in client code if 00267 you ever try to mix different SerializableTypes in the same 00268 code.) 00269 00270 00271 More specific conventions will be detailed later in the 00272 library manual. 00273 00274 */ 00275 class data_node 00276 { 00277 public: 00278 00279 /** 00280 The map type this object uses to store items 00281 internally. 00282 */ 00283 typedef std::map < std::string, std::string > map_type; 00284 00285 /** 00286 A pair type used to store key/value properties 00287 internally. 00288 */ 00289 typedef map_type::value_type value_type; 00290 00291 /** For compatibility with std::map */ 00292 typedef map_type::key_type key_type; 00293 00294 /** For compatibility with std::map */ 00295 typedef map_type::mapped_type mapped_type; 00296 00297 /** 00298 The container type used to store this object's children. 00299 It contains (data_node *). 00300 00301 While the exact type is not guaranteed, it is 00302 guaranteed to obey the most-commonly-used 00303 std::list/vector conventions: push_back(), erase(), 00304 etc. 00305 */ 00306 typedef std::vector<data_node *> child_list_type; 00307 00308 /** 00309 For iterating over properties using STL 00310 conventions. 00311 00312 Dereferences to a value_type object. 00313 */ 00314 typedef map_type::iterator iterator; 00315 00316 /** 00317 For iterating over properties using STL 00318 conventions. 00319 00320 Dereferences to a value_type object. 00321 */ 00322 typedef map_type::const_iterator const_iterator; 00323 00324 00325 /** 00326 Creates a new node with an empty name() and an 00327 impl_class() of "s11n::data_node". This 00328 node is functionally useless until it's name is 00329 set, as nodes with empty names are not supported by 00330 any current i/o parsers. 00331 */ 00332 data_node(); 00333 00334 /** 00335 Creates a new node with the given name() and an 00336 impl_class() of "s11n::data_node". 00337 */ 00338 explicit data_node( const std::string & name ); 00339 00340 /** 00341 Creates a new node with the given name() and and impl_class(). 00342 00343 Does not throw. 00344 */ 00345 data_node( const std::string & name, const std::string implclass ); 00346 00347 /** 00348 Destroys all child objects owned by this object, freeing up 00349 their resources. 00350 00351 Does not throw. 00352 */ 00353 ~data_node(); 00354 00355 /** 00356 See copy(). 00357 00358 Does not throw. 00359 */ 00360 data_node & operator=( const data_node & rhs ); 00361 00362 /** 00363 See copy(). 00364 00365 Does not throw. 00366 */ 00367 data_node( const data_node & rhs ); 00368 00369 /** 00370 Returns a list of the data_node children of this 00371 object. The caller should not delete any pointers 00372 from this list unless he also removes the pointers 00373 from the list, or else they will get double-deleted 00374 later. In practice it is (almost) never necessary 00375 for client code to manipulate this list directly. 00376 00377 See node_child_simple_formatter<> for a funcfor designed 00378 to quickly serialize lists such as this one. 00379 */ 00380 child_list_type & children(); 00381 00382 /** 00383 The const form of children(). 00384 */ 00385 const child_list_type & children() const; 00386 00387 00388 /** 00389 Removes all properties and deletes all children from 00390 this object, freeing up their resources. 00391 00392 Any pointers to children of this object become 00393 invalided by a call to this function (they get 00394 deleted). Since client code doesn't normally hold 00395 pointers to data_node children this should not be 00396 a practical problem. This is normally only used 00397 in test code, not client code. 00398 */ 00399 void clear(); 00400 /** older name for clear(). Deprecated. */ 00401 void reset() { this->clear(); } 00402 00403 00404 00405 /** 00406 Returns all children() with a name() matching the 00407 given string by inserting them into the given 00408 container, which must support: 00409 00410 push_back( const data_node * ) 00411 00412 The caller does NOT own the child pointers: they 00413 are still owned by this object. 00414 00415 This method is known to work with std::list and 00416 std::vector. 00417 00418 Complexity: basically linear, based on the number 00419 of children in this object and how many have the 00420 name nodename (more matches requires more 00421 insertions into the target container). 00422 00423 Note that constness will prohibit clients from modifying 00424 an established tree of data_nodes. This is in line with 00425 common usage of this class. If you want to modify nodes, 00426 do so before inserting them into a tree. 00427 00428 */ 00429 // template < typename ContainerType > 00430 // size_t children( const std::string & nodename, ContainerType & ctr ) const 00431 // { 00432 // // // todo: re-implement using copy_if() 00433 // data_node *ch = 0; 00434 // typedef data_node::child_list_type::const_iterator CIT; 00435 // CIT cit = this->children().begin(); 00436 // CIT cet = this->children().end(); 00437 // size_t count = 0; 00438 // for ( ; cit != cet; ++cit ) 00439 // { 00440 // ch = ( *cit ); 00441 // if ( ch->name() == nodename ) 00442 // { 00443 // ++count; 00444 // ctr.push_back( ch ); 00445 // } 00446 // } 00447 // return count; 00448 // } 00449 00450 00451 // /** 00452 // Returns the first child node with the given node 00453 // name, or NULL. The caller does not own the pointer. 00454 // */ 00455 // const data_node * child( const std::string & nodename ) const; 00456 00457 00458 /** 00459 Defines the class name which should be used as the 00460 implementation for the node when it is 00461 deserialize()d. 00462 00463 Client Serializable types should call this one time 00464 from their serialize() method, <em>after</em> calling 00465 the parent class' serialize() method (if indeed that 00466 is called at all), passing it the name of their class, 00467 <em>as it will be used by the classloader</em>. By convention 00468 the class name is the same as it's C++ name, thus Serializable 00469 class foo::FooBar should call: 00470 00471 <pre> 00472 node.impl_class( "foo::FooBar" ); 00473 </pre> 00474 from it's serialize() function. 00475 00476 00477 Historical note: the above call <em>should</em> be 00478 handled 100% transparently by this library. There 00479 are, however, legitimate use-cases which the 00480 template/macro-based solution cannot catch, so 00481 users are encouraged to set it manually, as 00482 described above. If you don't then you your 00483 serialized data will all have the same impl_class: 00484 probably that of the base-most Serializable 00485 class. That *will* break deserialization. 00486 */ 00487 void impl_class( const std::string & n ); 00488 00489 00490 /** 00491 Returns the implementation class name set via impl_class(). 00492 */ 00493 std::string impl_class() const; 00494 00495 /** 00496 The name which should be used as the key for 00497 storing the node. This is normally translated to 00498 something like an XML element name (e.g., <name>), 00499 and should not contain spaces or other characters 00500 which may not be usable as key names. To be safe, 00501 stick to alphanumeric and underscores, starting 00502 with a letter or underscore. (This class does no 00503 enforce any naming conventions, but your data file 00504 parsers certainly will.) 00505 */ 00506 void name( const std::string & n ); 00507 00508 /** 00509 Returns this node's name, as set via name(string). 00510 */ 00511 std::string name() const; 00512 00513 /** 00514 std::string propval = node["bar"] is functionally 00515 identical to node.get_string("bar"). 00516 00517 Unlike std::map and the like, calling this operator 00518 with a key which is not in the object does not 00519 create a new entry - it simply returns an empty 00520 string in that case. This behaviour is not a 00521 specific of the interface for purposes of data_node 00522 conventions. 00523 */ 00524 const mapped_type operator[] ( const key_type & key ) const; 00525 00526 /** 00527 Untested. 00528 00529 Returns a non-const reference to a property with 00530 the given key. If key does not exist a new entry is 00531 created. 00532 */ 00533 mapped_type & operator[] ( const key_type & key ); 00534 00535 00536 /** 00537 For compatibility with std::map. Inserts a 00538 value_type (i.e., pair) into this object. 00539 */ 00540 void insert( const value_type & ); 00541 00542 00543 /** 00544 * Returns the value for key, or defaultVal if the key 00545 * is not set. 00546 * 00547 * Maintenance note: this is the "master" 00548 * getter. Almost all other getXXX() functions call 00549 * this one, so do not call them from inside this 00550 * function. 00551 * 00552 */ 00553 std::string get_string( const std::string & key, const std::string & defaultVal = std::string() )const; 00554 00555 /** 00556 Sets the given key to the given value. 00557 See get_string(): same notes apply here. 00558 */ 00559 void set_string( const std::string & key, const std::string & val ); 00560 00561 /** 00562 See set_string(). This function is identical except 00563 that it converts val to string before saving it. If 00564 this type conversion is not possible it will fail 00565 at compile time. A value-conversion failure, on the 00566 other hand, is not caught at compile time. 00567 */ 00568 template < typename T > void set( const std::string & key, const T & val ) 00569 { 00570 this->set_string( key, s11n::to_string( val ) ); 00571 } 00572 00573 // /** 00574 // Returns true if this object has no properties and 00575 // no children, else false. 00576 // */ 00577 // bool empty() const; 00578 00579 /** 00580 The <const char *> variants of get() and set() are 00581 to help the developer avoid having to cast so much 00582 and to help out compilers which have mediocre 00583 template support. :/ 00584 */ 00585 void set( const char *key, const char *val ) 00586 { 00587 this->set_string( key, val ); 00588 } 00589 /** 00590 Overloaded for strings-via-streams reaons. 00591 */ 00592 void set( const std::string & key, const char *val ) 00593 { 00594 this->set_string( key, val ); 00595 } 00596 /** 00597 Overloaded for strings-via-streams reaons. 00598 */ 00599 void set( const char *key, const std::string & val ) 00600 { 00601 this->set_string( key, val ); 00602 } 00603 00604 /** 00605 See get_string(). This function is identical except 00606 that the returned string is converted to type T. If 00607 this type is not possible it will fail at compile 00608 time. A value-conversion failure, on the other 00609 hand, is not caught at compile time. If value 00610 conversion fails then defaultval is returned. This 00611 can be interpretted as an error value if the client 00612 so chooses, and it is often helpful to pass a 00613 known-invalid value here for that purpose. 00614 */ 00615 template < typename T > T 00616 get( const std::string & key, const T & defaultval ) const 00617 { 00618 std::string foo = this->get_string( key, s11n::to_string( defaultval ) ); 00619 return s11n::from_string( foo, defaultval ); 00620 } 00621 00622 /** 00623 get(): see <code>set( const char *, const char * )</code>. Same notes apply. 00624 */ 00625 std::string get( const char *key, const char *val ) const 00626 { 00627 return this->get_string( key, val ); 00628 } 00629 /** 00630 Overloaded for strings-via-streams reasons. 00631 */ 00632 std::string get( const std::string & key, const char *val ) const 00633 { 00634 return this->get_string( key, val ); 00635 } 00636 /** 00637 Overloaded for strings-via-streams reasons. 00638 */ 00639 std::string get( const char *key, const std::string & val ) const 00640 { 00641 return this->get_string( key, val ); 00642 } 00643 00644 00645 /** 00646 Returns true if this object contains the given 00647 property, else false. 00648 */ 00649 bool is_set( const std::string & key ) const; 00650 00651 /** 00652 Removes the given property from this object. 00653 */ 00654 void unset( const std::string & key ); 00655 00656 /** 00657 set_bool() is provided to work around a potential 00658 compiler warning: 00659 00660 <pre> 00661 props.set( "foo", false ); 00662 // ambiguous: may be bool, const char *, char, or even int :/ 00663 </pre> 00664 */ 00665 void set_bool( const std::string & key, bool val ); 00666 00667 /** 00668 get_bool(key) returns true if key's value is true, as 00669 evaluated by the static function bool_val(). 00670 */ 00671 bool get_bool( const std::string & key, bool defaultVal ) const; 00672 00673 00674 00675 /** 00676 * Returns the bool value of the passed string. 00677 * The following string values are considered equal to true: 00678 * 00679 * true, TRUE, True 00680 * yes, YES, Yes, y, Y 00681 * 1 00682 * 00683 * Anything else evaluates to false. 00684 * 00685 * Case IS significant! 00686 */ 00687 static bool bool_val( const std::string & key ); 00688 00689 00690 /** 00691 * Returns end() if the key is not in our map, otherise it returns 00692 * that iterator. Use the iterator's 'first' member to get the key 00693 * and 'second' to get at it's value. 00694 */ 00695 iterator find( const std::string & key ); 00696 00697 00698 /** 00699 * Returns the first item in the data map. 00700 * You can use this to iterate, STL-style: 00701 * <pre> 00702 * data_node::iterator it = node.begin(); 00703 * for( ; node.end() != it; ++it ) { ... } 00704 * </pre> 00705 * 00706 * Note that the iterator represents a 00707 * value_type (std::pair), so use (*it).first to get 00708 * the key and (*it).second to get the value. 00709 */ 00710 iterator begin(); 00711 00712 /** 00713 Returns a const_iterator pointing at this object's 00714 first property. 00715 */ 00716 const_iterator begin() const; 00717 00718 /** 00719 * The after-the-end iterator for the data map. 00720 */ 00721 iterator end(); 00722 00723 /** 00724 * The after-the-end iterator for the data map. 00725 */ 00726 const_iterator end() const; 00727 00728 00729 /** 00730 * Returns the internally-used map_type (see the typedefs). 00731 * It is safe to modify this directly. 00732 */ 00733 map_type & map(); 00734 00735 /** 00736 * Returns the internally-used map_type (see the typedefs). 00737 */ 00738 const map_type & map() const; 00739 00740 /** 00741 Returns the number of properties in this object. 00742 */ 00743 size_t size() const; 00744 00745 00746 private: 00747 map_type m_map; // stores key/value properties. 00748 std::string m_name; // name of this node 00749 std::string m_iname; // impl_class name of this node 00750 child_list_type m_children; // holds child pointers 00751 00752 /** 00753 Copies all properties and child data_nodes from 00754 rhs into this object, as well as any other details 00755 which need to be copied. 00756 00757 This can be a very expensive operation, and is rarely 00758 necessary. 00759 */ 00760 void copy( const data_node & rhs ); 00761 00762 private: 00763 /** 00764 Removes all property entries from this object. 00765 */ 00766 void clear_properties(); 00767 00768 /** 00769 Removes all children from this object, deleting all 00770 child pointers. 00771 */ 00772 void clear_children(); 00773 00774 00775 00776 00777 }; // class data_node 00778 00779 00780 00781 00782 }; // namespace s11n 00783 00784 #include <s11n/class_loader.h> // CL registration macros 00785 s11n_CLASSLOADER_REGISTER1(s11n::data_node); 00786 00787 00788 00789 #endif // s11n_DATA_NODE_H_INCLUDED