tag.cpp

00001 /*
00002   Copyright (c) 2005 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "tag.h"
00015 
00016 namespace gloox
00017 {
00018   Tag::Tag()
00019   : m_parent( 0 ), m_type( STANZA_UNDEFINED )
00020   {
00021   }
00022 
00023   Tag::Tag( const std::string& name, const std::string& cdata )
00024   : m_name( name ), m_cdata( escape( cdata ) ), m_parent( 0 ), m_type( STANZA_UNDEFINED )
00025   {
00026   }
00027 
00028   Tag::Tag( Tag *parent, const std::string& name, const std::string& cdata )
00029   : m_name( name ), m_cdata( escape( cdata ) ), m_parent( parent ), m_type( STANZA_UNDEFINED )
00030   {
00031     m_parent->addChild( this );
00032   }
00033 
00034   Tag::~Tag()
00035   {
00036     TagList::iterator it = m_children.begin();
00037     for( ; it != m_children.end(); ++it )
00038     {
00039       delete( (*it) );
00040       (*it) = 0;
00041     }
00042     m_children.clear();
00043   }
00044 
00045   void Tag::setCData( const std::string& cdata )
00046   {
00047     m_cdata = escape( cdata );
00048   }
00049 
00050   void Tag::addCData( const std::string& cdata )
00051   {
00052     m_cdata += escape( cdata );
00053   }
00054 
00055   const std::string Tag::xml() const
00056   {
00057     std::string xml;
00058     xml = "<" + m_name;
00059     if( m_attribs.size() )
00060     {
00061       StringMap::const_iterator it_a = m_attribs.begin();
00062       for( ; it_a != m_attribs.end(); ++it_a )
00063       {
00064         xml += " " + (*it_a).first + "='" + (*it_a).second + "'";
00065       }
00066     }
00067 
00068     if( m_cdata.empty() && !m_children.size() )
00069       xml += "/>";
00070     else if( m_children.size() )
00071     {
00072       xml += ">";
00073       TagList::const_iterator it_c = m_children.begin();
00074       for( ; it_c != m_children.end(); ++it_c )
00075       {
00076         xml += (*it_c)->xml();
00077       }
00078       xml += "</" + m_name + ">";
00079     }
00080     else if( !m_cdata.empty() )
00081       xml += ">" + m_cdata + "</" + m_name + ">";
00082 
00083     return xml;
00084   }
00085 
00086   void Tag::addAttrib( const std::string& name, const std::string& value )
00087   {
00088     if( !value.empty() )
00089       m_attribs[name] = value;
00090   }
00091 
00092   void Tag::addChild( Tag *child )
00093   {
00094     if( child )
00095     {
00096       m_children.push_back( child );
00097       child->m_parent = this;
00098     }
00099   }
00100 
00101   std::string Tag::cdata() const
00102   {
00103     return relax( m_cdata );
00104   }
00105 
00106   StringMap& Tag::attributes()
00107   {
00108     return m_attribs;
00109   }
00110 
00111   Tag::TagList& Tag::children()
00112   {
00113     return m_children;
00114   }
00115 
00116   const std::string Tag::findAttribute( const std::string& name ) const
00117   {
00118     StringMap::const_iterator it = m_attribs.find( name );
00119     if( it != m_attribs.end() )
00120       return (*it).second;
00121     else
00122       return "";
00123   }
00124 
00125   bool Tag::hasAttribute( const std::string& name, const std::string& value ) const
00126   {
00127     if( name.empty() )
00128       return true;
00129 
00130     StringMap::const_iterator it = m_attribs.find( name );
00131     if( it != m_attribs.end() )
00132       return ( ( value.empty() )?( true ):( (*it).second == value ) );
00133     else
00134       return false;
00135   }
00136 
00137   Tag* Tag::findChild( const std::string& name )
00138   {
00139     TagList::const_iterator it = m_children.begin();
00140     for( ; it != m_children.end(); ++it )
00141     {
00142       if( (*it)->name() == name )
00143         return (*it);
00144     }
00145 
00146     return 0;
00147   }
00148 
00149   bool Tag::hasChild( const std::string& name,
00150                       const std::string& attr, const std::string& value ) const
00151   {
00152     TagList::const_iterator it = m_children.begin();
00153     for( ; it != m_children.end(); ++it )
00154     {
00155       if( ( (*it)->name() == name )
00156               && (*it)->hasAttribute( attr, value ) )
00157         return true;
00158     }
00159 
00160     return false;
00161   }
00162 
00163   bool Tag::hasChildWithCData( const std::string& name, const std::string& cdata ) const
00164   {
00165     TagList::const_iterator it = m_children.begin();
00166     for( ; it != m_children.end(); ++it )
00167     {
00168       if( ( (*it)->name() == name ) && !cdata.empty() && ( (*it)->cdata() == cdata ) )
00169         return true;
00170       else if( ( (*it)->name() == name ) && cdata.empty() )
00171         return true;
00172     }
00173 
00174     return false;
00175   }
00176 
00177   bool Tag::hasChildWithAttrib( const std::string& attr, const std::string& value ) const
00178   {
00179     TagList::const_iterator it = m_children.begin();
00180     for( ; it != m_children.end(); ++it )
00181     {
00182       if( (*it)->hasAttribute( attr, value ) )
00183         return true;
00184     }
00185 
00186     return false;
00187   }
00188 
00189   Tag* Tag::findChildWithAttrib( const std::string& attr, const std::string& value )
00190   {
00191     TagList::const_iterator it = m_children.begin();
00192     for( ; it != m_children.end(); ++it )
00193     {
00194       if( (*it)->hasAttribute( attr, value ) )
00195         return (*it);
00196     }
00197 
00198     return 0;
00199   }
00200 
00201   const std::string Tag::replace( const std::string& what, const Duo& duo ) const
00202   {
00203     std::string esc = what;
00204     Duo::const_iterator it = duo.begin();
00205     for( ; it != duo.end(); ++it )
00206     {
00207       size_t lookHere = 0;
00208       size_t foundHere;
00209       while( ( foundHere = esc.find( (*it).first, lookHere ) ) != std::string::npos )
00210       {
00211         esc.replace( foundHere, (*it).first.size(), (*it).second );
00212         lookHere = foundHere + (*it).second.size();
00213       }
00214     }
00215     return esc;
00216   }
00217 
00218   const std::string Tag::escape( const std::string& what ) const
00219   {
00220     Duo d;
00221     d.push_back( duo( "&", "&amp;" ) );
00222     d.push_back( duo( "<", "&lt;" ) );
00223     d.push_back( duo( ">", "&gt;" ) );
00224     d.push_back( duo( "'", "&apos;" ) );
00225     d.push_back( duo( "\"", "&quot;" ) );
00226 
00227     return replace( what, d );
00228   }
00229 
00230   const std::string Tag::relax( const std::string& what ) const
00231   {
00232     Duo d;
00233     d.push_back( duo( "&lt;", "<" ) );
00234     d.push_back( duo( "&gt;", ">" ) );
00235     d.push_back( duo( "&apos;", "'" ) );
00236     d.push_back( duo( "&quot;", "\"" ) );
00237     d.push_back( duo( "&amp;", "&" ) );
00238 
00239     return replace( what, d );
00240   }
00241 
00242   Tag* Tag::clone()
00243   {
00244     Tag *t = new Tag( name(), cdata() );
00245     t->m_attribs = m_attribs;
00246 
00247     Tag::TagList::const_iterator it = m_children.begin();
00248     for( ; it != m_children.end(); ++it )
00249     {
00250       t->addChild( (*it)->clone() );
00251     }
00252 
00253     return t;
00254   }
00255 
00256 }

Generated on Mon Jan 16 16:19:54 2006 for gloox by  doxygen 1.4.6