2
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
3
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* Additional permission under GNU GPL version 3 section 7:
21
* If you modify this program, or any covered work, by linking or
22
* combining it with the OpenSSL project's OpenSSL library (or a
23
* modified version of that library), containing parts covered by the
24
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
25
* grants you additional permission to convey the resulting work.
26
* Corresponding Source for a non-source form of such a combination
27
* shall include the source code for the parts of OpenSSL used as well
28
* as that of the covered work.
31
#include "yamlparser.h"
33
#include "../global.h"
40
YamlParser::YamlParser(const char *file) : filename_(file)
41
, fd_(fopen(filename_.c_str(), "rb"))
47
, accountSequence_(NULL)
48
, preferenceNode_(NULL)
49
, addressbookNode_(NULL)
56
throw YamlParserException("Could not open file descriptor");
58
if (!yaml_parser_initialize(&parser_))
59
throw YamlParserException("Could not initialize");
61
yaml_parser_set_input_file(&parser_, fd_);
64
YamlParser::~YamlParser()
68
yaml_parser_delete(&parser_);
71
for (int i = 0; i < eventNumber_; ++i)
72
yaml_event_delete(&events_[i]);
75
doc_->deleteChildNodes();
80
void YamlParser::serializeEvents()
83
yaml_event_t event, copiedEvent;
86
if (!yaml_parser_parse(&parser_, &event))
87
throw YamlParserException("Error while parsing");
89
done = (event.type == YAML_STREAM_END_EVENT);
91
copyEvent(&copiedEvent, &event);
93
events_.push_back(copiedEvent);
97
yaml_event_delete(&event);
102
void YamlParser::copyEvent(yaml_event_t *event_to, yaml_event_t *event_from)
104
switch (event_from->type) {
105
case YAML_STREAM_START_EVENT: {
106
if (yaml_stream_start_event_initialize(event_to,
107
event_from->data.stream_start.encoding) == 0)
108
throw YamlParserException("Error stream start event");
113
case YAML_STREAM_END_EVENT: {
114
if (yaml_stream_end_event_initialize(event_to) == 0)
115
throw YamlParserException("Error stream end event");
120
case YAML_DOCUMENT_START_EVENT: {
121
if (yaml_document_start_event_initialize(event_to,
122
event_from->data.document_start.version_directive,
123
event_from->data.document_start.tag_directives.start,
124
event_from->data.document_start.tag_directives.end,
125
event_from->data.document_start.implicit) == 0)
126
throw YamlParserException("Error document start event");
131
case YAML_DOCUMENT_END_EVENT: {
132
if (yaml_document_end_event_initialize(event_to,
133
event_from->data.document_end.implicit) == 0)
134
throw YamlParserException("Error document end event");
138
case YAML_ALIAS_EVENT: {
139
if (yaml_alias_event_initialize(event_to,
140
event_from->data.alias.anchor) == 0)
141
throw YamlParserException("Error alias event initialize");
145
case YAML_SCALAR_EVENT: {
146
if (yaml_scalar_event_initialize(event_to,
147
event_from->data.scalar.anchor,
148
event_from->data.scalar.tag,
149
event_from->data.scalar.value,
150
event_from->data.scalar.length,
151
event_from->data.scalar.plain_implicit,
152
event_from->data.scalar.quoted_implicit,
153
event_from->data.scalar.style) == 0)
154
throw YamlParserException("Error scalar event initialize");
158
case YAML_SEQUENCE_START_EVENT: {
159
if (yaml_sequence_start_event_initialize(event_to,
160
event_from->data.sequence_start.anchor,
161
event_from->data.sequence_start.tag,
162
event_from->data.sequence_start.implicit,
163
event_from->data.sequence_start.style) == 0)
164
throw YamlParserException("Error sequence start event");
168
case YAML_SEQUENCE_END_EVENT: {
169
if (yaml_sequence_end_event_initialize(event_to) == 0)
170
throw YamlParserException("Error sequence end event");
174
case YAML_MAPPING_START_EVENT: {
175
if (yaml_mapping_start_event_initialize(event_to,
176
event_from->data.mapping_start.anchor,
177
event_from->data.mapping_start.tag,
178
event_from->data.mapping_start.implicit,
179
event_from->data.mapping_start.style) == 0)
180
throw YamlParserException("Error mapping start event");
183
case YAML_MAPPING_END_EVENT: {
184
if (yaml_mapping_end_event_initialize(event_to) == 0)
185
throw YamlParserException("Error mapping end event");
195
YamlDocument *YamlParser::composeEvents()
197
if (eventNumber_ == 0)
198
throw YamlParserException("No event available");
200
if (events_[0].type != YAML_STREAM_START_EVENT)
201
throw YamlParserException("Parsing does not start with stream start");
210
void YamlParser::processStream()
212
for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_STREAM_END_EVENT); ++eventIndex_)
213
if (events_[eventIndex_].type == YAML_DOCUMENT_START_EVENT)
216
if (events_[eventIndex_].type != YAML_STREAM_END_EVENT)
217
throw YamlParserException("Did not found end of stream");
220
void YamlParser::processDocument()
222
doc_ = new YamlDocument();
225
throw YamlParserException("Not able to create new document");
227
for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_DOCUMENT_END_EVENT); ++eventIndex_) {
228
switch (events_[eventIndex_].type) {
229
case YAML_SCALAR_EVENT:
230
processScalar((YamlNode *) doc_);
232
case YAML_SEQUENCE_START_EVENT:
233
processSequence((YamlNode *) doc_);
235
case YAML_MAPPING_START_EVENT:
236
processMapping((YamlNode *) doc_);
243
if (events_[eventIndex_].type != YAML_DOCUMENT_END_EVENT)
244
throw YamlParserException("Did not found end of document");
248
void YamlParser::processScalar(YamlNode *topNode)
251
throw YamlParserException("No container for scalar");
253
ScalarNode *sclr = new ScalarNode(std::string((const char*)events_[eventIndex_].data.scalar.value), topNode);
255
switch (topNode->getType()) {
257
((YamlDocument *)(topNode))->addNode(sclr);
260
((SequenceNode *)(topNode))->addNode(sclr);
263
((MappingNode *)(topNode))->addNode(sclr);
271
void YamlParser::processSequence(YamlNode *topNode)
274
throw YamlParserException("No container for sequence");
276
SequenceNode *seq = new SequenceNode(topNode);
278
switch (topNode->getType()) {
280
((YamlDocument *)(topNode))->addNode(seq);
283
((SequenceNode *)(topNode))->addNode(seq);
286
((MappingNode *)(topNode))->addNode(seq);
294
for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_SEQUENCE_END_EVENT); ++eventIndex_) {
295
switch (events_[eventIndex_].type) {
296
case YAML_SCALAR_EVENT:
299
case YAML_SEQUENCE_START_EVENT:
300
processSequence(seq);
302
case YAML_MAPPING_START_EVENT:
310
if (events_[eventIndex_].type != YAML_SEQUENCE_END_EVENT)
311
throw YamlParserException("Did not found end of sequence");
315
void YamlParser::processMapping(YamlNode *topNode)
318
throw YamlParserException("No container for mapping");
320
MappingNode *map = new MappingNode(topNode);
322
switch (topNode->getType()) {
324
((YamlDocument *)(topNode))->addNode(map);
327
((SequenceNode *)(topNode))->addNode(map);
330
((MappingNode *)(topNode))->addNode(map);
338
while ((eventIndex_ < eventNumber_) && (events_[eventIndex_].type != YAML_MAPPING_END_EVENT)) {
340
if (events_[eventIndex_].type != YAML_SCALAR_EVENT)
341
throw YamlParserException("Mapping not followed by a key");
343
map->setTmpKey(std::string((const char *)events_[eventIndex_].data.scalar.value));
346
switch (events_[eventIndex_].type) {
347
case YAML_SCALAR_EVENT:
350
case YAML_SEQUENCE_START_EVENT:
351
processSequence(map);
353
case YAML_MAPPING_START_EVENT:
363
if (events_[eventIndex_].type != YAML_MAPPING_END_EVENT)
364
throw YamlParserException("Did not found end of mapping");
367
void YamlParser::constructNativeData()
369
Sequence *seq = doc_->getSequence();
371
for (Sequence::iterator iter = seq->begin(); iter != seq->end(); ++iter) {
372
switch ((*iter)->getType()) {
374
throw YamlParserException("No scalar allowed at document level, expect a mapping");
377
throw YamlParserException("No sequence allowed at document level, expect a mapping");
380
MappingNode *map = (MappingNode *)(*iter);
381
mainNativeDataMapping(map);
385
throw YamlParserException("Unknown type in configuration file, expect a mapping");
391
void YamlParser::mainNativeDataMapping(MappingNode *map)
393
Mapping *mapping = map->getMapping();
395
accountSequence_ = (SequenceNode*)(*mapping)["accounts"];
396
addressbookNode_ = (MappingNode*)(*mapping)["addressbook"];
397
audioNode_ = (MappingNode*)(*mapping)["audio"];
398
hooksNode_ = (MappingNode*)(*mapping)["hooks"];
399
preferenceNode_ = (MappingNode*)(*mapping)["preferences"];
400
voiplinkNode_ = (MappingNode*)(*mapping)["voipPreferences"];
401
shortcutNode_ = (MappingNode*)(*mapping)["shortcuts"];