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

s11n_node.hpp

Go to the documentation of this file.
00001 #ifndef s11n_S11N_NODE_HPP_INCLUDED
00002 #define s11n_S11N_NODE_HPP_INCLUDED
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // s11n_node.hpp
00006 // A reference implementation for s11n's Data Node concept.
00007 // License: Public Domain
00008 // Author: stephan@s11n.net
00009 ////////////////////////////////////////////////////////////////////////
00010 #include <string>
00011 #include <map>
00012 
00013 #include <vector>
00014 #include <s11n.net/s11n/variant.hpp> // for lexical casting
00015 #include <s11n.net/s11n/export.hpp>
00016 
00017 namespace s11n {
00018 
00019     /**
00020        s11n_node is a slightly lighter-weight replacement for
00021        the data_node type used in s11n 1.0.x. It will become
00022        the standard node type for s11nlite in 1.1/1.2.
00023         */
00024         class S11N_EXPORT_API s11n_node
00025         {
00026         public:
00027 
00028                 /**
00029                    The map type this object uses to store properties.
00030                  */
00031         typedef std::map < std::string, std::string > map_type;
00032 
00033                 /**
00034                    A pair type used to store key/value properties
00035                    internally.
00036                 */
00037         typedef map_type::value_type value_type;
00038 
00039                 /** The type used to store property keys. For
00040                     compatibility with std::map.
00041                 */
00042                 typedef map_type::key_type key_type; 
00043 
00044                 /** The type used to internally store property
00045                     values. For compatibility with std::map.
00046                 */
00047                 typedef map_type::mapped_type mapped_type;
00048 
00049                 /**
00050                    The container type used to store this object's children.
00051                    It contains (s11n_node *).
00052 
00053                    While the exact type is not guaranteed, it is
00054                    guaranteed to obey the most-commonly-used
00055                    std::list/vector conventions: push_back(), erase(),
00056                    etc.
00057                 */
00058         typedef std::vector<s11n_node *> child_list_type;
00059 
00060 
00061                 /**
00062                    Creates a new node with an empty name() and an
00063                    class_name() of "s11n::s11n_node". This
00064                    node is functionally useless until it's name is
00065                    set, as nodes with empty names are not supported by
00066                    any current i/o parsers.
00067                 */
00068                 s11n_node();
00069 
00070                 /**
00071                    Creates a new node with the given name() and an
00072                    class_name() of "s11n::s11n_node".
00073                 */
00074         explicit s11n_node( const std::string & name );
00075 
00076                 /**
00077                    Creates a new node with the given name() and and class_name().
00078 
00079                    Does not throw.
00080                 */
00081                 s11n_node( const std::string & name, const std::string implclass );
00082 
00083                 /**
00084                    Destroys all child objects owned by this object, freeing up
00085                    their resources.
00086 
00087                    Does not throw.
00088                 */
00089                 ~s11n_node();
00090 
00091         /**
00092            Swaps all publically-visible internal state with
00093            rhs. This includes:
00094 
00095            - class_name()
00096            - name()
00097            - children()
00098            - properties()
00099 
00100            Complexity is, in theory, constant time.  For all
00101            data we use their member swap() implementations,
00102            which should be constant-time for the
00103            containers. The C++ Standard apparently guarantees
00104            O(1) swap() for strings, too.  (Josuttis, The C++
00105            Standard Library, section 11.2.8, page 490.)
00106 
00107            Added in version 1.1.3.
00108         */
00109         void swap( s11n_node & rhs );
00110 
00111                 /**
00112                    Copies the properties, name, class name and
00113                    children of rhs. If rhs is this object then this
00114                    function does nothing.
00115 
00116                    Does not throw.
00117                 */
00118                 s11n_node & operator=( const s11n_node & rhs );
00119 
00120                 /**
00121                    See copy().
00122 
00123                    Does not throw.
00124                 */
00125                 s11n_node( const s11n_node & rhs );
00126 
00127         /**
00128                    Returns a list of the s11n_node children of this
00129                    object. The caller should not delete any pointers
00130                    from this list unless he also removes the pointers
00131                    from the list, or else they will get double-deleted
00132                    later. In practice it is (almost) never necessary
00133                    for client code to manipulate this list directly.
00134                 */
00135                 child_list_type & children();
00136 
00137                 /**
00138                    The const form of children().
00139                  */
00140                 const child_list_type & children() const;
00141 
00142 
00143                 /**
00144                    Removes all properties and deletes all children from
00145                    this object, freeing up their resources.
00146                    
00147                    Any pointers to children of this object become
00148                    invalided by a call to this function (they get
00149                    deleted).
00150                 */
00151                 void clear();
00152 
00153 
00154                 /**
00155                    Defines the class name which should be used as the
00156                    implementation class when this node is
00157                    deserialize()d.
00158 
00159                    Client Serializable types should call this one time
00160                    from their serialize() method, <em>after</em> calling
00161                    the parent class' serialize() method (if indeed that
00162                    is called at all), passing it the name of their class,
00163                    <em>using the name expected by the classloader</em>. By convention
00164                    the class name is the same as it's C++ name, thus Serializable
00165                    class foo::FooBar should call:
00166 
00167 <pre>
00168 node.class_name( "foo::FooBar" );
00169 </pre>
00170 
00171           from it's serialize() function.
00172 
00173 
00174                   If classes to not set this then the serialized data
00175                   will not have a proper implementation class
00176                   name. That is likely to break deserialization.
00177 
00178           TODO: consider returning the old value,
00179           to simplify swap() operations.
00180 
00181           Added in 1.1.3.
00182                 */
00183         void class_name( const std::string & n );
00184 
00185 
00186                 /**
00187                    Returns the implementation class name set via
00188                    class_name().
00189                 */
00190                 std::string class_name() const;
00191 
00192         /**
00193                    The name which should be used as the key for
00194                    storing the node. This is normally translated to
00195                    something like an XML element name (e.g., &lt;name&gt;),
00196                    and should not contain spaces or other characters
00197                    which may not be usable as key names. To be safe,
00198                    stick to alphanumeric and underscores, starting
00199                    with a letter or underscore. (This class does no
00200                    enforce any naming conventions, but your data file
00201                    parsers very well may.)
00202                 */
00203         void name( const std::string & n );
00204 
00205         /**
00206                    Returns this node's name, as set via name(string).
00207                 */
00208         std::string name() const;
00209 
00210         /**
00211            Returns true if this object has no properties
00212            and no children. The name() and class_name()
00213            are *not* considered.
00214         */
00215         bool empty() const;
00216 
00217 
00218         /**
00219                    Lexically casts val to a string and stores it as a
00220                    property. If this type conversion is not possible
00221                    it will fail at compile time. A value-conversion
00222                    failure, on the other hand, is not caught at
00223                    compile time. T must support complementary
00224                    ostream<< and istream>> operators.
00225                  */
00226                 template < typename T >
00227                 void set( const std::string & key, const T & val )
00228         {
00229             this->m_map[key] = ::s11n::Detail::variant(val).str();
00230         }
00231 
00232         /**
00233                    Tries to get a property named key and lexically
00234                    cast it to type T. If this type conversion is not
00235                    possible it will fail at compile time. A
00236                    value-conversion failure, on the other hand, is not
00237                    caught at compile time. If value conversion fails,
00238                    or if the requested property is not set, then
00239                    defaultval is returned. This can be interpretted as
00240                    an error value if the client so chooses, and it is
00241                    often helpful to pass a known-invalid value here
00242                    for that purpose.
00243 
00244                  */
00245         template < typename T >
00246                 T get( const std::string & key, const T & defaultval ) const
00247         {
00248                         map_type::const_iterator cit = this->m_map.find( key );
00249                         return ( this->m_map.end() == cit ) ? defaultval : ::s11n::Detail::variant( (*cit).second ).cast_to(defaultval);
00250         }
00251 
00252                 /**
00253                    Returns true if this object contains the given
00254                    property, else false.
00255                 */
00256         bool is_set( const std::string & key ) const;
00257 
00258                 /**
00259                    Removes the given property from this object.
00260                 */
00261         void unset( const std::string & key );
00262 
00263         /**
00264            Returns the map of properties contained by this
00265            node.
00266         */
00267                 map_type & properties();
00268 
00269         /** Const overload. */
00270                 const map_type & properties() const;
00271 
00272         private:
00273         std::string m_name; // name of this node
00274         std::string m_iname; // class_name name of this node
00275         map_type m_map; // stores key/value properties.
00276         child_list_type m_children; // holds child pointers
00277 
00278                 /**
00279                    Copies all properties and child s11n_nodes from
00280                    rhs into this object, as well as any other details
00281                    which need to be copied.
00282 
00283                    This can be a very expensive operation, and is rarely
00284                    necessary.
00285                 */
00286                 void copy( const s11n_node & rhs );
00287 
00288         /**
00289                    Removes all property entries from this object.
00290                  */
00291         void clear_properties();
00292 
00293         /**
00294                    Removes all children from this object, deleting all
00295                    child pointers.
00296                  */
00297                 void clear_children();
00298 
00299     }; // class s11n_node
00300 
00301 } // namespace s11n
00302 
00303 #endif // s11n_S11N_NODE_HPP_INCLUDED

Generated on Sun Dec 18 18:38:03 2005 for libs11n-1.2.2 by  doxygen 1.4.4