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., <name>), 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