~ubuntu-branches/ubuntu/saucy/sflphone/saucy

« back to all changes in this revision

Viewing changes to sflphone-common/src/config/yamlparser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Francois Marier
  • Date: 2010-12-24 16:33:55 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20101224163355-tkvvikqxbrbav6up
Tags: 0.9.11-1
* New upstream release
* Add new build dependencies on libwebkit-dev and libyaml-dev

* Bump Standards-Version up to 3.9.1
* Bump debhelper compatibility to 8
* Patch another typo in the upstream code (lintian notice)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc.
 
3
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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.
 
18
 *
 
19
 *  Additional permission under GNU GPL version 3 section 7:
 
20
 *
 
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.
 
29
 */
 
30
 
 
31
#include "yamlparser.h"
 
32
 
 
33
#include "../global.h"
 
34
#include "config.h"
 
35
#include "yamlnode.h"
 
36
#include <stdio.h>
 
37
 
 
38
namespace Conf
 
39
{
 
40
 
 
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)
 
49
{
 
50
    memset (buffer, 0, PARSER_BUFFERSIZE);
 
51
 
 
52
    open();
 
53
}
 
54
 
 
55
YamlParser::~YamlParser()
 
56
{
 
57
    close();
 
58
}
 
59
 
 
60
void YamlParser::open()
 
61
{
 
62
 
 
63
    fd = fopen (filename.c_str(), "rb");
 
64
 
 
65
    if (!fd)
 
66
        throw YamlParserException ("Could not open file descriptor");
 
67
 
 
68
    if (!yaml_parser_initialize (&parser))
 
69
        throw YamlParserException ("Could not open file descriptor");
 
70
 
 
71
    yaml_parser_set_input_file (&parser, fd);
 
72
}
 
73
 
 
74
void YamlParser::close()
 
75
{
 
76
 
 
77
    yaml_parser_delete (&parser);
 
78
 
 
79
    if (!fd)
 
80
        throw YamlParserException ("File descriptor not valid");
 
81
 
 
82
    // fclose (fd);
 
83
    if (fclose (fd))
 
84
        throw YamlParserException ("Error closing file descriptor");
 
85
 
 
86
 
 
87
}
 
88
 
 
89
void YamlParser::serializeEvents()
 
90
{
 
91
    bool done = false;
 
92
    yaml_event_t event;
 
93
 
 
94
    while (!done) {
 
95
 
 
96
        if (!yaml_parser_parse (&parser, &event))
 
97
            throw YamlParserException ("Error while parsing");
 
98
 
 
99
        done = (event.type == YAML_STREAM_END_EVENT);
 
100
 
 
101
        if (eventNumber > PARSER_MAXEVENT)
 
102
            throw YamlParserException ("Reached maximum of event");
 
103
 
 
104
        if (!copyEvent (& (events[eventNumber++]), &event))
 
105
            throw YamlParserException ("Error copying event");
 
106
 
 
107
    }
 
108
}
 
109
 
 
110
 
 
111
int YamlParser::copyEvent (yaml_event_t *event_to, yaml_event_t *event_from)
 
112
{
 
113
 
 
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);
 
119
        }
 
120
 
 
121
        case YAML_STREAM_END_EVENT: {
 
122
            //_debug("YAML_STREAM_END_EVENT");
 
123
            return yaml_stream_end_event_initialize (event_to);
 
124
        }
 
125
 
 
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);
 
133
        }
 
134
 
 
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);
 
139
        }
 
140
        case YAML_ALIAS_EVENT: {
 
141
            // _debug("YAML_ALIAS_EVENT");
 
142
            return yaml_alias_event_initialize (event_to,
 
143
                                                event_from->data.alias.anchor);
 
144
        }
 
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);
 
155
        }
 
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);
 
163
        }
 
164
        case YAML_SEQUENCE_END_EVENT: {
 
165
            // _debug("YAML_SEQUENCE_END_EVENT");
 
166
            return yaml_sequence_end_event_initialize (event_to);
 
167
        }
 
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);
 
175
        }
 
176
        case YAML_MAPPING_END_EVENT: {
 
177
            // _debug("YAML_MAPPING_END_EVENT");
 
178
            return yaml_mapping_end_event_initialize (event_to);
 
179
 
 
180
        }
 
181
        default:
 
182
            assert (1);
 
183
 
 
184
    }
 
185
 
 
186
    return 0;
 
187
}
 
188
 
 
189
 
 
190
YamlDocument *YamlParser::composeEvents()
 
