xmlwrapp
xmlwrapp/attributes.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org)
00003  * All Rights Reserved
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in
00013  *    the documentation and/or other materials provided with the
00014  *    distribution.
00015  * 3. Neither the name of the Author nor the names of its contributors
00016  *    may be used to endorse or promote products derived from this software
00017  *    without specific prior written permission.
00018  * 
00019  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00021  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00022  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
00023  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00026  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00029  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  */
00032 
00033 /**
00034     @file
00035 
00036     This file contains the definition of the xml::attributes class.
00037  */
00038 
00039 #ifndef _xmlwrapp_attributes_h_
00040 #define _xmlwrapp_attributes_h_
00041 
00042 // xmlwrapp includes
00043 #include "xmlwrapp/init.h"
00044 
00045 // standard includes
00046 #include <cstddef>
00047 #include <iosfwd>
00048 #include <string>
00049 
00050 namespace xml
00051 {
00052 
00053 // forward declarations
00054 class node;
00055 
00056 namespace impl
00057 {
00058 class ait_impl;
00059 struct node_impl;
00060 }
00061 
00062 /**
00063     The xml::attributes class is used to access all the attributes of one
00064     xml::node. You can add, find and erase attributes by name, and for some
00065     member functions, use the provided iterator classes.
00066 
00067     The iterator classes allow you to access one XML attribute. This is done
00068     using the xml::attributes::attr class interface.
00069  */
00070 class attributes
00071 {
00072 public:
00073     /// size type
00074     typedef std::size_t size_type;
00075 
00076     /**
00077         Create a new xml::attributes object with no attributes.
00078      */
00079     attributes();
00080 
00081     /**
00082         Copy construct a xml::attributes object.
00083 
00084         @param other The xml::attributes object to copy from.
00085      */
00086     attributes(const attributes& other);
00087 
00088     /**
00089         Copy the given xml::attributes object into this one.
00090 
00091         @param other The xml::attributes object to copy from.
00092         @return   *this.
00093      */
00094     attributes& operator=(const attributes& other);
00095 
00096     /**
00097         Swap this xml::attributes object with another one.
00098 
00099         @param other The other xml::attributes object to swap with.
00100      */
00101     void swap(attributes& other);
00102 
00103     ~attributes();
00104 
00105     // forward declarations
00106     class const_iterator;
00107 
00108     /**
00109         The xml::attributes::attr class is used to hold information about one
00110         attribute.
00111      */
00112     class attr
00113     {
00114     public:
00115         /**
00116             Get the name of this attribute.
00117 
00118             @return The name for this attribute.
00119          */
00120         const char *get_name() const;
00121 
00122         /**
00123             Get the value of this attribute.
00124 
00125             @return The value for this attribute.
00126          */
00127         const char* get_value() const;
00128 
00129     private:
00130         void *node_;
00131         void *prop_;
00132         std::string name_;
00133         mutable std::string value_;
00134 
00135         attr();
00136         attr(const attr& other);
00137         attr& operator=(const attr& other);
00138         void swap(attr& other);
00139 
00140         void set_data(void *node, void *prop);
00141         void set_data(const char *name, const char *value, bool);
00142 
00143         friend class impl::ait_impl;
00144     };
00145 
00146     /**
00147         Iterator class for accessing attribute pairs.
00148      */
00149     class iterator
00150     {
00151     public:
00152         typedef attr value_type;
00153         typedef std::ptrdiff_t difference_type;
00154         typedef value_type* pointer;
00155         typedef value_type& reference;
00156         typedef std::forward_iterator_tag iterator_category;
00157 
00158         iterator();
00159         iterator(const iterator& other);
00160         iterator& operator=(const iterator& other);
00161         ~iterator();
00162 
00163         reference operator*() const;
00164         pointer   operator->() const;
00165 
00166         /// prefix increment
00167         iterator& operator++();
00168 
00169         /// postfix increment (avoid if possible for better performance)
00170         iterator operator++(int);
00171 
00172         friend bool operator==(const iterator& lhs, const iterator& rhs);
00173         friend bool operator!=(const iterator& lhs, const iterator& rhs);
00174 
00175     private:
00176         impl::ait_impl *pimpl_;
00177 
00178         iterator(void *node, void *prop);
00179         iterator(const char *name, const char *value, bool);
00180         void swap(iterator& other);
00181         void* get_raw_attr();
00182 
00183         friend class attributes;
00184         friend class const_iterator;
00185     };
00186 
00187     /**
00188         Const Iterator class for accessing attribute pairs.
00189      */
00190     class const_iterator
00191     {
00192     public:
00193         typedef const attr value_type;
00194         typedef std::ptrdiff_t difference_type;
00195         typedef value_type* pointer;
00196         typedef value_type& reference;
00197         typedef std::forward_iterator_tag iterator_category;
00198 
00199         const_iterator();
00200         const_iterator(const const_iterator& other);
00201         const_iterator(const iterator& other);
00202         const_iterator& operator=(const const_iterator& other);
00203         ~const_iterator();
00204 
00205         reference operator*() const;
00206         pointer   operator->() const;
00207 
00208         /// prefix increment
00209         const_iterator& operator++();
00210 
00211         /// postfix increment (avoid if possible better for performance)
00212         const_iterator operator++ (int);
00213 
00214         friend bool operator== (const const_iterator &lhs, const const_iterator &rhs);
00215         friend bool operator!= (const const_iterator &lhs, const const_iterator &rhs);
00216 
00217     private:
00218         impl::ait_impl *pimpl_;
00219 
00220         const_iterator(void *node, void *prop);
00221         const_iterator(const char *name, const char *value, bool);
00222         void swap(const_iterator &other);
00223         void* get_raw_attr();
00224 
00225         friend class attributes;
00226     };
00227 
00228     /**
00229         Get an iterator that points to the first attribute.
00230 
00231         @return An iterator that points to the first attribute.
00232         @return An iterator equal to end() if there are no attributes.
00233         @see xml::attributes::iterator
00234         @see xml::attributes::attr
00235      */
00236     iterator begin();
00237 
00238     /**
00239         Get a const_iterator that points to the first attribute.
00240 
00241         @return A const_iterator that points to the first attribute.
00242         @return A const_iterator equal to end() if there are no attributes.
00243         @see xml::attributes::const_iterator
00244         @see xml::attributes::attr
00245      */
00246     const_iterator begin() const;
00247 
00248     /**
00249         Get an iterator that points one past the the last attribute.
00250 
00251         @return An "end" iterator.
00252      */
00253     iterator end();
00254 
00255     /**
00256         Get a const_iterator that points one past the last attribute.
00257 
00258         @return An "end" const_iterator.
00259      */
00260     const_iterator end() const;
00261 
00262     /**
00263         Add an attribute to the attributes list. If there is another
00264         attribute with the same name, it will be replaced with this one.
00265 
00266         @param name The name of the attribute to add.
00267         @param value The value of the attribute to add.
00268      */
00269     void insert(const char *name, const char *value);
00270 
00271     /**
00272         Find the attribute with the given name. If the attribute is not found
00273         on the current node, the DTD will be searched for a default value.
00274         This is, of course, if there was a DTD parsed with the XML document.
00275 
00276         @param name The name of the attribute to find.
00277         @return An iterator that points to the attribute with the given name.
00278         @return If the attribute was not found, find will return end().
00279         @see xml::attributes::iterator
00280         @see xml::attributes::attr
00281      */
00282     iterator find(const char *name);
00283 
00284     /**
00285         Find the attribute with the given name. If the attribute is not found
00286         on the current node, the DTD will be searched for a default value.
00287         This is, of course, if there was a DTD parsed with the XML document.
00288 
00289         @param name The name of the attribute to find.
00290         @return A const_iterator that points to the attribute with the given name.
00291         @return If the attribute was not found, find will return end().
00292         @see xml::attributes::const_iterator
00293         @see xml::attributes::attr
00294      */
00295     const_iterator find(const char *name) const;
00296 
00297     /**
00298         Erase the attribute that is pointed to by the given iterator. This
00299         will invalidate any iterators for this attribute, as well as any
00300         pointers or references to it.
00301 
00302         @param to_erase An iterator that points to the attribute to erased.
00303         @return An iterator that points to the attribute after the one to be erased.
00304         @see xml::attributes::iterator
00305         @see xml::attributes::attr
00306      */
00307     iterator erase(iterator to_erase);
00308 
00309     /**
00310         Erase the attribute with the given name. This will invalidate any
00311         iterators that are pointing to that attribute, as well as any
00312         pointers or references to that attribute.
00313 
00314         @param name The name of the attribute to erase.
00315      */
00316     void erase(const char *name);
00317 
00318     /**
00319         Find out if there are any attributes in this xml::attributes object.
00320 
00321         @return True if there are no attributes.
00322         @return False if there is at least one attribute.
00323      */
00324     bool empty() const;
00325 
00326     /**
00327         Find out how many attributes there are in this xml::attributes
00328         object.
00329 
00330         @return The number of attributes in this xml::attributes object.
00331      */
00332     size_type size() const;
00333 
00334 private:
00335     struct pimpl; pimpl *pimpl_;
00336 
00337     // private ctor to create uninitialized instance
00338     explicit attributes (int);
00339 
00340     void set_data (void *node);
00341     void* get_data();
00342     friend struct impl::node_impl;
00343     friend class node;
00344 };
00345 
00346 } // namespace xml
00347 
00348 #endif // _xmlwrapp_attributes_h_