SOAPElement.cpp

Go to the documentation of this file.
00001 
00010 // SOAPElement.cpp: implementation of the SOAPElement class.
00011 //
00013 #ifdef _MSC_VER 
00014 // Microsoft only extension to the compiler
00015 // Turns off noise about debug symbols being "too long".
00016     #pragma warning( disable : 4786 )
00017 #endif // _MSC_VER 
00018 #include <stdexcept>
00019 #include "SOAPElement.h"
00020 #include <iostream>
00021 
00023 // Construction/Destruction
00025 
00026 bool splitNamespaceAndName( const std::string& KszOriginal,
00027     std::string& szNamespace, std::string& szAccessor )
00028 {
00029     bool retval = KszOriginal.length() > 0;
00030 
00031     if ( retval )
00032     {
00033         long nColonPos = KszOriginal.find( ":" );
00034         if ( nColonPos != std::string::npos )
00035         {
00036             szNamespace = KszOriginal.substr( 0, nColonPos );
00037             szAccessor = KszOriginal.substr( nColonPos + 1, KszOriginal.length() - nColonPos - 1 );
00038         }
00039         else 
00040         {
00041             szNamespace = "";
00042             szAccessor = KszOriginal;
00043         }
00044     }
00045 
00046     return retval;
00047 }
00048 
00049 SOAPElement::SOAPElement()
00050 {
00051 
00052 }
00053 
00054 SOAPElement::~SOAPElement()
00055 {
00056         for(int i=0;i<numElements();i++) 
00057     {
00058         delete m_internalElements[i];
00059         }
00060 }
00061 
00062 
00063 SOAPElement::SOAPElement( const SOAPElement& rhs )
00064 {
00065     *this = rhs;
00066 }
00067 
00068 SOAPElement& SOAPElement::operator=( const SOAPElement& rhs )
00069 {
00070     m_szAccessorName = rhs.m_szAccessorName;
00071     m_szNamespace = rhs.m_szNamespace;
00072     m_szValue = rhs.m_szValue;
00073     m_attributes = rhs.m_attributes;
00074 
00075         //Change on 07/03/2001 by SM
00076         //Correct copy operator
00077 
00078         for(int i=0;i<rhs.numElements();i++) 
00079     {
00080         SOAPElement* pElement = new SOAPElement( *rhs.m_internalElements[i] );
00081         addElement( pElement );
00082         }
00083 
00084     return *this;
00085 }
00086 
00087 std::string& SOAPElement::accessorName()
00088 {
00089     return m_szAccessorName;
00090 }
00091 
00092 bool SOAPElement::addAttribute( SOAPAttribute theAttribute )
00093 {
00094     bool retval = true;
00095     m_attributes.push_back( theAttribute );
00096     return retval;
00097 }
00098 
00099 bool SOAPElement::getAttribute( const std::string& szAttributeName, SOAPAttribute& szValue )
00100 {
00101     bool retval = false;
00102 
00103     // I don't expect most SOAP messages to have large numbers of elements. If I did,
00104     // I would have used a map as well as a vector.
00105     std::string szAccessor;
00106     std::string szNamespace;
00107     splitNamespaceAndName( szAttributeName, szNamespace, szAccessor );
00108     for( AttributeContainer::iterator itElement = m_attributes.begin();
00109          itElement != m_attributes.end();
00110          ++itElement )
00111     {
00112         if ( itElement->accessor() == szAttributeName )
00113         {
00114             if ( szNamespace.empty() || ( itElement->namespaceName() == szNamespace ) )
00115             {
00116                 // We found the element.
00117                 szValue = *itElement;
00118                 retval = true;
00119                 break;
00120             }
00121         }
00122     }
00123 
00124     return retval;
00125 }
00126 
00127 bool SOAPElement::addElement( SOAPElement* pElement )
00128 {
00129     m_internalElements.push_back( pElement );
00130     return true;
00131 }
00132 
00133 bool SOAPElement::getElement( const std::string& szElementName,
00134     SOAPElement** pValue )
00135 {
00136     bool retval = false;
00137     *pValue = NULL;
00138 
00139     std::string szAccessor;
00140     std::string szNamespace;
00141     splitNamespaceAndName( szElementName, szNamespace, szAccessor );
00142 
00143     // I don't expect most SOAP messages to have large numbers of 
00144     // elements. If I did, I would have used a map as well as a
00145     // vector.  Map for name lookup, vector for positional lookup.  
00146         // Probably would store the element in a vector and map 
00147         // accessors to indices.
00148     for( ElementContainer::iterator itElement = 
00149             m_internalElements.begin();
00150          itElement != m_internalElements.end();
00151          ++itElement )
00152     {
00153         if ( (*itElement)->accessorName() == szElementName )
00154         {
00155             if ( szNamespace.empty() || 
00156                  ( (*itElement)->namespaceName() == szNamespace ) )
00157             {
00158                 // We found the element.
00159                 *pValue = *itElement;
00160                 retval = true;
00161                 break;
00162             }
00163         }
00164     }
00165 
00166     return retval;
00167 }
00168 
00169 std::string& SOAPElement::value()
00170 {
00171     return m_szValue;
00172 }
00173 
00174 long SOAPElement::numElements() const
00175 {
00176     return m_internalElements.size();
00177 }
00178 
00179 long SOAPElement::numAttributes()
00180 {
00181     return m_attributes.size();
00182 }
00183 
00184 SOAPElement& SOAPElement::elementAt( long index )
00185 {
00186     if ( ( numElements() <= index ) || ( 0 > index ) )
00187     {
00188         throw std::out_of_range( std::string( "Invalid index passed to SOAPElement::elementAt" ) );
00189     }
00190     return *m_internalElements[index];
00191 }
00192 
00193 SOAPAttribute& SOAPElement::attributeAt( long index )
00194 {
00195     if ( ( numAttributes() <= index ) || ( 0 > index ) )
00196     {
00197         throw std::out_of_range( std::string( "Invalid index passed to SOAPElement::attributeAt" ) );
00198     }
00199     return m_attributes[index];
00200 }
00201 
00202 std::string& SOAPElement::namespaceName()
00203 {
00204     return m_szNamespace;
00205 }
00206 
00207 void SOAPElement::serialize(std::ostringstream& stream)
00208 {
00209         serialize(stream, *this);
00210 }
00211 
00212 void SOAPElement::serialize(std::ostringstream& stream, SOAPElement& element)
00213 {
00214         // encode the element name
00215 
00216         stream << "<";
00217         if (element.m_szNamespace.size() > 0) {
00218                 stream << element.m_szNamespace << ":";
00219         }
00220         stream << element.m_szAccessorName << " ";
00221 
00222         // encode the element's attributes
00223     for (AttributeContainer::iterator itElement = m_attributes.begin(); itElement != m_attributes.end(); ++itElement) {
00224                 if (itElement->namespaceName().size() > 0) {
00225                         stream << itElement->namespaceName() << ":";
00226                 }
00227                 stream << itElement->accessor() << "=" << "\"" << itElement->value() << "\" ";
00228     }
00229 
00230         // terminate the element declaration
00231         stream << ">";
00232 
00233         // encode the element's children OR the value
00234         if (element.m_internalElements.size() > 0) {
00235                 stream << std::endl;
00236             for (ElementContainer::iterator itElement = m_internalElements.begin(); 
00237                                 itElement != m_internalElements.end(); 
00238                                 ++itElement) {
00239                         SOAPElement * e = *itElement;
00240                         e->serialize(stream);
00241                 }
00242         } else {
00243                 stream << element.value();
00244         }
00245 
00246         // terminate the element
00247         stream << "</";
00248         if (element.m_szNamespace.size() > 0) {
00249                 stream << element.m_szNamespace << ":";
00250         }
00251         stream << element.m_szAccessorName << ">";
00252 }
00253 
00254 

Generated on Tue Mar 28 09:10:14 2006 for Simple SOAP by  doxygen 1.4.6