parser.cpp

00001 /*
00002   Copyright (c) 2004-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 
00015 #include "gloox.h"
00016 
00017 #include "parser.h"
00018 #include "clientbase.h"
00019 #include "stanza.h"
00020 
00021 namespace gloox
00022 {
00023 
00024   Parser::Parser( ClientBase *parent )
00025     : m_parent( parent ), m_current( 0 ), m_root( 0 )
00026   {
00027     m_parser = iks_sax_new( this, (iksTagHook*)tagHook, (iksCDataHook*)cdataHook );
00028   }
00029 
00030   Parser::~Parser()
00031   {
00032     iks_parser_delete( m_parser );
00033     delete m_root;
00034   }
00035 
00036   Parser::ParserState Parser::feed( const std::string& data )
00037   {
00038     int res = iks_parse( m_parser, data.c_str(), data.length(), 0 );
00039     switch( res )
00040     {
00041       case IKS_NOMEM:
00042         return PARSER_NOMEM;
00043         break;
00044       case IKS_BADXML:
00045         return PARSER_BADXML;
00046         break;
00047       case IKS_OK:
00048       default:
00049         return PARSER_OK;
00050         break;
00051     }
00052   }
00053 
00054   void Parser::streamEvent( Stanza *stanza )
00055   {
00056     if( m_parent && stanza )
00057     {
00058       ClientBase::NodeType type = ClientBase::NODE_STREAM_CHILD;
00059       if( m_root->name() == "stream:stream" )
00060         type = ClientBase::NODE_STREAM_START;
00061       else if( m_root->name() == "stream:error" )
00062         type = ClientBase::NODE_STREAM_ERROR;
00063 
00064       m_parent->filter( type, stanza );
00065     }
00066     else if( !stanza )
00067       m_parent->filter( ClientBase::NODE_STREAM_CLOSE, 0 );
00068   }
00069 
00070   int tagHook( Parser *parser, char *name, char **atts, int type )
00071   {
00072     if( !name )
00073       return IKS_OK;
00074 
00075     switch( type )
00076     {
00077       case IKS_OPEN:
00078       case IKS_SINGLE:
00079       {
00080         Stanza *tag = new Stanza( name, "", "default", true );
00081         for(int i=0; atts && atts[i]; )
00082         {
00083           tag->addAttribute( atts[i], atts[i+1] );
00084           i+=2;
00085         }
00086         if( !parser->m_root )
00087         {
00088           parser->m_root = tag;
00089           parser->m_current = parser->m_root;
00090         }
00091         else
00092         {
00093           parser->m_current->addChild( tag );
00094           parser->m_current = tag;
00095         }
00096         if( tag->name() == "stream:stream" )
00097         {
00098           parser->streamEvent( parser->m_root );
00099           delete parser->m_root;
00100           parser->m_root = 0;
00101           parser->m_current = 0;
00102         }
00103         if( type == IKS_OPEN )
00104         break;
00105       }
00106       case IKS_CLOSE:
00107         if( iks_strncmp( name, "stream:stream", 13 ) == 0 )
00108         {
00109           parser->streamEvent( 0 );
00110           break;
00111         }
00112         parser->m_current = dynamic_cast<Stanza*>( parser->m_current->parent() );
00113         if( !parser->m_current )
00114         {
00115           parser->m_root->finalize();
00116           parser->streamEvent( parser->m_root );
00117           delete parser->m_root;
00118           parser->m_root = 0;
00119           parser->m_current = 0;
00120         }
00121         break;
00122     }
00123     return IKS_OK;
00124   }
00125 
00126   int cdataHook( Parser *parser, char *data, size_t len )
00127   {
00128     if( parser->m_current && data && len )
00129     {
00130       std::string tmp;
00131       tmp.assign( data, len );
00132       parser->m_current->addCData( tmp );
00133     }
00134 
00135     return IKS_OK;
00136   }
00137 
00138 }

Generated on Tue May 1 14:20:20 2007 for gloox by  doxygen 1.5.1