18 |
18 |
19 namespace relpipe { |
19 namespace relpipe { |
20 namespace in { |
20 namespace in { |
21 namespace xmltable { |
21 namespace xmltable { |
22 |
22 |
|
23 #include <codecvt> |
|
24 |
23 #include <libxml++-2.6/libxml++/libxml++.h> |
25 #include <libxml++-2.6/libxml++/libxml++.h> |
|
26 #include <yaml.h> |
24 |
27 |
25 class XMLDocumentConstructor { |
28 class XMLDocumentConstructor { |
26 private: |
29 private: |
27 std::istream* input = nullptr; |
30 std::istream* input = nullptr; |
28 xmlpp::DomParser* parser = nullptr; |
31 xmlpp::DomParser* parser = nullptr; |
|
32 yaml_parser_t yamlParser; |
|
33 |
|
34 static int readFromInput(void* instance, unsigned char* buffer, size_t size, size_t* length) { |
|
35 std::istream* input = ((XMLDocumentConstructor*) instance)->input; |
|
36 input->read((char*) buffer, size); |
|
37 *length = input->gcount(); |
|
38 return (input->good() || input->eof()) ? 1 : 0; |
|
39 } |
|
40 |
|
41 /** |
|
42 * Both YAML and XML strings are in UTF-8. |
|
43 */ |
|
44 const char* y2x(yaml_char_t* value) { |
|
45 return value ? (const char*) value : ""; |
|
46 } |
|
47 |
29 public: |
48 public: |
30 |
49 |
31 XMLDocumentConstructor(std::istream* input, xmlpp::DomParser* parser) : input(input), parser(parser) { |
50 XMLDocumentConstructor(std::istream* input, xmlpp::DomParser* parser) : input(input), parser(parser) { |
|
51 yaml_parser_initialize(&yamlParser); |
|
52 yaml_parser_set_input(&yamlParser, readFromInput, (void*) this); |
|
53 } |
|
54 |
|
55 virtual ~XMLDocumentConstructor() { |
|
56 yaml_parser_delete(&yamlParser); |
32 } |
57 } |
33 |
58 |
34 void process() { |
59 void process() { |
35 parser->parse_stream(*input); |
60 xmlpp::Element* root = parser->get_document()->create_root_node("yaml"); |
|
61 |
|
62 while (true) { |
|
63 yaml_event_t event; |
|
64 |
|
65 if (!yaml_parser_parse(&yamlParser, &event)) { |
|
66 // FIXME: throw exception |
|
67 std::wcerr << L"YAML error" << std::endl; |
|
68 return; |
|
69 } |
|
70 |
|
71 |
|
72 if (event.type == YAML_STREAM_END_EVENT) { |
|
73 xmlpp::Element* e = root->add_child("YAML_STREAM_END_EVENT"); |
|
74 yaml_event_delete(&event); |
|
75 break; |
|
76 } else if (event.type == YAML_STREAM_START_EVENT) { |
|
77 xmlpp::Element* e = root->add_child("YAML_STREAM_START_EVENT"); |
|
78 } else if (event.type == YAML_NO_EVENT) { |
|
79 xmlpp::Element* e = root->add_child("YAML_NO_EVENT"); |
|
80 } else if (event.type == YAML_DOCUMENT_START_EVENT) { |
|
81 xmlpp::Element* e = root->add_child("YAML_DOCUMENT_START_EVENT"); |
|
82 } else if (event.type == YAML_DOCUMENT_END_EVENT) { |
|
83 xmlpp::Element* e = root->add_child("YAML_DOCUMENT_END_EVENT"); |
|
84 } else if (event.type == YAML_ALIAS_EVENT) { |
|
85 xmlpp::Element* e = root->add_child("YAML_ALIAS_EVENT"); |
|
86 } else if (event.type == YAML_SCALAR_EVENT) { |
|
87 xmlpp::Element* e = root->add_child("YAML_SCALAR_EVENT"); |
|
88 e->set_attribute("value", y2x(event.data.scalar.value)); |
|
89 e->set_attribute("anchor", y2x(event.data.scalar.anchor)); |
|
90 e->set_attribute("tag", y2x(event.data.scalar.tag)); |
|
91 e->set_attribute("style", std::to_string(event.data.scalar.style)); |
|
92 } else if (event.type == YAML_SEQUENCE_START_EVENT) { |
|
93 xmlpp::Element* e = root->add_child("YAML_SEQUENCE_START_EVENT"); |
|
94 e->set_attribute("style", std::to_string(event.data.sequence_start.style)); |
|
95 } else if (event.type == YAML_SEQUENCE_END_EVENT) { |
|
96 xmlpp::Element* e = root->add_child("YAML_SEQUENCE_END_EVENT"); |
|
97 } else if (event.type == YAML_MAPPING_START_EVENT) { |
|
98 xmlpp::Element* e = root->add_child("YAML_MAPPING_START_EVENT"); |
|
99 } else if (event.type == YAML_MAPPING_END_EVENT) { |
|
100 xmlpp::Element* e = root->add_child("YAML_MAPPING_END_EVENT"); |
|
101 } |
|
102 |
|
103 yaml_event_delete(&event); |
|
104 } |
|
105 |
|
106 |
36 } |
107 } |
37 }; |
108 }; |
38 |
109 |
39 } |
110 } |
40 } |
111 } |