7 #include "Atlas/Codecs/XML.h" 8 #include "Atlas/Message/Element.h" 17 XML::XML(std::istream &in, std::ostream &out,
Atlas::Bridge &b)
18 : m_istream(in), m_ostream(out), m_bridge(b) {
20 m_state.push(PARSE_NOTHING);
24 void XML::tokenTag(
char next) {
29 m_token = TOKEN_END_TAG;
38 m_token = TOKEN_START_TAG;
44 void XML::tokenStartTag(
char next) {
59 m_token = TOKEN_END_TAG;
69 void XML::tokenEndTag(
char next) {
88 void XML::tokenData(
char next) {
100 m_data.top() += next;
105 void XML::parseStartTag() {
106 int tag_end = (int) m_tag.find(
' ');
107 int name_start = (int) m_tag.find(
"name=\"") + 6;
108 int name_end = (int) m_tag.rfind(
'\"');
110 if (name_start < name_end) {
112 std::string(m_tag, (
unsigned long) name_start, (
unsigned long) (name_end - name_start)));
117 m_tag = std::string(m_tag, 0, (
unsigned long) tag_end);
119 switch (m_state.top()) {
121 if (m_tag ==
"atlas") {
123 m_state.push(PARSE_STREAM);
131 if (m_tag ==
"map") {
133 m_state.push(PARSE_MAP);
141 if (m_tag ==
"map") {
143 m_state.push(PARSE_MAP);
144 }
else if (m_tag ==
"list") {
146 m_state.push(PARSE_LIST);
147 }
else if (m_tag ==
"int") {
148 m_state.push(PARSE_INT);
149 }
else if (m_tag ==
"float") {
150 m_state.push(PARSE_FLOAT);
151 }
else if (m_tag ==
"string") {
152 m_state.push(PARSE_STRING);
153 }
else if (m_tag ==
"none") {
154 m_state.push(PARSE_NONE);
162 if (m_tag ==
"map") {
164 m_state.push(PARSE_MAP);
165 }
else if (m_tag ==
"list") {
167 m_state.push(PARSE_LIST);
168 }
else if (m_tag ==
"int") {
169 m_state.push(PARSE_INT);
170 }
else if (m_tag ==
"float") {
171 m_state.push(PARSE_FLOAT);
172 }
else if (m_tag ==
"string") {
173 m_state.push(PARSE_STRING);
174 }
else if (m_tag ==
"none") {
175 m_state.push(PARSE_NONE);
192 void XML::parseEndTag() {
193 switch (m_state.top()) {
200 if (m_tag ==
"atlas") {
210 if (m_tag ==
"map") {
220 if (m_tag ==
"list") {
230 if (m_tag ==
"int") {
233 Atlas::Message::IntType value = 0;
234 auto data = m_data.top();
236 value = std::stol(data);
238 if (m_state.top() == PARSE_MAP) {
253 if (m_tag ==
"float") {
256 Atlas::Message::FloatType value = 0;
257 auto data = m_data.top();
259 value = std::stod(data);
261 if (m_state.top() == PARSE_MAP) {
276 if (m_tag ==
"string") {
278 if (m_state.top() == PARSE_MAP) {
289 if (m_tag ==
"none") {
291 if (m_state.top() == PARSE_MAP) {
307 std::streamsize count;
309 while ((count = m_istream.rdbuf()->in_avail()) > 0) {
311 for (std::streamsize i = 0; i < count; ++i) {
313 char next = m_istream.rdbuf()->sbumpc();
319 case TOKEN_START_TAG:
334 m_ostream <<
"<atlas>";
338 m_ostream <<
"</atlas>";
342 m_ostream <<
"<map>";
346 m_ostream <<
"<map name=\"" <<
escape(name) <<
"\">";
350 m_ostream <<
"<list name=\"" <<
escape(name) <<
"\">";
354 m_ostream <<
"<int name=\"" <<
escape(name) <<
"\">" << data <<
"</int>";
358 m_ostream <<
"<float name=\"" <<
escape(name) <<
"\">" << data <<
"</float>";
362 m_ostream <<
"<string name=\"" <<
escape(name) <<
"\">" <<
escape(data) <<
"</string>";
366 m_ostream <<
"<none name=\"" <<
escape(name) <<
"\"></none>";
370 m_ostream <<
"</map>";
374 m_ostream <<
"<map>";
378 m_ostream <<
"<list>";
382 m_ostream <<
"<int>" << data <<
"</int>";
386 m_ostream <<
"<float>" << data <<
"</float>";
390 m_ostream <<
"<string>" <<
escape(data) <<
"</string>";
394 m_ostream <<
"<none></none>";
398 m_ostream <<
"</list>";
403 buffer.reserve(original.size() + (original.size() / 2));
404 for (
size_t pos = 0; pos != original.size(); ++pos) {
405 switch (original[pos]) {
407 buffer.append(
"&");
410 buffer.append(
""");
413 buffer.append(
"'");
416 buffer.append(
"<");
419 buffer.append(
">");
422 buffer.append(1, original[pos]);
431 buffer.reserve(original.size());
432 for (
size_t pos = 0; pos != original.size(); ++pos) {
433 if (original[pos] ==
'&') {
434 if (original.size() - pos >= 3) {
435 if (original[pos + 1] ==
'l' && original[pos + 2] ==
't' && original[pos + 3] ==
';') {
436 buffer.append(1,
'<');
439 }
else if (original[pos + 1] ==
'g' && original[pos + 2] ==
't' && original[pos + 3] ==
';') {
440 buffer.append(1,
'>');
445 if (original.size() - pos >= 4) {
446 if (original[pos + 1] ==
'a' && original[pos + 2] ==
'm' && original[pos + 3] ==
'p' &&
447 original[pos + 4] ==
';') {
448 buffer.append(1,
'&');
453 if (original.size() - pos >= 5) {
454 if (original[pos + 1] ==
'q' && original[pos + 2] ==
'u' && original[pos + 3] ==
'o' &&
455 original[pos + 4] ==
't' && original[pos + 5] ==
';') {
456 buffer.append(1,
'"');
459 }
else if (original[pos + 1] ==
'a' && original[pos + 2] ==
'p' && original[pos + 3] ==
'o' &&
460 original[pos + 4] ==
's' && original[pos + 5] ==
';') {
461 buffer.append(1,
'\'');
467 buffer.append(1, original[pos]);
static std::string unescape(const std::string &)
void listMapItem() override
void mapMapItem(std::string name) override
void streamBegin() override
void listNoneItem() override
virtual void listFloatItem(double)=0
virtual void listIntItem(std::int64_t)=0
void streamEnd() override
void mapNoneItem(std::string name) override
void listIntItem(std::int64_t) override
virtual void mapListItem(std::string name)=0
virtual void listListItem()=0
void mapIntItem(std::string name, std::int64_t) override
virtual void mapStringItem(std::string name, std::string)=0
virtual void streamMessage()=0
void listFloatItem(double) override
void streamMessage() override
void listListItem() override
virtual void mapMapItem(std::string name)=0
void mapStringItem(std::string name, std::string) override
virtual void mapFloatItem(std::string name, double)=0
virtual void streamEnd()=0
virtual void listStringItem(std::string)=0
void listStringItem(std::string) override
virtual void mapIntItem(std::string name, std::int64_t)=0
virtual void mapNoneItem(std::string name)=0
virtual void listMapItem()=0
virtual void listNoneItem()=0
static std::string escape(const std::string &)
virtual void streamBegin()=0
void mapFloatItem(std::string name, double) override
void mapListItem(std::string name) override