1 /* 2 * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org) 3 * All Rights Reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 3. Neither the name of the Author nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 23 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /** 34 @file 35 36 This file contains the definition of the xml::attributes class. 37 */ 38 39 #ifndef _xmlwrapp_attributes_h_ 40 #define _xmlwrapp_attributes_h_ 41 42 // xmlwrapp includes 43 #include "xmlwrapp/init.h" 44 #include "xmlwrapp/export.h" 45 46 // standard includes 47 #include <cstddef> 48 #include <iosfwd> 49 #include <string> 50 51 namespace xml 52 { 53 54 // forward declarations 55 class node; 56 57 namespace impl 58 { 59 class ait_impl; 60 struct node_impl; 61 } 62 63 /** 64 The xml::attributes class is used to access all the attributes of one 65 xml::node. You can add, find and erase attributes by name, and for some 66 member functions, use the provided iterator classes. 67 68 The iterator classes allow you to access one XML attribute. This is done 69 using the xml::attributes::attr class interface. 70 */ 71 class XMLWRAPP_API attributes 72 { 73 public: 74 /// size type 75 typedef std::size_t size_type; 76 77 /** 78 Create a new xml::attributes object with no attributes. 79 */ 80 attributes(); 81 82 /** 83 Copy construct a xml::attributes object. 84 85 @param other The xml::attributes object to copy from. 86 */ 87 attributes(const attributes& other); 88 89 /** 90 Copy the given xml::attributes object into this one. 91 92 @param other The xml::attributes object to copy from. 93 @return *this. 94 */ 95 attributes& operator=(const attributes& other); 96 97 /** 98 Swap this xml::attributes object with another one. 99 100 @param other The other xml::attributes object to swap with. 101 */ 102 void swap(attributes& other); 103 104 ~attributes(); 105 106 // forward declarations 107 class const_iterator; 108 109 /** 110 The xml::attributes::attr class is used to hold information about one 111 attribute. 112 */ 113 class attr 114 { 115 public: 116 /** 117 Get the name of this attribute. 118 119 @return The name for this attribute. 120 */ 121 const char *get_name() const; 122 123 /** 124 Get the value of this attribute. 125 126 @return The value for this attribute. 127 */ 128 const char* get_value() const; 129 130 private: 131 void *node_; 132 void *prop_; 133 std::string name_; 134 mutable std::string value_; 135 136 attr(); 137 attr(const attr& other); 138 attr& operator=(const attr& other); 139 void swap(attr& other); 140 141 void set_data(void *node, void *prop); 142 void set_data(const char *name, const char *value, bool); 143 144 friend class impl::ait_impl; 145 }; 146 147 /** 148 Iterator class for accessing attribute pairs. 149 */ 150 class iterator 151 { 152 public: 153 typedef attr value_type; 154 typedef std::ptrdiff_t difference_type; 155 typedef value_type* pointer; 156 typedef value_type& reference; 157 typedef std::forward_iterator_tag iterator_category; 158 159 iterator(); 160 iterator(const iterator& other); 161 iterator& operator=(const iterator& other); 162 ~iterator(); 163 164 reference operator*() const; 165 pointer operator->() const; 166 167 /// prefix increment 168 iterator& operator++(); 169 170 /// postfix increment (avoid if possible for better performance) 171 iterator operator++(int); 172 173 friend bool XMLWRAPP_API operator==(const iterator& lhs, const iterator& rhs); 174 friend bool XMLWRAPP_API operator!=(const iterator& lhs, const iterator& rhs); 175 176 private: 177 impl::ait_impl *pimpl_; 178 179 iterator(void *node, void *prop); 180 iterator(const char *name, const char *value, bool); 181 void swap(iterator& other); 182 void* get_raw_attr(); 183 184 friend class attributes; 185 friend class const_iterator; 186 }; 187 188 /** 189 Const Iterator class for accessing attribute pairs. 190 */ 191 class const_iterator 192 { 193 public: 194 typedef const attr value_type; 195 typedef std::ptrdiff_t difference_type; 196 typedef value_type* pointer; 197 typedef value_type& reference; 198 typedef std::forward_iterator_tag iterator_category; 199 200 const_iterator(); 201 const_iterator(const const_iterator& other); 202 const_iterator(const iterator& other); 203 const_iterator& operator=(const const_iterator& other); 204 ~const_iterator(); 205 206 reference operator*() const; 207 pointer operator->() const; 208 209 /// prefix increment 210 const_iterator& operator++(); 211 212 /// postfix increment (avoid if possible better for performance) 213 const_iterator operator++ (int); 214 215 friend bool XMLWRAPP_API operator== (const const_iterator &lhs, const const_iterator &rhs); 216 friend bool XMLWRAPP_API operator!= (const const_iterator &lhs, const const_iterator &rhs); 217 218 private: 219 impl::ait_impl *pimpl_; 220 221 const_iterator(void *node, void *prop); 222 const_iterator(const char *name, const char *value, bool); 223 void swap(const_iterator &other); 224 void* get_raw_attr(); 225 226 friend class attributes; 227 }; 228 229 /** 230 Get an iterator that points to the first attribute. 231 232 @return An iterator that points to the first attribute. 233 @return An iterator equal to end() if there are no attributes. 234 @see xml::attributes::iterator 235 @see xml::attributes::attr 236 */ 237 iterator begin(); 238 239 /** 240 Get a const_iterator that points to the first attribute. 241 242 @return A const_iterator that points to the first attribute. 243 @return A const_iterator equal to end() if there are no attributes. 244 @see xml::attributes::const_iterator 245 @see xml::attributes::attr 246 */ 247 const_iterator begin() const; 248 249 /** 250 Get an iterator that points one past the the last attribute. 251 252 @return An "end" iterator. 253 */ 254 iterator end(); 255 256 /** 257 Get a const_iterator that points one past the last attribute. 258 259 @return An "end" const_iterator. 260 */ 261 const_iterator end() const; 262 263 /** 264 Add an attribute to the attributes list. If there is another 265 attribute with the same name, it will be replaced with this one. 266 267 @param name The name of the attribute to add. 268 @param value The value of the attribute to add. 269 */ 270 void insert(const char *name, const char *value); 271 272 /** 273 Find the attribute with the given name. If the attribute is not found 274 on the current node, the DTD will be searched for a default value. 275 This is, of course, if there was a DTD parsed with the XML document. 276 277 @param name The name of the attribute to find. 278 @return An iterator that points to the attribute with the given name. 279 @return If the attribute was not found, find will return end(). 280 @see xml::attributes::iterator 281 @see xml::attributes::attr 282 */ 283 iterator find(const char *name); 284 285 /** 286 Find the attribute with the given name. If the attribute is not found 287 on the current node, the DTD will be searched for a default value. 288 This is, of course, if there was a DTD parsed with the XML document. 289 290 @param name The name of the attribute to find. 291 @return A const_iterator that points to the attribute with the given name. 292 @return If the attribute was not found, find will return end(). 293 @see xml::attributes::const_iterator 294 @see xml::attributes::attr 295 */ 296 const_iterator find(const char *name) const; 297 298 /** 299 Erase the attribute that is pointed to by the given iterator. This 300 will invalidate any iterators for this attribute, as well as any 301 pointers or references to it. 302 303 @param to_erase An iterator that points to the attribute to erased. 304 @return An iterator that points to the attribute after the one to be erased. 305 @see xml::attributes::iterator 306 @see xml::attributes::attr 307 */ 308 iterator erase(iterator to_erase); 309 310 /** 311 Erase the attribute with the given name. This will invalidate any 312 iterators that are pointing to that attribute, as well as any 313 pointers or references to that attribute. 314 315 @param name The name of the attribute to erase. 316 */ 317 void erase(const char *name); 318 319 /** 320 Find out if there are any attributes in this xml::attributes object. 321 322 @return True if there are no attributes. 323 @return False if there is at least one attribute. 324 */ 325 bool empty() const; 326 327 /** 328 Find out how many attributes there are in this xml::attributes 329 object. 330 331 @return The number of attributes in this xml::attributes object. 332 */ 333 size_type size() const; 334 335 private: 336 struct pimpl; pimpl *pimpl_; 337 338 // private ctor to create uninitialized instance 339 explicit attributes (int); 340 341 void set_data (void *node); 342 void* get_data(); 343 friend struct impl::node_impl; 344 friend class node; 345 }; 346 347 } // namespace xml 348 349 #endif // _xmlwrapp_attributes_h_ 350