2
* Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 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"
41
YamlParser::YamlParser (const char *file) : filename (file)
42
, accountSequence (NULL)
43
, preferenceSequence (NULL)
44
, addressbookSequence (NULL)
45
, audioSequence (NULL)
46
, hooksSequence (NULL)
47
, voiplinkSequence (NULL)
48
, shortcutSequence (NULL)
50
memset (buffer, 0, PARSER_BUFFERSIZE);
55
YamlParser::~YamlParser()
60
void YamlParser::open()
63
fd = fopen (filename.c_str(), "rb");
66
throw YamlParserException ("Could not open file descriptor");
68
if (!yaml_parser_initialize (&parser))
69
throw YamlParserException ("Could not open file descriptor");
71
yaml_parser_set_input_file (&parser, fd);
74
void YamlParser::close()
77
yaml_parser_delete (&parser);
80
throw YamlParserException ("File descriptor not valid");
84
throw YamlParserException ("Error closing file descriptor");
89
void YamlParser::serializeEvents()
96
if (!yaml_parser_parse (&parser, &event))
97
throw YamlParserException ("Error while parsing");
99
done = (event.type == YAML_STREAM_END_EVENT);
101
if (eventNumber > PARSER_MAXEVENT)
102
throw YamlParserException ("Reached maximum of event");
104
if (!copyEvent (& (events[eventNumber++]), &event))
105
throw YamlParserException ("Error copying event");
111
int YamlParser::copyEvent (yaml_event_t *event_to, yaml_event_t *event_from)
114
switch (event_from->type) {
115
case YAML_STREAM_START_EVENT: {
116
// _debug("YAML_STREAM_START_EVENT");
117
return yaml_stream_start_event_initialize (event_to,
118
event_from->data.stream_start.encoding);
121
case YAML_STREAM_END_EVENT: {
122
//_debug("YAML_STREAM_END_EVENT");
123
return yaml_stream_end_event_initialize (event_to);
126
case YAML_DOCUMENT_START_EVENT: {
127
// _debug("YAML_DOCUMENT_START_EVENT");
128
return yaml_document_start_event_initialize (event_to,
129
event_from->data.document_start.version_directive,
130
event_from->data.document_start.tag_directives.start,
131
event_from->data.document_start.tag_directives.end,
132
event_from->data.document_start.implicit);
135
case YAML_DOCUMENT_END_EVENT: {
136
// _debug("YAML_DOCUMENT_END_EVENT");
137
return yaml_document_end_event_initialize (event_to,
138
event_from->data.document_end.implicit);
140
case YAML_ALIAS_EVENT: {
141
// _debug("YAML_ALIAS_EVENT");
142
return yaml_alias_event_initialize (event_to,
143
event_from->data.alias.anchor);
145
case YAML_SCALAR_EVENT: {
146
// _debug("YAML_SCALAR_EVENT");
147
return yaml_scalar_event_initialize (event_to,
148
event_from->data.scalar.anchor,
149
event_from->data.scalar.tag,
150
event_from->data.scalar.value,
151
event_from->data.scalar.length,
152
event_from->data.scalar.plain_implicit,
153
event_from->data.scalar.quoted_implicit,
154
event_from->data.scalar.style);
156
case YAML_SEQUENCE_START_EVENT: {
157
// _debug("YAML_SEQUENCE_START_EVENT");
158
return yaml_sequence_start_event_initialize (event_to,
159
event_from->data.sequence_start.anchor,
160
event_from->data.sequence_start.tag,
161
event_from->data.sequence_start.implicit,
162
event_from->data.sequence_start.style);
164
case YAML_SEQUENCE_END_EVENT: {
165
// _debug("YAML_SEQUENCE_END_EVENT");
166
return yaml_sequence_end_event_initialize (event_to);
168
case YAML_MAPPING_START_EVENT: {
169
// _debug("YAML_MAPPING_START_EVENT");
170
return yaml_mapping_start_event_initialize (event_to,
171
event_from->data.mapping_start.anchor,
172
event_from->data.mapping_start.tag,
173
event_from->data.mapping_start.implicit,
174
event_from->data.mapping_start.style);
176
case YAML_MAPPING_END_EVENT: {
177
// _debug("YAML_MAPPING_END_EVENT");
178
return yaml_mapping_end_event_initialize (event_to);
190
YamlDocument *YamlParser::composeEvents()
193
// _debug("YamlParser: Compose Events");
195
if (eventNumber == 0)
196
throw YamlParserException ("No event available");
198
if (events[0].type != YAML_STREAM_START_EVENT)
199
throw YamlParserException ("Parsing does not start with stream start");
208
void YamlParser::processStream ()
211
// _debug("YamlParser: process stream");
213
while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_STREAM_END_EVENT)) {
215
if (events[eventIndex].type == YAML_DOCUMENT_START_EVENT)
221
if (events[eventIndex].type != YAML_STREAM_END_EVENT)
222
throw YamlParserException ("Did not found end of stream");
226
void YamlParser::processDocument()
228
// _debug("YamlParser: process document");
230
doc = new YamlDocument();
233
throw YamlParserException ("Not able to create new document");
235
while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_DOCUMENT_END_EVENT)) {
237
switch (events[eventIndex].type) {
238
case YAML_SCALAR_EVENT:
239
processScalar ( (YamlNode *) doc);
241
case YAML_SEQUENCE_START_EVENT:
242
processSequence ( (YamlNode *) doc);
244
case YAML_MAPPING_START_EVENT:
245
processMapping ( (YamlNode *) doc);
254
if (events[eventIndex].type != YAML_DOCUMENT_END_EVENT)
255
throw YamlParserException ("Did not found end of document");
260
void YamlParser::processScalar (YamlNode *topNode)
263
// _debug("YamlParser: process scalar");
266
throw YamlParserException ("No container for scalar");
269
snprintf (buffer, 1000, "%s", events[eventIndex].data.scalar.value);
270
// _debug("and the scalar is: %s", buffer);
272
ScalarNode *sclr = new ScalarNode (buffer, topNode);
274
switch (topNode->getType()) {
276
( (YamlDocument *) (topNode))->addNode (sclr);
279
( (SequenceNode *) (topNode))->addNode (sclr);
282
( (MappingNode *) (topNode))->addNode (sclr);
290
void YamlParser::processSequence (YamlNode *topNode)
292
_debug ("YamlParser: process sequence");
295
throw YamlParserException ("No container for sequence");
297
SequenceNode *seq = new SequenceNode (topNode);
299
switch (topNode->getType()) {
301
( (YamlDocument *) (topNode))->addNode (seq);
304
( (SequenceNode *) (topNode))->addNode (seq);
307
( (MappingNode *) (topNode))->addNode (seq);
315
while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_SEQUENCE_END_EVENT)) {
317
switch (events[eventIndex].type) {
318
case YAML_SCALAR_EVENT:
321
case YAML_SEQUENCE_START_EVENT:
322
processSequence (seq);
324
case YAML_MAPPING_START_EVENT:
325
processMapping (seq);
334
if (events[eventIndex].type != YAML_SEQUENCE_END_EVENT)
335
throw YamlParserException ("Did not found end of sequence");
339
void YamlParser::processMapping (YamlNode *topNode)
341
// _debug("YamlParser: process mapping");
344
throw YamlParserException ("No container for mapping");
346
MappingNode *map = new MappingNode (topNode);
348
switch (topNode->getType()) {
350
( (YamlDocument *) (topNode))->addNode (map);
353
( (SequenceNode *) (topNode))->addNode (map);
356
( (MappingNode *) (topNode))->addNode (map);
364
while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_MAPPING_END_EVENT)) {
366
if (events[eventIndex].type != YAML_SCALAR_EVENT)
367
throw YamlParserException ("Mapping not followed by a key");
370
snprintf (buffer, 1000, "%s", events[eventIndex].data.scalar.value);
371
map->setTmpKey (Key (buffer));
372
// _debug("KEY %s", buffer);
376
switch (events[eventIndex].type) {
377
case YAML_SCALAR_EVENT:
380
case YAML_SEQUENCE_START_EVENT:
381
processSequence (map);
383
case YAML_MAPPING_START_EVENT:
384
processMapping (map);
393
if (events[eventIndex].type != YAML_MAPPING_END_EVENT)
394
throw YamlParserException ("Did not found end of mapping");
397
void YamlParser::constructNativeData()
402
seq = doc->getSequence();
404
Sequence::iterator iter = seq->begin();
406
while (iter != seq->end()) {
408
switch ( (*iter)->getType()) {
410
// _debug("construct scalar");
411
throw YamlParserException ("No scalar allowed at document level, expect a mapping");
414
// _debug("construct sequence");
415
throw YamlParserException ("No sequence allowed at document level, expect a mapping");
418
// _debug("construct mapping");
419
MappingNode *map = (MappingNode *) (*iter);
420
mainNativeDataMapping (map);
424
throw YamlParserException ("Unknown type in configuration file, expect a mapping");
435
void YamlParser::mainNativeDataMapping (MappingNode *map)
439
Mapping::iterator iter = map->getMapping()->begin();
441
Key accounts ("accounts");
442
Key addressbook ("addressbook");
445
Key preferences ("preferences");
446
Key voiplink ("voipPreferences");
447
Key shortcuts ("shortcuts");
449
while (iter != map->getMapping()->end()) {
451
_debug ("Iterating: %s", iter->first.c_str());
453
if (accounts.compare (iter->first) == 0) {
454
_debug ("YamlParser: Adding voip account preferences");
455
accountSequence = (SequenceNode *) (iter->second);
456
} else if (addressbook.compare (iter->first) == 0) {
457
_debug ("YamlParser: Adding addressbook preference");
458
addressbookSequence = (SequenceNode *) (iter->second);
459
} else if (audio.compare (iter->first) == 0) {
460
_debug ("YamlParser: Adding audio preference");
461
audioSequence = (SequenceNode *) (iter->second);
462
} else if (hooks.compare (iter->first) == 0) {
463
_debug ("YamlParser: Adding hooks preference");
464
hooksSequence = (SequenceNode *) (iter->second);
465
} else if (preferences.compare (iter->first) == 0) {
466
_debug ("YamlParser: Adding preference preference");
467
preferenceSequence = (SequenceNode *) (iter->second);
468
} else if (voiplink.compare (iter->first) == 0) {
469
_debug ("YamlParser: Adding voip preference");
470
voiplinkSequence = (SequenceNode *) (iter->second);
471
} else if (shortcuts.compare (iter->first) == 0) {
472
_debug ("YamlParser: Adding shortcut preference");
473
shortcutSequence = (SequenceNode *) (iter->second);
475
throw YamlParserException ("Unknow map key in configuration");