⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 Jabber code library, developed with c
💻 CPP
字号:
/*  Copyright (c) 2004-2008 by Jakob Schroeter <js@camaya.net>  This file is part of the gloox library. http://camaya.net/gloox  This software is distributed under a license. The full license  agreement can be found in the file LICENSE in this distribution.  This software may not be copied, modified, sold or distributed  other than expressed in the named license agreement.  This software is distributed without any warranty.*/#include "gloox.h"#include "parser.h"namespace gloox{  Parser::Parser( TagHandler *ph )    : m_tagHandler( ph ), m_current( 0 ), m_root( 0 ), m_state( Initial ),      m_preamble( 0 ), m_quote( false )  {  }  Parser::~Parser()  {    delete m_root;  }  bool Parser::feed( const std::string& data )  {    std::string::const_iterator it = data.begin();    for( ; it != data.end(); ++it )    {      const unsigned char c = (*it);//       printf( "found char:   %c, ", c );      if( !isValid( c ) )      {        cleanup();        return false;      }      switch( m_state )      {        case Initial:          m_tag = "";          if( isWhitespace( c ) )            break;          switch( c )          {            case '<':              m_state = TagOpening;              break;            case '>':            default://               cleanup();//               return false;              break;          }          break;        case TagOpening:               // opening '<' has been found before          if( isWhitespace( c ) )            break;          switch( c )          {            case '<':            case '>':            case '!':              cleanup();              return false;              break;            case '/':              m_state = TagClosingSlash;              break;            case '?':              m_state = TagNameCollect;              m_preamble = 1;              break;            default:              m_tag += c;              m_state = TagNameCollect;              break;          }          break;        case TagNameCollect:          // we're collecting the tag's name, we have at least one octet already          if( isWhitespace( c ) )          {            m_state = TagNameComplete;            break;          }          switch( c )          {            case '<':            case '?':            case '!':              cleanup();              return false;              break;            case '/':              m_state = TagOpeningSlash;              break;            case '>':              addTag();              m_state = TagInside;              break;            default:              m_tag += c;              break;          }          break;        case TagInside:                // we're inside a tag, expecting a child tag or cdata          m_tag = "";          switch( c )          {            case '<':              addCData();              m_state = TagOpening;              break;            default:              m_cdata += c;              break;          }          break;        case TagOpeningSlash:         // a slash in an opening tag has been found, initing close of the tag          if( isWhitespace( c ) )            break;          if( c == '>' )          {            addTag();            if( !closeTag() )            {              cleanup();              return false;            }            m_state = Initial;          }          else          {            cleanup();            return false;          }          break;        case TagClosingSlash:         // we have found the '/' of a closing tag          if( isWhitespace( c ) )            break;          switch( c )          {            case '>':            case '<':            case '/':              cleanup();              return false;              break;            default:              m_tag += c;              m_state = TagClosing;              break;          }          break;        case TagClosing:               // we're collecting the name of a closing tag          switch( c )          {            case '<':            case '/':              cleanup();              return false;              break;            case '>':              if( !closeTag() )              {                cleanup();                return false;              }              m_state = Initial;              break;            default:              m_tag += c;              break;          }          break;        case TagNameComplete:        // a tag name is complete, expect tag close or attribs          if( isWhitespace( c ) )            break;          switch( c )          {            case '<':              cleanup();              return false;              break;            case '/':              m_state = TagOpeningSlash;              break;            case '>':              if( m_preamble == 1 )              {                cleanup();                return false;              }              m_state = TagInside;              addTag();              break;            case '?':              if( m_preamble == 1 )                m_preamble = 2;              else              {                cleanup();                return false;              }              break;            default:              m_attrib += c;              m_state = TagAttribute;              break;          }          break;        case TagAttribute:                  // we're collecting the name of an attribute, we have at least 1 octet          if( isWhitespace( c ) )          {            m_state = TagAttributeComplete;            break;          }          switch( c )          {            case '<':            case '/':            case '>':              cleanup();              return false;              break;            case '=':              m_state = TagAttributeEqual;              break;            default:              m_attrib += c;          }          break;        case TagAttributeComplete:         // we're expecting an equals sign or ws or the attrib value          if( isWhitespace( c ) )            break;          switch( c )          {            case '=':              m_state = TagAttributeEqual;              break;            case '<':            case '/':            case '>':            default:              cleanup();              return false;              break;          }          break;        case TagAttributeEqual:            // we have found an equals sign          if( isWhitespace( c ) )            break;          switch( c )          {            case '"':              m_quote = true;            case '\'':              m_state = TagValue;              break;            case '=':            case '<':            case '>':            default:              cleanup();              return false;              break;          }          break;        case TagValue:                 // we're expecting value data          switch( c )          {            case '<':              cleanup();              return false;              break;            case '\'':              if( m_quote )              {                m_value += c;                break;              }            case '"':              addAttribute();              m_state = TagNameComplete;              m_quote = false;              break;            case '>':            default:              m_value += c;          }          break;        default://           printf( "default action!?\n" );          break;      }//       printf( "parser state: %d\n", m_state );    }    return true;  }  void Parser::addTag()  {    if( !m_root )    {//       printf( "created Tag named %s, ", m_tag.c_str() );      m_root = new Tag( m_tag, "", true );      m_current = m_root;    }    else    {//       printf( "created Tag named %s, ", m_tag.c_str() );      m_current = new Tag( m_current, m_tag, "", true );    }    if( m_attribs.size() )    {      m_current->setAttributes( m_attribs );//       printf( "added %d attributes, ", m_attribs.size() );      m_attribs.clear();    }    if( m_tag == "stream:stream" )    {      streamEvent( m_root );      cleanup();    }//     else//       printf( "%s, ", m_root->xml().c_str() );    if( m_tag == "xml" && m_preamble == 2 )      cleanup();  }  void Parser::addAttribute()  {//     printf( "adding attribute: %s='%s', ", m_attrib.c_str(), m_value.c_str() );    m_attribs.push_back( Tag::Attribute( Tag::relax( m_attrib ), Tag::relax( m_value ) ) );    m_attrib = "";    m_value = "";//     printf( "added, " );  }  void Parser::addCData()  {    if( m_current )    {      m_current->setCData( m_cdata );//       printf( "added cdata %s, ", m_cdata.c_str() );      m_cdata = "";    }  }  bool Parser::closeTag()  {//     printf( "about to close, " );    if( m_tag == "stream:stream" )      return true;    if( !m_current || m_current->name() != m_tag )      return false;//       printf( "m_current: %s, ", m_current->name().c_str() );//       printf( "m_tag: %s, ", m_tag.c_str() );    if( m_current->parent() )      m_current = m_current->parent();    else    {//       printf( "pushing upstream, " );      streamEvent( m_root );      cleanup();    }    return true;  }  void Parser::cleanup()  {    delete m_root;    m_root = 0;    m_current = 0;    m_cdata = "";    m_tag = "";    m_attrib = "";    m_value = "";    m_attribs.clear();    m_state = Initial;    m_preamble = 0;  }  bool Parser::isValid( unsigned char c )  {    return ( c != 0xc0 || c != 0xc1 || c < 0xf5 );  }  bool Parser::isWhitespace( unsigned char c )  {    return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );  }  void Parser::streamEvent( Tag *tag )  {    if( m_tagHandler )      m_tagHandler->handleTag( tag );  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -