30 |
32 |
31 class YAMLCommand { |
33 class YAMLCommand { |
32 private: |
34 private: |
33 std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings. |
35 std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings. |
34 |
36 |
|
37 class YAMLEvent { |
|
38 private: |
|
39 yaml_event_t event; |
|
40 public: |
|
41 |
|
42 YAMLEvent(yaml_event_t event) : event(event) { |
|
43 } |
|
44 |
|
45 virtual ~YAMLEvent() { |
|
46 yaml_event_delete(&event); |
|
47 } |
|
48 |
|
49 const yaml_event_type_t getType() const { |
|
50 return event.type; |
|
51 } |
|
52 |
|
53 const yaml_event_t* getEvent() const { |
|
54 return &event; |
|
55 } |
|
56 |
|
57 YAMLEvent(const YAMLEvent&) = delete; |
|
58 YAMLEvent& operator=(const YAMLEvent&) = delete; |
|
59 }; |
|
60 |
|
61 class YAMLParser { |
|
62 private: |
|
63 yaml_parser_t yamlParser; |
|
64 std::istream* input = nullptr; |
|
65 |
|
66 static int readFromInput(void* instance, unsigned char* buffer, size_t size, size_t* length) { |
|
67 std::istream* input = ((YAMLParser*) instance)->input; |
|
68 input->read((char*) buffer, size); |
|
69 *length = input->gcount(); |
|
70 return (input->good() || input->eof()) ? 1 : 0; |
|
71 } |
|
72 public: |
|
73 |
|
74 YAMLParser() { |
|
75 yaml_parser_initialize(&yamlParser); |
|
76 } |
|
77 |
|
78 virtual ~YAMLParser() { |
|
79 yaml_parser_delete(&yamlParser); |
|
80 } |
|
81 |
|
82 YAMLParser(const YAMLParser&) = delete; |
|
83 YAMLParser& operator=(const YAMLParser&) = delete; |
|
84 |
|
85 void setInput(std::istream* input) { |
|
86 this->input = input; |
|
87 yaml_parser_set_input(&yamlParser, readFromInput, (void*) this); |
|
88 } |
|
89 |
|
90 YAMLEvent* next() { |
|
91 yaml_event_t event; |
|
92 int result = yaml_parser_parse(&yamlParser, &event); |
|
93 return result == 1 && event.type != yaml_event_type_e::YAML_NO_EVENT ? new YAMLEvent(event) : nullptr; // 1 = OK in yaml.h; YAML_NO_EVENT = end |
|
94 } |
|
95 }; |
|
96 |
|
97 YAMLParser parser; |
|
98 |
|
99 using YAMLEvent_p = std::shared_ptr<YAMLEvent>; |
|
100 |
|
101 enum class Mode { |
|
102 ROOT, |
|
103 RELATIONS_SEQUENCE, |
|
104 MAPPING, |
|
105 MAP_KEY |
|
106 }; |
|
107 |
|
108 std::vector<Mode> mode; |
|
109 |
|
110 /** |
|
111 * Both YAML and XML strings are in UTF-8. |
|
112 */ |
|
113 const char* y2x(yaml_char_t* value) { |
|
114 return value ? (const char*) value : ""; |
|
115 } |
|
116 |
35 public: |
117 public: |
36 |
118 |
|
119 YAMLCommand() { |
|
120 } |
|
121 |
|
122 virtual ~YAMLCommand() { |
|
123 } |
|
124 |
37 void process(std::istream& input, std::shared_ptr<relpipe::writer::RelationalWriter> writer) { |
125 void process(std::istream& input, std::shared_ptr<relpipe::writer::RelationalWriter> writer) { |
|
126 parser.setInput(&input); |
|
127 |
38 std::vector<relpipe::writer::AttributeMetadata> attributesMetadata; |
128 std::vector<relpipe::writer::AttributeMetadata> attributesMetadata; |
39 attributesMetadata.push_back(relpipe::writer::AttributeMetadata{L"todo", relpipe::writer::TypeId::STRING}); |
129 attributesMetadata.push_back(relpipe::writer::AttributeMetadata{L"todo", relpipe::writer::TypeId::STRING}); |
40 writer->startRelation(L"YAML", attributesMetadata, true); |
130 writer->startRelation(L"YAML", attributesMetadata, true); |
|
131 |
|
132 mode.push_back(Mode::ROOT); |
|
133 std::string itemName; |
|
134 |
|
135 writer->writeAttribute(L"before cycle"); |
|
136 for (YAMLEvent_p event = YAMLEvent_p(parser.next()); event; event = YAMLEvent_p(parser.next())) { |
|
137 |
|
138 if (event->getType() == YAML_NO_EVENT) { writer->writeAttribute(L"YAML_NO_EVENT"); |
|
139 } else if (event->getType() == YAML_STREAM_START_EVENT) { writer->writeAttribute(L"YAML_STREAM_START_EVENT"); |
|
140 } else if (event->getType() == YAML_STREAM_END_EVENT) { writer->writeAttribute(L"YAML_STREAM_END_EVENT"); |
|
141 } else if (event->getType() == YAML_DOCUMENT_START_EVENT) { writer->writeAttribute(L"YAML_DOCUMENT_START_EVENT"); |
|
142 } else if (event->getType() == YAML_DOCUMENT_END_EVENT) { writer->writeAttribute(L"YAML_DOCUMENT_END_EVENT"); |
|
143 } else if (event->getType() == YAML_ALIAS_EVENT) { writer->writeAttribute(L"YAML_ALIAS_EVENT"); |
|
144 } else if (event->getType() == YAML_SCALAR_EVENT) { writer->writeAttribute(L"YAML_SCALAR_EVENT"); |
|
145 } else if (event->getType() == YAML_SEQUENCE_START_EVENT) { writer->writeAttribute(L"YAML_SEQUENCE_START_EVENT"); |
|
146 } else if (event->getType() == YAML_SEQUENCE_END_EVENT) { writer->writeAttribute(L"YAML_SEQUENCE_END_EVENT"); |
|
147 } else if (event->getType() == YAML_MAPPING_START_EVENT) { writer->writeAttribute(L"YAML_MAPPING_START_EVENT"); |
|
148 } else if (event->getType() == YAML_MAPPING_END_EVENT) { writer->writeAttribute(L"YAML_MAPPING_END_EVENT"); |
|
149 } else { writer->writeAttribute(L"else???"); |
|
150 // TODO: unsupported type? |
|
151 } |
|
152 } |
|
153 writer->writeAttribute(L"after cycle"); |
41 } |
154 } |
42 }; |
155 }; |
43 |
156 |
44 } |
157 } |
45 } |
158 } |