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