191
{
 
192
 
 
193
    // _debug("YamlParser: Compose Events");
 
194
 
 
195
    if (eventNumber == 0)
 
196
        throw YamlParserException ("No event available");
 
197
 
 
198
    if (events[0].type != YAML_STREAM_START_EVENT)
 
199
        throw YamlParserException ("Parsing does not start with stream start");
 
200
 
 
201
    eventIndex = 0;
 
202
 
 
203
    processStream();
 
204
 
 
205
    return doc;
 
206
}
 
207
 
 
208
void YamlParser::processStream ()
 
209
{
 
210
 
 
211
    // _debug("YamlParser: process stream");
 
212
 
 
213
    while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_STREAM_END_EVENT)) {
 
214
 
 
215
        if (events[eventIndex].type == YAML_DOCUMENT_START_EVENT)
 
216
            processDocument();
 
217
 
 
218
        eventIndex++;
 
219
    }
 
220
 
 
221
    if (events[eventIndex].type != YAML_STREAM_END_EVENT)
 
222
        throw YamlParserException ("Did not found end of stream");
 
223
}
 
224
 
 
225
 
 
226
void YamlParser::processDocument()
 
227
{
 
228
    // _debug("YamlParser: process document");
 
229
 
 
230
    doc = new YamlDocument();
 
231
 
 
232
    if (!doc)
 
233
        throw YamlParserException ("Not able to create new document");
 
234
 
 
235
    while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_DOCUMENT_END_EVENT)) {
 
236
 
 
237
        switch (events[eventIndex].type) {
 
238
            case YAML_SCALAR_EVENT:
 
239
                processScalar ( (YamlNode *) doc);
 
240
                break;
 
241
            case YAML_SEQUENCE_START_EVENT:
 
242
                processSequence ( (YamlNode *) doc);
 
243
                break;
 
244
            case YAML_MAPPING_START_EVENT:
 
245
                processMapping ( (YamlNode *) doc);
 
246
                break;
 
247
            default:
 
248
                break;
 
249
        }
 
250
 
 
251
        eventIndex++;
 
252
    }
 
253
 
 
254
    if (events[eventIndex].type != YAML_DOCUMENT_END_EVENT)
 
255
        throw YamlParserException ("Did not found end of document");
 
256
 
 
257
}
 
258
 
 
259
 
 
260
void YamlParser::processScalar (YamlNode *topNode)
 
261
{
 
262
 
 
263
    // _debug("YamlParser: process scalar");
 
264
 
 
265
    if (!topNode)
 
266
        throw YamlParserException ("No container for scalar");
 
267
 
 
268
    char buffer[1000];
 
269
    snprintf (buffer, 1000, "%s", events[eventIndex].data.scalar.value);
 
270
    // _debug("and the scalar is: %s", buffer);
 
271
 
 
272
    ScalarNode *sclr = new ScalarNode (buffer, topNode);
 
273
 
 
274
    switch (topNode->getType()) {
 
275
        case DOCUMENT:
 
276
            ( (YamlDocument *) (topNode))->addNode (sclr);
 
277
            break;
 
278
        case SEQUENCE:
 
279
            ( (SequenceNode *) (topNode))->addNode (sclr);
 
280
            break;
 
281
        case MAPPING:
 
282
            ( (MappingNode *) (topNode))->addNode (sclr);
 
283
        case SCALAR:
 
284
        default:
 
285
            break;
 
286
    }
 
287
}
 
288
 
 
289
 
 
290
void YamlParser::processSequence (YamlNode *topNode)
 
291
{
 
292
    _debug ("YamlParser: process sequence");
 
293
 
 
294
    if (!topNode)
 
295
        throw YamlParserException ("No container for sequence");
 
296
 
 
297
    SequenceNode *seq = new SequenceNode (topNode);
 
298
 
 
299
    switch (topNode->getType()) {
 
300
        case DOCUMENT:
 
301
            ( (YamlDocument *) (topNode))->addNode (seq);
 
302
            break;
 
303
        case SEQUENCE:
 
304
            ( (SequenceNode *) (topNode))->addNode (seq);
 
305
            break;
 
306
        case MAPPING:
 
307
            ( (MappingNode *) (topNode))->addNode (seq);
 
308
        case SCALAR:
 
309
        default:
 
310
            break;
 
311
    }
 
312
 
 
313
    eventIndex++;
 
314
 
 
315
    while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_SEQUENCE_END_EVENT)) {
 
316
 
 
317
        switch (events[eventIndex].type) {
 
318
            case YAML_SCALAR_EVENT:
 
319
                processScalar (seq);
 
320
                break;
 
321
            case YAML_SEQUENCE_START_EVENT:
 
322
                processSequence (seq);
 
323
                break;
 
324
            case YAML_MAPPING_START_EVENT:
 
325
                processMapping (seq);
 
326
                break;
 
327
            default:
 
328
                break;
 
329
        }
 
330
 
 
331
        eventIndex++;
 
332
    }
 
