23 : m_tagHandler( ph ), m_current( 0 ), m_root( 0 ), m_xmlnss( 0 ), m_state( Initial ),
24 m_preamble( 0 ), m_quote( false ), m_haveTagPrefix( false ), m_haveAttribPrefix( false ),
25 m_attribIsXmlns( false ), m_deleteRoot( deleteRoot )
34 Parser::DecodeState Parser::decode( std::string::size_type& pos,
const std::string& data )
36 std::string::size_type p = data.find(
';', pos );
37 std::string::size_type diff = p - pos;
39 if( p == std::string::npos )
41 m_backBuffer = data.substr( pos );
42 return DecodeInsufficient;
45 if( diff < 3 || diff > 9 )
49 switch( data[pos + 1] )
56 if( data[pos + 2] ==
'x' || data[pos + 2] ==
'X' )
63 const long int val = std::strtol( data.data() + pos + idx, &end, base );
64 if( *end !=
';' || val < 0 )
67 if( val == 0x9 || val == 0xA || val == 0xD || ( val >= 0x20 && val <= 0x7F ) )
71 else if( val >= 0x80 && val <= 0x7FF )
73 rep += char( 192 + ( val >> 6 ) );
74 rep += char( 128 + ( val % 64 ) );
76 else if( ( val >= 0x800 && val <= 0xD7FF ) || ( val >= 0xE000 && val <= 0xFFFD ) )
78 rep += char( 224 + ( val >> 12 ) );
79 rep += char( 128 + ( ( val >> 6 ) % 64 ) );
80 rep += char( 128 + ( val % 64 ) );
82 else if( val >= 0x100000 && val < 0x10FFFF )
84 rep += char( 240 + ( val >> 18 ) );
85 rep += char( 128 + ( ( val >> 12 ) % 64 ) );
86 rep += char( 128 + ( ( val >> 6 ) % 64 ) );
87 rep += char( 128 + ( val % 64 ) );
94 if( diff == 3 && data[pos + 2] ==
't' )
100 if( diff == 3 && data[pos + 2] ==
't' )
103 return DecodeInvalid;
106 if( diff == 5 && !data.compare( pos + 1, 5,
"apos;" ) )
108 else if( diff == 4 && !data.compare( pos + 1, 4,
"amp;" ) )
111 return DecodeInvalid;
114 if( diff == 5 && !data.compare( pos + 1, 5,
"quot;" ) )
117 return DecodeInvalid;
120 return DecodeInvalid;
129 case TagAttributeValue:
139 Parser::ForwardScanState Parser::forwardScan( std::string::size_type& pos,
const std::string& data,
140 const std::string& needle )
142 if( pos + needle.length() <= data.length() )
144 if( !data.compare( pos, needle.length(), needle ) )
146 pos += needle.length() - 1;
151 return ForwardNotFound;
156 m_backBuffer = data.substr( pos );
157 return ForwardInsufficientSize;
163 if( !m_backBuffer.empty() )
165 data.insert( 0, m_backBuffer );
169 std::string::size_type count = data.length();
170 for( std::string::size_type i = 0; i < count; ++i )
172 const unsigned char c = data[i];
179 if( isWhitespace( c ) )
185 m_state = TagOpening;
189 return static_cast<int>( i );
196 if( isWhitespace( c ) )
208 switch( decode( i, data ) )
215 return static_cast<int>( i );
216 case DecodeInsufficient:
221 m_state = TagOpening;
235 if( isWhitespace( c ) )
244 return static_cast<int>( i );
247 m_state = TagClosingSlash;
250 m_state = TagNameCollect;
254 switch( forwardScan( i, data,
"![CDATA[" ) )
257 m_state = TagCDATASection;
259 case ForwardNotFound:
261 return static_cast<int>( i );
262 case ForwardInsufficientSize:
268 m_state = TagNameCollect;
272 case TagCDATASection:
276 switch( forwardScan( i, data,
"]]>" ) )
281 case ForwardNotFound:
284 case ForwardInsufficientSize:
295 if( isWhitespace( c ) )
297 m_state = TagNameComplete;
308 return static_cast<int>( i );
311 m_state = TagOpeningSlash;
318 if( !m_haveTagPrefix )
320 m_haveTagPrefix =
true;
327 return static_cast<int>( i );
342 m_state = TagOpening;
346 switch( decode( i, data ) )
352 return static_cast<int>( i );
353 case DecodeInsufficient:
362 case TagOpeningSlash:
364 if( isWhitespace( c ) )
374 return static_cast<int>( i );
382 return static_cast<int>( i );
385 case TagClosingSlash:
387 if( isWhitespace( c ) )
396 return static_cast<int>( i );
400 m_state = TagClosing;
414 return static_cast<int>( i );
417 if( !m_haveTagPrefix )
419 m_haveTagPrefix =
true;
426 return static_cast<int>( i );
434 return static_cast<int>( i );
443 case TagNameComplete:
445 if( isWhitespace( c ) )
454 return static_cast<int>( i );
457 m_state = TagOpeningSlash;
460 if( m_preamble == 1 )
463 return static_cast<int>( i );
469 if( m_preamble == 1 )
474 return static_cast<int>( i );
479 m_state = TagAttribute;
485 if( isWhitespace( c ) )
487 m_state = TagAttributeComplete;
500 return static_cast<int>( i );
503 m_state = TagAttributeEqual;
506 if( !m_haveAttribPrefix && m_attrib !=
XMLNS )
508 m_haveAttribPrefix =
true;
509 m_attribPrefix = m_attrib;
512 else if( m_attrib ==
XMLNS )
514 m_attribIsXmlns =
true;
520 return static_cast<int>( i );
527 case TagAttributeComplete:
529 if( isWhitespace( c ) )
535 m_state = TagAttributeEqual;
539 return static_cast<int>( i );
543 case TagAttributeEqual:
545 if( isWhitespace( c ) )
553 m_state = TagAttributeValue;
557 return static_cast<int>( i );
561 case TagAttributeValue:
567 return static_cast<int>( i );
577 m_state = TagNameAlmostComplete;
582 switch( decode( i, data ) )
588 return static_cast<int>( i );
589 case DecodeInsufficient:
598 case TagNameAlmostComplete:
600 if( isWhitespace( c ) )
602 m_state = TagNameComplete;
609 m_state = TagOpeningSlash;
612 if( m_preamble == 1 )
615 return static_cast<int>( i );
621 if( m_preamble == 1 )
626 return static_cast<int>( i );
631 return static_cast<int>( i );
645 void Parser::addTag()
650 m_root =
new Tag( m_tag );
656 m_current =
new Tag( m_current, m_tag );
659 if( m_haveTagPrefix )
663 m_haveTagPrefix =
false;
666 if( m_attribs.size() )
688 streamEvent( m_root );
695 if( m_root && m_root == m_current && m_tagPrefix ==
"stream" )
698 if( m_tag ==
"xml" && m_preamble == 2 )
702 void Parser::addAttribute()
704 Tag::Attribute* attr =
new Tag::Attribute( m_attrib, m_value );;
705 if( m_attribIsXmlns )
710 (*m_xmlnss)[m_attrib] = m_value;
711 attr->setPrefix(
XMLNS );
716 if( !m_attribPrefix.empty() )
717 attr->setPrefix( m_attribPrefix );
718 if( m_attrib ==
XMLNS )
721 m_attribs.push_back( attr );
725 m_haveAttribPrefix =
false;
726 m_attribIsXmlns =
false;
729 void Parser::addCData()
731 if( m_current && !m_cdata.empty() )
740 bool Parser::closeTag()
744 if( m_tag ==
"stream" && m_tagPrefix ==
"stream" )
747 if( !m_current || m_current->
name() != m_tag
748 || ( !m_current->
prefix().empty() && m_current->
prefix() != m_tagPrefix ) )
760 m_haveTagPrefix =
false;
763 m_current = m_current->
parent();
767 streamEvent( m_root );
787 m_haveAttribPrefix =
false;
788 m_haveTagPrefix =
false;
797 bool Parser::isWhitespace(
unsigned char c )
799 return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );
802 void Parser::streamEvent( Tag* tag )
Parser(TagHandler *ph, bool deleteRoot=true)
void cleanup(bool deleteRoot=true)
int feed(std::string &data)
A virtual interface which can be reimplemented to receive non-XMPP Core stanzas.
virtual void handleTag(Tag *tag)=0
This is an abstraction of an XML element.
bool setPrefix(const std::string &prefix)
const std::string & prefix() const
const std::string xmlns() const
bool addCData(const std::string &cdata)
const std::string & name() const
void setAttributes(const AttributeList &attributes)
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
void clearList(std::list< T * > &L)
The namespace for the gloox library.
const std::string XMLNS_STREAM
const std::string EmptyString
std::map< std::string, std::string > StringMap