tag.cpp

00001 /*
00002   Copyright (c) 2005-2006 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 #include <sstream>
00017 
00018 namespace gloox
00019 {
00020   Tag::Tag()
00021     : m_parent( 0 ), m_type( StanzaUndefined )
00022   {
00023   }
00024 
00025   Tag::Tag( const std::string& name, const std::string& cdata )
00026     : m_name( name ), m_cdata( escape( cdata ) ), m_parent( 0 ), m_type( StanzaUndefined )
00027   {
00028   }
00029 
00030   Tag::Tag( Tag *parent, const std::string& name, const std::string& cdata )
00031     : m_name( name ), m_cdata( escape( cdata ) ), m_parent( parent ), m_type( StanzaUndefined )
00032   {
00033     m_parent->addChild( this );
00034   }
00035 
00036   Tag::~Tag()
00037   {
00038     TagList::iterator it = m_children.begin();
00039     for( ; it != m_children.end(); ++it )
00040     {
00041       delete (*it);
00042       (*it) = 0;
00043     }
00044     m_children.clear();
00045   }
00046 
00047   void Tag::setCData( const std::string& cdata )
00048   {
00049     m_cdata = escape( cdata );
00050   }
00051 
00052   void Tag::addCData( const std::string& cdata )
00053   {
00054     m_cdata += escape( cdata );
00055   }
00056 
00057   const std::string Tag::xml() const
00058   {
00059     std::string xml;
00060     xml = "<" + m_name;
00061     if( m_attribs.size() )
00062     {
00063       StringMap::const_iterator it_a = m_attribs.begin();
00064       for( ; it_a != m_attribs.end(); ++it_a )
00065       {
00066         xml += " " + (*it_a).first + "='" + (*it_a).second + "'";
00067       }
00068     }
00069 
00070     if( m_cdata.empty() && !m_children.size() )
00071       xml += "/>";
00072     else if( m_children.size() )
00073     {
00074       xml += ">";
00075       TagList::const_iterator it_c = m_children.begin();
00076       for( ; it_c != m_children.end(); ++it_c )
00077       {
00078         xml += (*it_c)->xml();
00079       }
00080       xml += "</" + m_name + ">";
00081     }
00082     else if( !m_cdata.empty() )
00083       xml += ">" + m_cdata + "</" + m_name + ">";
00084 
00085     return xml;
00086   }
00087 
00088   void Tag::addAttribute( const std::string& name, const std::string& value )
00089   {
00090     if( !name.empty() && !value.empty() )
00091       m_attribs[name] = value;
00092   }
00093 
00094   void Tag::addAttribute( const std::string& name, int value )
00095   {
00096     if( !name.empty() )
00097     {
00098       std::ostringstream oss;
00099       oss << value;
00100       m_attribs[name] = oss.str();
00101     }
00102   }
00103 
00104   void Tag::addChild( Tag *child )
00105   {
00106     if( child )
00107     {
00108       m_children.push_back( child );
00109       child->m_parent = this;
00110     }
00111   }
00112 
00113   const std::string Tag::cdata() const
00114   {
00115     return relax( m_cdata );
00116   }
00117 
00118   StringMap& Tag::attributes()
00119   {
00120     return m_attribs;
00121   }
00122 
00123   Tag::TagList& Tag::children()
00124   {
00125     return m_children;
00126   }
00127 
00128   const std::string Tag::findAttribute( const std::string& name ) const
00129   {
00130     StringMap::const_iterator it = m_attribs.find( name );
00131     if( it != m_attribs.end() )
00132       return (*it).second;
00133     else
00134       return "";
00135   }
00136 
00137   bool Tag::hasAttribute( const std::string& name, const std::string& value ) const
00138   {
00139     if( name.empty() )
00140       return true;
00141 
00142     StringMap::const_iterator it = m_attribs.find( name );
00143     if( it != m_attribs.end() )
00144       return ( ( value.empty() )?( true ):( (*it).second == value ) );
00145     else
00146       return false;
00147   }
00148 
00149   Tag* Tag::findChild( const std::string& name )
00150   {
00151     TagList::const_iterator it = m_children.begin();
00152     for( ; it != m_children.end(); ++it )
00153     {
00154       if( (*it)->name() == name )
00155         return (*it);
00156     }
00157 
00158     return 0;
00159   }
00160 
00161   Tag* Tag::findChild( const std::string& name, const std::string& attr,
00162                        const std::string& value )
00163   {
00164     TagList::const_iterator it = m_children.begin();
00165     for( ; it != m_children.end(); ++it )
00166     {
00167       if( ( (*it)->name() == name ) && (*it)->hasAttribute( attr, value ) )
00168         return (*it);
00169     }
00170 
00171     return 0;
00172   }
00173 
00174   bool Tag::hasChild( const std::string& name,
00175                       const std::string& attr, const std::string& value ) const
00176   {
00177     if( name.empty() )
00178       return false;
00179 
00180     TagList::const_iterator it = m_children.begin();
00181     for( ; it != m_children.end(); ++it )
00182     {
00183       if( ( (*it)->name() == name )
00184               && (*it)->hasAttribute( attr, value ) )
00185         return true;
00186     }
00187 
00188     return false;
00189   }
00190 
00191   bool Tag::hasChildWithCData( const std::string& name, const std::string& cdata ) const
00192   {
00193     TagList::const_iterator it = m_children.begin();
00194     for( ; it != m_children.end(); ++it )
00195     {
00196       if( ( (*it)->name() == name ) && !cdata.empty() && ( (*it)->cdata() == cdata ) )
00197         return true;
00198       else if( ( (*it)->name() == name ) && cdata.empty() )
00199         return true;
00200     }
00201 
00202     return false;
00203   }
00204 
00205   bool Tag::hasChildWithAttrib( const std::string& attr, const std::string& value ) const
00206   {
00207     TagList::const_iterator it = m_children.begin();
00208     for( ; it != m_children.end(); ++it )
00209     {
00210       if( (*it)->hasAttribute( attr, value ) )
00211         return true;
00212     }
00213 
00214     return false;
00215   }
00216 
00217   Tag* Tag::findChildWithAttrib( const std::string& attr, const std::string& value )
00218   {
00219     TagList::const_iterator it = m_children.begin();
00220     for( ; it != m_children.end(); ++it )
00221     {
00222       if( (*it)->hasAttribute( attr, value ) )
00223         return (*it);
00224     }
00225 
00226     return 0;
00227   }
00228 
00229   const std::string Tag::replace( const std::string& what, const Duo& duo ) const
00230   {
00231     std::string esc = what;
00232     Duo::const_iterator it = duo.begin();
00233     for( ; it != duo.end(); ++it )
00234     {
00235       size_t lookHere = 0;
00236       size_t foundHere = 0;
00237       while( ( foundHere = esc.find( (*it).first, lookHere ) ) != std::string::npos )
00238       {
00239         esc.replace( foundHere, (*it).first.size(), (*it).second );
00240         lookHere = foundHere + (*it).second.size();
00241       }
00242     }
00243     return esc;
00244   }
00245 
00246   const std::string Tag::escape( const std::string& what ) const
00247   {
00248     Duo d;
00249     d.push_back( duo( "&", "&amp;" ) );
00250     d.push_back( duo( "<", "&lt;" ) );
00251     d.push_back( duo( ">", "&gt;" ) );
00252     d.push_back( duo( "'", "&apos;" ) );
00253     d.push_back( duo( "\"", "&quot;" ) );
00254 
00255     return replace( what, d );
00256   }
00257 
00258   const std::string Tag::relax( const std::string& what ) const
00259   {
00260     Duo d;
00261     d.push_back( duo( "&lt;", "<" ) );
00262     d.push_back( duo( "&gt;", ">" ) );
00263     d.push_back( duo( "&apos;", "'" ) );
00264     d.push_back( duo( "&quot;", "\"" ) );
00265     d.push_back( duo( "&amp;", "&" ) );
00266 
00267     return replace( what, d );
00268   }
00269 
00270   Tag* Tag::clone() const
00271   {
00272     Tag *t = new Tag( name(), cdata() );
00273     t->m_attribs = m_attribs;
00274 
00275     Tag::TagList::const_iterator it = m_children.begin();
00276     for( ; it != m_children.end(); ++it )
00277     {
00278       t->addChild( (*it)->clone() );
00279     }
00280 
00281     return t;
00282   }
00283 
00284 }

Generated on Sun Sep 24 21:57:32 2006 for gloox by  doxygen 1.4.7