~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/src/config/yamlparser.cpp

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2011-11-25 13:24:12 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20111125132412-dc4qvhyosk74cd42
Tags: 1.0.1-4
Don't assume that arch:all packages will get built (closes: #649726)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 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 <cstdio>
 
37
 
 
38
namespace Conf {
 
39
 
 
40
YamlParser::YamlParser(const char *file) : filename_(file)
 
41
    , fd_(fopen(filename_.c_str(), "rb"))
 
42
    , parser_()
 
43
    , events_()
 
44
    , eventNumber_(0)
 
45
    , doc_(NULL)
 
46
    , eventIndex_(0)
 
47
    , accountSequence_(NULL)
 
48
    , preferenceNode_(NULL)
 
49
    , addressbookNode_(NULL)
 
50
    , audioNode_(NULL)
 
51
    , hooksNode_(NULL)
 
52
    , voiplinkNode_(NULL)
 
53
    , shortcutNode_(NULL)
 
54
{
 
55
    if (!fd_)
 
56
        throw YamlParserException("Could not open file descriptor");
 
57
 
 
58
    if (!yaml_parser_initialize(&parser_))
 
59
        throw YamlParserException("Could not initialize");
 
60
 
 
61
    yaml_parser_set_input_file(&parser_, fd_);
 
62
}
 
63
 
 
64
YamlParser::~YamlParser()
 
65
{
 
66
    if (fd_) {
 
67
        fclose(fd_);
 
68
        yaml_parser_delete(&parser_);
 
69
    }
 
70
 
 
71
    for (int i = 0; i < eventNumber_; ++i)
 
72
        yaml_event_delete(&events_[i]);
 
73
 
 
74
    if (doc_) {
 
75
        doc_->deleteChildNodes();
 
76
        delete doc_;
 
77
    }
 
78
}
 
79
 
 
80
void YamlParser::serializeEvents()
 
81
{
 
82
    bool done = false;
 
83
    yaml_event_t event, copiedEvent;
 
84
 
 
85
    while (not done) {
 
86
        if (!yaml_parser_parse(&parser_, &event))
 
87
            throw YamlParserException("Error while parsing");
 
88
 
 
89
        done = (event.type == YAML_STREAM_END_EVENT);
 
90
 
 
91
        copyEvent(&copiedEvent, &event);
 
92
 
 
93
        events_.push_back(copiedEvent);
 
94
 
 
95
        ++eventNumber_;
 
96
 
 
97
        yaml_event_delete(&event);
 
98
    }
 
99
}
 
100
 
 
101
 
 
102
void YamlParser::copyEvent(yaml_event_t *event_to, yaml_event_t *event_from)
 
103
{
 
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");
 
109
 
 
110
            break;
 
111
        }
 
112
 
 
113
        case YAML_STREAM_END_EVENT: {
 
114
            if (yaml_stream_end_event_initialize(event_to) == 0)
 
115
                throw YamlParserException("Error stream end event");
 
116
 
 
117
            break;
 
118
        }
 
119
 
 
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");
 
127
 
 
128
            break;
 
129
        }
 
130
 
 
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");
 
135
 
 
136
            break;
 
137
        }
 
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");
 
142
 
 
143
            break;
 
144
        }
 
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");
 
155
 
 
156
            break;
 
157
        }
 
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");
 
165
 
 
166
            break;
 
167
        }
 
168
        case YAML_SEQUENCE_END_EVENT: {
 
169
            if (yaml_sequence_end_event_initialize(event_to) == 0)
 
170
                throw YamlParserException("Error sequence end event");
 
171
 
 
172
            break;
 
173
        }
 
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");
 
181
            break;
 
182
        }
 
183
        case YAML_MAPPING_END_EVENT: {
 
184
            if (yaml_mapping_end_event_initialize(event_to) == 0)
 
185
                throw YamlParserException("Error mapping end event");
 
186
 
 
187
            break;
 
188
        }
 
189
        default:
 
190
            break;
 
191
    }
 
192
}
 
193
 
 
194
 
 
195
YamlDocument *YamlParser::composeEvents()
 
196
{
 
197
    if (eventNumber_ == 0)
 
198
        throw YamlParserException("No event available");
 
199
 
 
200
    if (events_[0].type != YAML_STREAM_START_EVENT)
 
201
        throw YamlParserException("Parsing does not start with stream start");
 
202
 
 
203
    eventIndex_ = 0;
 
204
 
 
205
    processStream();
 
206
 
 
207
    return doc_;
 
208
}
 
209
 
 
210
void YamlParser::processStream()
 
211
{
 
212
    for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_STREAM_END_EVENT); ++eventIndex_)
 
213
        if (events_[eventIndex_].type == YAML_DOCUMENT_START_EVENT)
 
214
            processDocument();
 
215
 
 
216
    if (events_[eventIndex_].type != YAML_STREAM_END_EVENT)
 
217
        throw YamlParserException("Did not found end of stream");
 
218
}
 
219
 
 
220
void YamlParser::processDocument()
 
221
{
 
222
    doc_ = new YamlDocument();
 
223
 
 
224
    if (!doc_)
 
225
        throw YamlParserException("Not able to create new document");
 
226
 
 
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_);
 
231
                break;
 
232
            case YAML_SEQUENCE_START_EVENT:
 
233
                processSequence((YamlNode *) doc_);
 
234
                break;
 
235
            case YAML_MAPPING_START_EVENT:
 
236
                processMapping((YamlNode *) doc_);
 
237
                break;
 
238
            default:
 
239
                break;
 
240
        }
 
241
    }
 
242
 
 
243
    if (events_[eventIndex_].type != YAML_DOCUMENT_END_EVENT)
 
244
        throw YamlParserException("Did not found end of document");
 
