Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members

data_node.h

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&lt;SerializableType&gt;, 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., &lt;name&gt;),
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

Generated on Thu Jun 16 16:18:12 2005 for s11n by  doxygen 1.4.3-20050530