src/XMLDocumentConstructor.h
branchv_0
changeset 16 3b197bf7a231
parent 14 5be268bc4c69
child 17 75c6685cceb9
equal deleted inserted replaced
15:66db59d77033 16:3b197bf7a231
    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 }