245
}
 
246
 
 
247
 
 
248
void YamlParser::processScalar(YamlNode *topNode)
 
249
{
 
250
    if (!topNode)
 
251
        throw YamlParserException("No container for scalar");
 
252
 
 
253
    ScalarNode *sclr = new ScalarNode(std::string((const char*)events_[eventIndex_].data.scalar.value), topNode);
 
254
 
 
255
    switch (topNode->getType()) {
 
256
        case DOCUMENT:
 
257
            ((YamlDocument *)(topNode))->addNode(sclr);
 
258
            break;
 
259
        case SEQUENCE:
 
260
            ((SequenceNode *)(topNode))->addNode(sclr);
 
261
            break;
 
262
        case MAPPING:
 
263
            ((MappingNode *)(topNode))->addNode(sclr);
 
264
        case SCALAR:
 
265
        default:
 
266
            break;
 
267
    }
 
268
}
 
269
 
 
270
 
 
271
void YamlParser::processSequence(YamlNode *topNode)
 
272
{
 
273
    if (!topNode)
 
274
        throw YamlParserException("No container for sequence");
 
275
 
 
276
    SequenceNode *seq = new SequenceNode(topNode);
 
277
 
 
278
    switch (topNode->getType()) {
 
279
        case DOCUMENT:
 
280
            ((YamlDocument *)(topNode))->addNode(seq);
 
281
            break;
 
282
        case SEQUENCE:
 
283
            ((SequenceNode *)(topNode))->addNode(seq);
 
284
            break;
 
285
        case MAPPING:
 
286
            ((MappingNode *)(topNode))->addNode(seq);
 
287
        case SCALAR:
 
288
        default:
 
289
            break;
 
290
    }
 
291
 
 
292
    ++eventIndex_;
 
293
 
 
294
    for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_SEQUENCE_END_EVENT); ++eventIndex_) {
 
295
        switch (events_[eventIndex_].type) {
 
296
            case YAML_SCALAR_EVENT:
 
297
                processScalar(seq);
 
298
                break;
 
299
            case YAML_SEQUENCE_START_EVENT:
 
300
                processSequence(seq);
 
301
                break;
 
302
            case YAML_MAPPING_START_EVENT:
 
303
                processMapping(seq);
 
304
                break;
 
305
            default:
 
306
                break;
 
307
        }
 
308
    }
 
309
 
 
310
    if (events_[eventIndex_].type != YAML_SEQUENCE_END_EVENT)
 
311
        throw YamlParserException("Did not found end of sequence");
 
312
 
 
313
}
 
314
 
 
315
void YamlParser::processMapping(YamlNode *topNode)
 
316
{
 
317
    if (!topNode)
 
318
        throw YamlParserException("No container for mapping");
 
319
 
 
320
    MappingNode *map = new MappingNode(topNode);
 
321
 
 
322
    switch (topNode->getType()) {
 
323
        case DOCUMENT:
 
324
            ((YamlDocument *)(topNode))->addNode(map);
 
325
            break;
 
326
        case SEQUENCE:
 
327
            ((SequenceNode *)(topNode))->addNode(map);
 
328
            break;
 
329
        case MAPPING:
 
330
            ((MappingNode *)(topNode))->addNode(map);
 
331
        case SCALAR:
 
332
        default:
 
333
            break;
 
334
    }
 
335
 
 
336
    ++eventIndex_;
 
337
 
 
338
    while ((eventIndex_ < eventNumber_) && (events_[eventIndex_].type != YAML_MAPPING_END_EVENT)) {
 
339
 
 
340
        if (events_[eventIndex_].type != YAML_SCALAR_EVENT)
 
341
            throw YamlParserException("Mapping not followed by a key");
 
342
 
 
343
        map->setTmpKey(std::string((const char *)events_[eventIndex_].data.scalar.value));
 
344
        ++eventIndex_;
 
345
 
 
346
        switch (events_[eventIndex_].type) {
 
347
            case YAML_SCALAR_EVENT:
 
348
                processScalar(map);
 
349
                break;
 
350
            case YAML_SEQUENCE_START_EVENT:
 
351
                processSequence(map);
 
352
                break;
 
353
            case YAML_MAPPING_START_EVENT:
 
354
                processMapping(map);
 
355
                break;
 
356
            default:
 
357
                break;
 
358
        }
 
359
 
 
360
        ++eventIndex_;
 
361
    }
 
362
 
 
363
    if (events_[eventIndex_].type != YAML_MAPPING_END_EVENT)
 
364
        throw YamlParserException("Did not found end of mapping");
 
365
}
 
366
 
 
367
void YamlParser::constructNativeData()
 
368
{
 
369
    Sequence *seq = doc_->getSequence();
 
370
 
 
371
    for (Sequence::iterator iter = seq->begin(); iter != seq->end(); ++iter) {
 
372
        switch ((*iter)->getType()) {
 
373
            case SCALAR:
 
374
                throw YamlParserException("No scalar allowed at document level, expect a mapping");
 
375
                break;
 
376
            case SEQUENCE:
 
377
                throw YamlParserException("No sequence allowed at document level, expect a mapping");
 
378
                break;
 
379
            case MAPPING: {
 
380
                MappingNode *map = (MappingNode *)(*iter);
 
381
                mainNativeDataMapping(map);
 
382
                break;
 
383
            }
 
384
            default:
 
385
                throw YamlParserException("Unknown type in configuration file, expect a mapping");
 
386
                break;
 
387
        }
 
388
    }
 
389
}
 
390
 
 
391
void YamlParser::mainNativeDataMapping(MappingNode *map)
 
392
{
 
393
    Mapping *mapping = map->getMapping();
 
394
 
 
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"];
 
402
}
 
403
}
 
404