Skip to content

Commit e1d87f4

Browse files
committed
Trying again...
2 parents 7240a2d + 12e542f commit e1d87f4

File tree

7 files changed

+561
-2
lines changed

7 files changed

+561
-2
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright (c) Glyn Matthews 2010.
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
7+
#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__
8+
# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__
9+
10+
11+
# include <boost/network/traits/string.hpp>
12+
# include <boost/network/detail/xml_wrappers/element.hpp>
13+
# include <expat.h>
14+
# include <cstring>
15+
16+
17+
namespace boost {
18+
namespace network {
19+
namespace detail {
20+
template <
21+
class Tag
22+
>
23+
class basic_expat_element_parser {
24+
public:
25+
26+
typedef typename string<Tag>::type string_type;
27+
28+
typedef basic_element<Tag> element_type;
29+
30+
basic_expat_element_parser() {
31+
parser_ = XML_ParserCreate(NULL);
32+
// handle the case where the parser is NULL
33+
element_ = 0;
34+
depth_ = 0;
35+
36+
XML_SetUserData(parser_, this);
37+
XML_SetElementHandler(parser_, start_element, end_element);
38+
XML_SetCharacterDataHandler(parser_, cdata);
39+
}
40+
41+
~basic_expat_element_parser() {
42+
XML_ParserFree(parser_);
43+
}
44+
45+
bool feed(const string_type &chunk) {
46+
return feed(chunk, 0);
47+
}
48+
49+
bool feed(const string_type &chunk, element_type *element) {
50+
element_ = element;
51+
return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0;
52+
}
53+
54+
private:
55+
56+
static void set_name(element_type *element, const XML_Char *name) {
57+
const XML_Char *name_begin = name;
58+
const XML_Char *name_end = name_begin + std::strlen(name_begin);
59+
60+
element->set_name(string_type(name_begin, name_end));
61+
}
62+
63+
static void set_attributes(element_type *element, const XML_Char **attrs) {
64+
if (attrs) {
65+
for (int i = 0; attrs[i]; i += 2) {
66+
const XML_Char *key_begin = attrs[i];
67+
const XML_Char *key_end = key_begin + std::strlen(key_begin);
68+
69+
const XML_Char *val_begin = attrs[i + 1];
70+
const XML_Char *val_end = val_begin + std::strlen(val_begin);
71+
72+
element->set_attribute(string_type(key_begin, key_end),
73+
string_type(val_begin, val_end));
74+
}
75+
}
76+
}
77+
78+
static void start_element(void *userdata,
79+
const XML_Char *name,
80+
const XML_Char **attrs) {
81+
basic_expat_element_parser<Tag> *parser
82+
= static_cast<basic_expat_element_parser<Tag> *>(userdata);
83+
84+
if (parser->depth_ == 1) {
85+
set_name(parser->element_, name);
86+
set_attributes(parser->element_, attrs);
87+
}
88+
else if (parser->depth_ > 1) {
89+
element_type *child = new element_type;
90+
set_name(child, name);
91+
set_attributes(child, attrs);
92+
parser->element_->add_child(child);
93+
}
94+
95+
++parser->depth_;
96+
}
97+
98+
static void end_element(void *userdata,
99+
const XML_Char *name) {
100+
basic_expat_element_parser<Tag> *parser
101+
= static_cast<basic_expat_element_parser<Tag> *>(userdata);
102+
103+
--parser->depth_;
104+
}
105+
106+
static void cdata(void *userdata,
107+
const XML_Char *s,
108+
int len) {
109+
basic_expat_element_parser<Tag> *parser
110+
= static_cast<basic_expat_element_parser<Tag> *>(userdata);
111+
112+
parser->element_->add_child(
113+
new element_type(typename element_type::text(), string_type(s, s + len)));
114+
}
115+
116+
XML_Parser parser_;
117+
element_type *element_;
118+
int depth_;
119+
120+
};
121+
} // namespace detail
122+
} // namespace network
123+
} // namespace boost
124+
125+
126+
#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_ELEMENT_PARSER_INC__
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Copyright (c) Glyn Matthews 2010.
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
7+
#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__
8+
# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__
9+
10+
11+
# include <boost/network/traits/string.hpp>
12+
# include <boost/network/protocol/xmpp/stanza.hpp>
13+
# include <expat.h>
14+
# include <cstring>
15+
16+
17+
namespace boost {
18+
namespace network {
19+
namespace detail {
20+
template <
21+
class Tag
22+
>
23+
class basic_expat_stanza_parser {
24+
public:
25+
26+
typedef typename string<Tag>::type string_type;
27+
28+
typedef basic_stanza<Tag> stanza_type;
29+
30+
basic_expat_stanza_parser() {
31+
parser_ = XML_ParserCreate(NULL);
32+
// handle the case where the parser is NULL
33+
stanza_ = 0;
34+
depth_ = 0;
35+
36+
XML_SetUserData(parser_, this);
37+
XML_SetElementHandler(parser_, start_element, end_element);
38+
XML_SetCharacterDataHandler(parser_, cdata);
39+
}
40+
41+
~basic_expat_stanza_parser() {
42+
XML_ParserFree(parser_);
43+
}
44+
45+
bool feed(const string_type &chunk) {
46+
stanza_ = 0;
47+
return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0;
48+
}
49+
50+
bool feed(const string_type &chunk, stanza_type &stanza) {
51+
stanza_ = &stanza;
52+
return XML_Parse(parser_, chunk.c_str(), chunk.size(), 0) != 0;
53+
}
54+
55+
private:
56+
57+
static void set_name(stanza_type *stanza, const XML_Char *name) {
58+
const XML_Char *name_begin = name;
59+
const XML_Char *name_end = name_begin + std::strlen(name_begin);
60+
61+
stanza->set_name(string_type(name_begin, name_end));
62+
}
63+
64+
static void set_attributes(stanza_type *stanza, const XML_Char **attrs) {
65+
if (attrs) {
66+
for (int i = 0; attrs[i]; i += 2) {
67+
const XML_Char *key_begin = attrs[i];
68+
const XML_Char *key_end = key_begin + std::strlen(key_begin);
69+
70+
const XML_Char *val_begin = attrs[i + 1];
71+
const XML_Char *val_end = val_begin + std::strlen(val_begin);
72+
73+
stanza->set_attribute(string_type(key_begin, key_end),
74+
string_type(val_begin, val_end));
75+
}
76+
}
77+
}
78+
79+
static void start_element(void *userdata,
80+
const XML_Char *name,
81+
const XML_Char **attrs) {
82+
basic_expat_stanza_parser<Tag> *parser
83+
= static_cast<basic_expat_stanza_parser<Tag> *>(userdata);
84+
85+
if (parser->depth_ == 1) {
86+
set_name(parser->stanza_, name);
87+
set_attributes(parser->stanza_, attrs);
88+
}
89+
else if (parser->depth_ > 1) {
90+
// element_type *child = new element_type;
91+
// set_name(child, name);
92+
// set_attributes(child, attrs);
93+
// parser->element_->add_child(child);
94+
}
95+
96+
++parser->depth_;
97+
}
98+
99+
static void end_element(void *userdata,
100+
const XML_Char *name) {
101+
basic_expat_stanza_parser<Tag> *parser
102+
= static_cast<basic_expat_stanza_parser<Tag> *>(userdata);
103+
104+
--parser->depth_;
105+
}
106+
107+
static void cdata(void *userdata,
108+
const XML_Char *s,
109+
int len) {
110+
basic_expat_stanza_parser<Tag> *parser
111+
= static_cast<basic_expat_stanza_parser<Tag> *>(userdata);
112+
}
113+
114+
XML_Parser parser_;
115+
stanza_type *stanza_;
116+
int depth_;
117+
118+
};
119+
} // namespace detail
120+
} // namespace network
121+
} // namespace boost
122+
123+
124+
#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_EXPAT_STANZA_PARSER_INC__
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) Glyn Matthews 2010.
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE_1_0.txt or copy at
4+
// http://www.boost.org/LICENSE_1_0.txt)
5+
6+
7+
#ifndef __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__
8+
# define __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__
9+
10+
11+
# include <boost/network/traits/string.hpp>
12+
# include <boost/network/detail/xml_wrappers/element.hpp>
13+
# include <libxml/parser.h>
14+
# include <libxml/tree.h>
15+
16+
17+
namespace boost {
18+
namespace network {
19+
namespace detail {
20+
template <
21+
class Tag
22+
>
23+
class basic_libxml2_element_parser {
24+
25+
public:
26+
27+
typedef typename string<Tag>::type string_type;
28+
29+
typedef basic_element<Tag> element_type;
30+
31+
basic_libxml2_element_parser() {
32+
std::memset(&handlers_, 0, sizeof(xmlSAXHandler));
33+
handlers_.startElement = start_element;
34+
handlers_.endElement = end_element;
35+
handlers_.characters = characters;
36+
depth_ = 0;
37+
element_ = 0;
38+
39+
context_ = xmlCreatePushParserCtxt(&handlers_,
40+
this, 0, 0, 0);
41+
// assert(!context_);
42+
}
43+
44+
~basic_libxml2_element_parser() {
45+
xmlFreeParserCtxt(context_);
46+
}
47+
48+
bool feed(const string_type &chunk) {
49+
return feed(chunk, 0);
50+
}
51+
52+
bool feed(const string_type &chunk, element_type *element) {
53+
element_ = element;
54+
return xmlParseChunk(context_, chunk.c_str(), chunk.size(), 0);
55+
}
56+
57+
private:
58+
59+
static void set_name(element_type *element, const xmlChar *name) {
60+
const xmlChar *name_begin = name;
61+
const xmlChar *name_end = name_begin + xmlStrlen(name_begin);
62+
element->set_name(string_type(name_begin, name_end));
63+
}
64+
65+
static void set_attributes(basic_element<Tag> *element, const xmlChar **attrs) {
66+
if (attrs) {
67+
for (int i = 0; attrs[i]; i += 2) {
68+
const xmlChar *key_begin = attrs[i];
69+
const xmlChar *key_end = key_begin + xmlStrlen(key_begin);
70+
71+
const xmlChar *val_begin = attrs[i + 1];
72+
const xmlChar *val_end = val_begin + xmlStrlen(val_begin);
73+
74+
element->set_attribute(string_type(key_begin, key_end),
75+
string_type(val_begin, val_end));
76+
}
77+
}
78+
}
79+
80+
static void start_element(void *userdata,
81+
const xmlChar *name,
82+
const xmlChar **attrs) {
83+
basic_libxml2_element_parser<Tag> *parser
84+
= static_cast<basic_libxml2_element_parser<Tag> *>(userdata);
85+
86+
if (parser->depth_ == 1) {
87+
set_name(parser->element_, name);
88+
set_attributes(parser->element_, attrs);
89+
}
90+
else if (parser->depth_ > 1) {
91+
element_type *child = new element_type;
92+
set_name(child, name);
93+
set_attributes(child, attrs);
94+
parser->element_->add_child(child);
95+
}
96+
97+
++parser->depth_;
98+
}
99+
100+
static void end_element(void *userdata,
101+
const xmlChar *name) {
102+
basic_libxml2_element_parser<Tag> *parser
103+
= static_cast<basic_libxml2_element_parser<Tag> *>(userdata);
104+
105+
--parser->depth_;
106+
}
107+
108+
static void characters(void *userdata,
109+
const xmlChar *s,
110+
int len) {
111+
basic_libxml2_element_parser<Tag> *parser
112+
= static_cast<basic_libxml2_element_parser<Tag> *>(userdata);
113+
114+
parser->element_->add_child(
115+
new element_type(typename element_type::text(), string_type(s, s + len)));
116+
}
117+
118+
xmlParserCtxtPtr context_;
119+
xmlSAXHandler handlers_;
120+
element_type *element_;
121+
int depth_;
122+
123+
};
124+
} // namespace detail
125+
} // namespace network
126+
} // namespace boost
127+
128+
129+
#endif // __BOOST_NETWORK_DETAIL_XML_WRAPPERS_PARSER_BACKENDS_LIBXML2_ELEMENT_PARSER_INC__

0 commit comments

Comments
 (0)