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

Generated on Sat Mar 20 12:29:24 2010 for libs11n-1.2.10 by  doxygen 1.6.1