333
 
 
334
    if (events[eventIndex].type != YAML_SEQUENCE_END_EVENT)
 
335
        throw YamlParserException ("Did not found end of sequence");
 
336
}
 
337
 
 
338
 
 
339
void YamlParser::processMapping (YamlNode *topNode)
 
340
{
 
341
    // _debug("YamlParser: process mapping");
 
342
 
 
343
    if (!topNode)
 
344
        throw YamlParserException ("No container for mapping");
 
345
 
 
346
    MappingNode *map = new MappingNode (topNode);
 
347
 
 
348
    switch (topNode->getType()) {
 
349
        case DOCUMENT:
 
350
            ( (YamlDocument *) (topNode))->addNode (map);
 
351
            break;
 
352
        case SEQUENCE:
 
353
            ( (SequenceNode *) (topNode))->addNode (map);
 
354
            break;
 
355
        case MAPPING:
 
356
            ( (MappingNode *) (topNode))->addNode (map);
 
357
        case SCALAR:
 
358
        default:
 
359
            break;
 
360
    }
 
361
 
 
362
    eventIndex++;
 
363
 
 
364
    while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_MAPPING_END_EVENT)) {
 
365
 
 
366
        if (events[eventIndex].type != YAML_SCALAR_EVENT)
 
367
            throw YamlParserException ("Mapping not followed by a key");
 
368
 
 
369
        char buffer[1000];
 
370
        snprintf (buffer, 1000, "%s", events[eventIndex].data.scalar.value);
 
371
        map->setTmpKey (Key (buffer));
 
372
        // _debug("KEY %s", buffer);
 
373
 
 
374
        eventIndex++;
 
375
 
 
376
        switch (events[eventIndex].type) {
 
377
            case YAML_SCALAR_EVENT:
 
378
                processScalar (map);
 
379
                break;
 
380
            case YAML_SEQUENCE_START_EVENT:
 
381
                processSequence (map);
 
382
                break;
 
383
            case YAML_MAPPING_START_EVENT:
 
384
                processMapping (map);
 
385
                break;
 
386
            default:
 
387
                break;
 
388
        }
 
389
 
 
390
        eventIndex++;
 
391
    }
 
392
 
 
393
    if (events[eventIndex].type != YAML_MAPPING_END_EVENT)
 
394
        throw YamlParserException ("Did not found end of mapping");
 
395
}
 
396
 
 
397
void YamlParser::constructNativeData()
 
398
{
 
399
 
 
400
    Sequence *seq;
 
401
 
 
402
    seq = doc->getSequence();
 
403
 
 
404
    Sequence::iterator iter = seq->begin();
 
405
 
 
406
    while (iter != seq->end()) {
 
407
 
 
408
        switch ( (*iter)->getType()) {
 
409
            case SCALAR:
 
410
                // _debug("construct scalar");
 
411
                throw YamlParserException ("No scalar allowed at document level, expect a mapping");
 
412
                break;
 
413
            case SEQUENCE:
 
414
                // _debug("construct sequence");
 
415
                throw YamlParserException ("No sequence allowed at document level, expect a mapping");
 
416
                break;
 
417
            case MAPPING: {
 
418
                // _debug("construct mapping");
 
419
                MappingNode *map = (MappingNode *) (*iter);
 
420
                mainNativeDataMapping (map);
 
421
                break;
 
422
            }
 
423
            default:
 
424
                throw YamlParserException ("Unknown type in configuration file, expect a mapping");
 
425
                break;
 
426
        }
 
427
 
 
428
        iter++;
 
429
 
 
430
    }
 
431
 
 
432
}
 
433
 
 
434
 
 
435
void YamlParser::mainNativeDataMapping (MappingNode *map)
 
436
{
 
437
 
 
438
 
 
439
    Mapping::iterator iter = map->getMapping()->begin();
 
440
 
 
441
    Key accounts ("accounts");
 
442
    Key addressbook ("addressbook");
 
443
    Key audio ("audio");
 
444
    Key hooks ("hooks");
 
445
    Key preferences ("preferences");
 
446
    Key voiplink ("voipPreferences");
 
447
    Key shortcuts ("shortcuts");
 
448
 
 
449
    while (iter != map->getMapping()->end()) {
 
450
 
 
451
        _debug ("Iterating: %s", iter->first.c_str());
 
452
 
 
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);
 
474
        } else
 
475
            throw YamlParserException ("Unknow map key in configuration");
 
476
 
 
477
        iter++;
 
478
    }
 
479
 
 
480
    // _debug("Done");
 
481
}
 
482
 
 
483
}