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 )
35 Parser::DecodeState Parser::decode( std::string::size_type& pos,
const std::string& data )
37 std::string::size_type p = data.find(
';', pos );
38 std::string::size_type diff = p - pos;
40 if( p == std::string::npos )
42 m_backBuffer = data.substr( pos );
43 return DecodeInsufficient;
46 if( diff < 3 || diff > 9 )
50 switch( data[pos + 1] )
57 if( data[pos + 2] ==
'x' || data[pos + 2] ==
'X' )
64 const long int val = std::strtol( data.data() + pos + idx, &end, base );
65 if( *end !=
';' || val < 0 )
68 if( val == 0x9 || val == 0xA || val == 0xD || ( val >= 0x20 && val <= 0x7F ) )
72 else if( val >= 0x80 && val <= 0x7FF )
74 rep += char( 192 + ( val >> 6 ) );
75 rep += char( 128 + ( val % 64 ) );
77 else if( ( val >= 0x800 && val <= 0xD7FF ) || ( val >= 0xE000 && val <= 0xFFFD ) )
79 rep += char( 224 + ( val >> 12 ) );
80 rep += char( 128 + ( ( val >> 6 ) % 64 ) );
81 rep += char( 128 + ( val % 64 ) );
83 else if( val >= 0x100000 && val < 0x10FFFF )
85 rep += char( 240 + ( val >> 18 ) );
86 rep += char( 128 + ( ( val >> 12 ) % 64 ) );
87 rep += char( 128 + ( ( val >> 6 ) % 64 ) );
88 rep += char( 128 + ( val % 64 ) );
95 if( diff == 3 && data[pos + 2] ==
't' )
101 if( diff == 3 && data[pos + 2] ==
't' )
104 return DecodeInvalid;
107 if( diff == 5 && !data.compare( pos + 1, 5,
"apos;" ) )
109 else if( diff == 4 && !data.compare( pos + 1, 4,
"amp;" ) )
112 return DecodeInvalid;
115 if( diff == 5 && !data.compare( pos + 1, 5,
"quot;" ) )
118 return DecodeInvalid;
121 return DecodeInvalid;
130 case TagAttributeValue:
140 Parser::ForwardScanState Parser::forwardScan( std::string::size_type& pos,
const std::string& data,
141 const std::string& needle )
143 if( pos + needle.length() <= data.length() )
145 if( !data.compare( pos, needle.length(), needle ) )
147 pos += needle.length() - 1;
152 return ForwardNotFound;
157 m_backBuffer = data.substr( pos );
158 return ForwardInsufficientSize;
164 if( !m_backBuffer.empty() )
166 data.insert( 0, m_backBuffer );
170 std::string::size_type count = data.length();
171 for( std::string::size_type i = 0; i < count; ++i )
173 const unsigned char c = data[i];
180 if( isWhitespace( c ) )
186 m_state = TagOpening;
190 return static_cast<int>( i );
197 if( isWhitespace( c ) )
209 switch( decode( i, data ) )
216 return static_cast<int>( i );
217 case DecodeInsufficient:
222 m_state = TagOpening;
236 if( isWhitespace( c ) )
245 return static_cast<int>( i );
248 m_state = TagClosingSlash;
251 m_state = TagNameCollect;
255 switch( forwardScan( i, data,
"![CDATA[" ) )
258 m_state = TagCDATASection;
260 case ForwardNotFound:
262 return static_cast<int>( i );
263 case ForwardInsufficientSize:
269 m_state = TagNameCollect;
273 case TagCDATASection:
277 switch( forwardScan( i, data,
"]]>" ) )
282 case ForwardNotFound:
285 case ForwardInsufficientSize:
296 if( isWhitespace( c ) )
298 m_state = TagNameComplete;
309 return static_cast<int>( i );
312 m_state = TagOpeningSlash;
319 if( !m_haveTagPrefix )
321 m_haveTagPrefix =
true;
328 return static_cast<int>( i );
343 m_state = TagOpening;
347 switch( decode( i, data ) )
353 return static_cast<int>( i );
354 case DecodeInsufficient:
363 case TagOpeningSlash:
365 if( isWhitespace( c ) )
375 return static_cast<int>( i );
383 return static_cast<int>( i );
386 case TagClosingSlash:
388 if( isWhitespace( c ) )
397 return static_cast<int>( i );
401 m_state = TagClosing;
415 return static_cast<int>( i );
418 if( !m_haveTagPrefix )
420 m_haveTagPrefix =
true;
427 return static_cast<int>( i );
435 return static_cast<int>( i );
444 case TagNameComplete:
446 if( isWhitespace( c ) )
455 return static_cast<int>( i );
458 m_state = TagOpeningSlash;
461 if( m_preamble == 1 )
464 return static_cast<int>( i );
470 if( m_preamble == 1 )
475 return static_cast<int>( i );
480 m_state = TagAttribute;
486 if( isWhitespace( c ) )
488 m_state = TagAttributeComplete;
501 return static_cast<int>( i );
504 m_state = TagAttributeEqual;
507 if( !m_haveAttribPrefix && m_attrib !=
XMLNS )
509 m_haveAttribPrefix =
true;
510 m_attribPrefix = m_attrib;
513 else if( m_attrib ==
XMLNS )
515 m_attribIsXmlns =
true;
521 return static_cast<int>( i );
528 case TagAttributeComplete:
530 if( isWhitespace( c ) )
536 m_state = TagAttributeEqual;
540 return static_cast<int>( i );
544 case TagAttributeEqual:
546 if( isWhitespace( c ) )
554 m_state = TagAttributeValue;
558 return static_cast<int>( i );
562 case TagAttributeValue:
568 return static_cast<int>( i );
578 m_state = TagNameAlmostComplete;
583 switch( decode( i, data ) )
589 return static_cast<int>( i );
590 case DecodeInsufficient:
599 case TagNameAlmostComplete:
601 if( isWhitespace( c ) )
603 m_state = TagNameComplete;
610 m_state = TagOpeningSlash;
613 if( m_preamble == 1 )
616 return static_cast<int>( i );
622 if( m_preamble == 1 )
627 return static_cast<int>( i );
632 return static_cast<int>( i );
646 void Parser::addTag()
651 m_root =
new Tag( m_tag );
657 m_current =
new Tag( m_current, m_tag );
660 if( m_haveTagPrefix )
664 m_haveTagPrefix =
false;
667 if( m_attribs.size() )
689 streamEvent( m_root );
696 if( m_root && m_root == m_current && m_tagPrefix ==
"stream" )
699 if( m_tag ==
"xml" && m_preamble == 2 )
703 void Parser::addAttribute()
705 Tag::Attribute* attr =
new Tag::Attribute( m_attrib, m_value );;
706 if( m_attribIsXmlns )
711 (*m_xmlnss)[m_attrib] = m_value;
712 attr->setPrefix(
XMLNS );
717 if( !m_attribPrefix.empty() )
718 attr->setPrefix( m_attribPrefix );
719 if( m_attrib ==
XMLNS )
722 m_attribs.push_back( attr );
726 m_haveAttribPrefix =
false;
727 m_attribIsXmlns =
false;
730 void Parser::addCData()
732 if( m_current && !m_cdata.empty() )
741 bool Parser::closeTag()
745 if( m_tag ==
"stream" && m_tagPrefix ==
"stream" )
748 if( !m_current || m_current->
name() != m_tag
749 || ( !m_current->
prefix().empty() && m_current->
prefix() != m_tagPrefix ) )
761 m_haveTagPrefix =
false;
764 m_current = m_current->
parent();
768 streamEvent( m_root );
788 m_haveAttribPrefix =
false;
789 m_haveTagPrefix =
false;
798 bool Parser::isWhitespace(
unsigned char c )
800 return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );
803 void Parser::streamEvent( Tag* tag )
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
void clearList(std::list< T * > &L)
bool setPrefix(const std::string &prefix)
Parser(TagHandler *ph, bool deleteRoot=true)
void setAttributes(const AttributeList &attributes)
The namespace for the gloox library.
const std::string & xmlns() const
A virtual interface which can be reimplemented to receive non-XMPP Core stanzas.
bool addCData(const std::string &cdata)
std::map< std::string, std::string > StringMap
virtual void handleTag(Tag *tag)=0
const std::string & prefix() const
void cleanup(bool deleteRoot=true)
const std::string XMLNS_STREAM
const std::string & name() const
const std::string EmptyString
This is an abstraction of an XML element.
int feed(std::string &data)