diff --git a/sflphone-common/src/config/yamlnode.cpp b/sflphone-common/src/config/yamlnode.cpp index ebfb8f245c6e17209cd63e4eeb5f55f05a8133de..51c4c97ee388417faec1e68e205af2dfe8dc7e57 100755 --- a/sflphone-common/src/config/yamlnode.cpp +++ b/sflphone-common/src/config/yamlnode.cpp @@ -50,6 +50,12 @@ YamlNode *YamlDocument::popNode() return node; } +void MappingNode::addNode(YamlNode *node) +{ + Mapping::iterator it = map.end(); + map.insert(it, std::pair<Key, YamlNode *>(tmpKey, node)); +} + void MappingNode::setKeyValue(Key key, YamlNode *value) { Mapping::iterator it = map.end(); diff --git a/sflphone-common/src/config/yamlnode.h b/sflphone-common/src/config/yamlnode.h index 934b82faec0a04581eec239e75af6daca4831d47..4b8ae443acf5c4854a4bf428d1bcae17d717770b 100755 --- a/sflphone-common/src/config/yamlnode.h +++ b/sflphone-common/src/config/yamlnode.h @@ -135,6 +135,10 @@ class MappingNode : public YamlNode { Mapping *getMapping() { return ↦ } + void addNode(YamlNode *node); + + void setTmpKey(Key key) { tmpKey = key; } + void setKeyValue(Key key, YamlNode *value); void removeKeyValue(Key key); @@ -145,6 +149,8 @@ class MappingNode : public YamlNode { Mapping map; + Key tmpKey; + }; diff --git a/sflphone-common/src/config/yamlparser.cpp b/sflphone-common/src/config/yamlparser.cpp index 7090bea7aecb1720eab19e6c3f48598aee4c565e..ba0f0d24bcc14409ea94b45935884be85dc5cd01 100755 --- a/sflphone-common/src/config/yamlparser.cpp +++ b/sflphone-common/src/config/yamlparser.cpp @@ -182,24 +182,18 @@ YamlDocument *YamlParser::composeEvents() { if(eventNumber == 0) throw YamlParserException("No event available"); - doc = NULL; - topNode = NULL; + if(events[0].type != YAML_STREAM_START_EVENT) + throw YamlParserException("Parsing does not start with stream start"); + eventIndex = 0; + + processStream(); + + /* for (int i = 0; i < eventNumber;) { switch(events[i].type) { - case YAML_STREAM_START_EVENT: - _debug("YAML_STREAM_START_EVENT"); - break; - case YAML_STREAM_END_EVENT: - _debug("YAML_STREAM_END_EVENT"); - break; - case YAML_DOCUMENT_START_EVENT: { - _debug("YAML_DOCUMENT_START_EVENT"); - // startDocument(); - break; - } - case YAML_DOCUMENT_END_EVENT: { + _debug("YAML_DOCUMENT_END_EVENT"); // topNode = NULL; break; @@ -209,9 +203,11 @@ YamlDocument *YamlParser::composeEvents() { break; case YAML_SCALAR_EVENT: { _debug("YAML_SCALAR_EVENT: anchor %s, tag %s, value %s", events[i].data.scalar.anchor, events[i].data.scalar.tag, events[i].data.scalar.value); + char buffer[1000]; snprintf(buffer, 1000, "%s", events[i].data.scalar.value); composeScalarEvent(topNode, buffer); + break; } case YAML_SEQUENCE_START_EVENT: { @@ -226,7 +222,7 @@ YamlDocument *YamlParser::composeEvents() { } case YAML_MAPPING_START_EVENT: { _debug("YAML_MAPPING_START_EVENT: anchor %s, tag %s", events[i].data.mapping_start.anchor, events[i].data.sequence_start.tag); - + Key mapkey; YamlNode *mapvalue; @@ -256,7 +252,7 @@ YamlDocument *YamlParser::composeEvents() { } else throw YamlParserException("Not acceptable value for mapping"); - + break; } case YAML_MAPPING_END_EVENT: { @@ -270,73 +266,67 @@ YamlDocument *YamlParser::composeEvents() { i++; } - + */ return doc; } +void YamlParser::processStream () { -void YamlParser::startDocument() -{ - doc = new YamlDocument(); + while((eventIndex < eventNumber) && (events[eventIndex].type != YAML_STREAM_END_EVENT)) { - if(!doc) - throw YamlParserException("Not able to create new document"); - - topNode = (YamlNode *)(doc); -} - -void YamlParser::endDocument() -{ - if(!doc || !topNode) - throw YamlParserException("No document to end"); + if(events[eventIndex].type == YAML_DOCUMENT_START_EVENT) + processDocument(); - if(topNode->getType() != DOCUMENT) - throw YamlParserException("Top node is not a document"); + eventIndex++; + } - topNode = NULL; + if(events[eventIndex].type != YAML_STREAM_END_EVENT) + throw YamlParserException("Did not found end of stream"); } -void YamlParser::startSequence() -{ - if(!topNode) - throw YamlParserException("No container for sequence"); - SequenceNode *seq = new SequenceNode(topNode); - - composeSequence(); - topNode = (YamlNode *)seq; -} - -void YamlParser::endSequence() +void YamlParser::processDocument() { - if(!topNode) - throw YamlParserException("No sequence to stop"); - - if(topNode->getType() != SEQUENCE) - throw YamlParserException("Top node is not a sequence"); - - - topNode = topNode->getTopNode(); -} + doc = new YamlDocument(); -void YamlParser::endMapping() { + if(!doc) + throw YamlParserException("Not able to create new document"); - if(!topNode) - throw YamlParserException("No mapping to stop"); + while((eventIndex < eventNumber) && (events[eventIndex].type != YAML_DOCUMENT_END_EVENT)) { - if(topNode->getType() != MAPPING) - throw YamlParserException("Top node is not a mapping"); + switch(events[eventIndex].type){ + case YAML_SCALAR_EVENT: + processScalar((YamlNode *)doc); + break; + case YAML_SEQUENCE_START_EVENT: + processSequence((YamlNode *)doc); + break; + case YAML_MAPPING_START_EVENT: + processMapping((YamlNode *)doc); + break; + default: + break; + } - topNode = topNode->getTopNode(); + eventIndex++; + } + if(events[eventIndex].type != YAML_DOCUMENT_END_EVENT) + throw YamlParserException("Did not found end of document"); + } -void YamlParser::composeScalarEvent(YamlNode *topNode, char *data) + +void YamlParser::processScalar(YamlNode *topNode) { + if(!topNode) throw YamlParserException("No container for scalar"); - ScalarNode *sclr = new ScalarNode(data, topNode); + char buffer[1000]; + snprintf(buffer, 1000, "%s", events[eventIndex].data.scalar.value); + + ScalarNode *sclr = new ScalarNode(buffer, topNode); switch(topNode->getType()) { case DOCUMENT: @@ -345,58 +335,111 @@ void YamlParser::composeScalarEvent(YamlNode *topNode, char *data) case SEQUENCE: ((SequenceNode *)(topNode))->addNode(sclr); break; - case SCALAR: case MAPPING: + ((MappingNode *)(topNode))->addNode(sclr); + case SCALAR: default: break; } - } -void YamlParser::composeMappingEvent(MappingNode *map, Key key, YamlNode *val) +void YamlParser::processSequence(YamlNode *topNode) { - YamlNode *topNode = map->getTopNode(); - if(!topNode) - throw YamlParserException("No container for mapping"); + throw YamlParserException("No container for sequence"); - map->setKeyValue(key, val); + SequenceNode *seq = new SequenceNode(topNode); switch(topNode->getType()) { case DOCUMENT: - ((YamlDocument *)(topNode))->addNode(map); + ((YamlDocument *)(topNode))->addNode(seq); break; case SEQUENCE: - ((SequenceNode *)(topNode))->addNode(map); + ((SequenceNode *)(topNode))->addNode(seq); break; - case SCALAR: case MAPPING: + ((MappingNode *)(topNode))->addNode(seq); + case SCALAR: default: break; } + while((eventIndex < eventNumber) < (events[eventIndex].type != YAML_SEQUENCE_END_EVENT)) { + + switch(events[eventIndex].type){ + case YAML_SCALAR_EVENT: + processScalar(seq); + break; + case YAML_SEQUENCE_START_EVENT: + processSequence(seq); + break; + case YAML_MAPPING_START_EVENT: + processMapping(seq); + break; + default: + break; + } + + eventIndex++; + } + + if(events[eventIndex].type != YAML_SEQUENCE_END_EVENT) + throw YamlParserException("Did not found end of sequence"); } -void YamlParser::composeSequenceEvent(YamlNode *topNode, YamlNode *node) -{ +void YamlParser::processMapping(YamlNode *topNode) +{ if(!topNode) - throw YamlParserException("No container for sequence"); + throw YamlParserException("No container for mapping"); + + MappingNode *map = new MappingNode(topNode); switch(topNode->getType()) { case DOCUMENT: - ((YamlDocument *)(topNode))->addNode(node); + ((YamlDocument *)(topNode))->addNode(map); break; case SEQUENCE: - ((SequenceNode *)(topNode))->addNode(node); + ((SequenceNode *)(topNode))->addNode(map); break; - case SCALAR: case MAPPING: + ((MappingNode *)(topNode))->addNode(map); + case SCALAR: default: break; } + while((eventIndex < eventNumber) < (events[eventIndex].type != YAML_MAPPING_END_EVENT)) { + + if(events[eventIndex].type != YAML_SCALAR_EVENT) + throw YamlParserException("Mapping not followed by a key"); + + char buffer[1000]; + snprintf(buffer, 1000, "%s", events[eventIndex].data.scalar.value); + map->setTmpKey(Key(buffer)); + + eventIndex++; + + switch(events[eventIndex].type){ + case YAML_SCALAR_EVENT: + processScalar(map); + break; + case YAML_SEQUENCE_START_EVENT: + processSequence(map); + break; + case YAML_MAPPING_START_EVENT: + processMapping(map); + break; + default: + break; + } + + eventIndex++; + } + + if(events[eventIndex].type != YAML_MAPPING_END_EVENT) + throw YamlParserException("Did not found end of mapping"); } } diff --git a/sflphone-common/src/config/yamlparser.h b/sflphone-common/src/config/yamlparser.h index 35c18fb8db20991a343180a74d49dced32822491..701dc46b479f278b0e2278245376e823bcff0efe 100755 --- a/sflphone-common/src/config/yamlparser.h +++ b/sflphone-common/src/config/yamlparser.h @@ -83,21 +83,15 @@ class YamlParser { */ int copyEvent(yaml_event_t *event_to, yaml_event_t *event_from); - void startDocument(void); + void processStream(void); - void endDocument(void); + void processDocument(void); - void startSequence(void); + void processScalar(YamlNode *topNode); - void endSequence(void); + void processSequence(YamlNode *topNode); - void endMapping(void); - - void composeScalarEvent(YamlNode *topNode, char *data); - - void composeMappingEvent(MappingNode *map, Key key, YamlNode *node); - - void composeSequenceEvent(YamlNode *topNode, YamlNode *node); + void processMapping(YamlNode *topNode); std::string filename; @@ -123,10 +117,10 @@ class YamlParser { */ int eventNumber; - YamlNode *topNode; - YamlDocument *doc; + int eventIndex; + }; } diff --git a/sflphone-common/test/configurationtest.cpp b/sflphone-common/test/configurationtest.cpp index 68c0356aed33330c4685792098d57d8f5485ada2..03ab6c2de35d9e26184fc08a8454f2c1a0a60771 100755 --- a/sflphone-common/test/configurationtest.cpp +++ b/sflphone-common/test/configurationtest.cpp @@ -158,7 +158,7 @@ void ConfigurationTest::testYamlParser() Conf::YamlParser *parser; try { - parser = new Conf::YamlParser("sequence.yml"); + parser = new Conf::YamlParser("sequence2.yml"); parser->serializeEvents(); diff --git a/sflphone-common/test/sequence.yml b/sflphone-common/test/sequence.yml new file mode 100755 index 0000000000000000000000000000000000000000..9cb54dd63661ab25b6255cb23ae414259c8bb91f --- /dev/null +++ b/sflphone-common/test/sequence.yml @@ -0,0 +1,22 @@ +accounts: + - id: 1234 + alias: sfl-181 + username: 181 + password: sfl-181pw + hostname: sflphone.org + enable: true + type: sip + + - id: 2345 + alias: sfl-431 + username: 431 + password: alexandre + hostname: 192.168.50.3 + enable: true + type: sip + + + + + + diff --git a/sflphone-common/test/sequence2.yml b/sflphone-common/test/sequence2.yml new file mode 100644 index 0000000000000000000000000000000000000000..c63756336f815a62a8745e960d6263be9c047807 --- /dev/null +++ b/sflphone-common/test/sequence2.yml @@ -0,0 +1,117 @@ +accounts: + - id: 1234 + alias: sfl-181 + username: 181 + password: sfl-181pw + hostname: sflphone.org + enable: true + type: sip + + - id: 2345 + alias: sfl-431 + username: 431 + password: alexandre + hostname: 192.168.50.3 + enable: true + type: sip + expire: 3600 + interface: lo + port: 5065 + mailbox: 97 + publishaddr: 127.0.0.1 + publishport: 5065 + sameaslocal: true + resolveonce: false + codecs: 0/9/110/111/112/ + credential: + count: 0 + srtp: + enable: true + keyexchange: sdes + rtpfallback: true + zrtp: + displaySas: true + displaySasOnce: false + helloHashEnabled: true + notSuppWarning: true + tls: + certificate: /home/msavard/Development/sflphone/sflphone-client-gnome/config.guess + calist: /home/msavard/Development/sflphone/sflphone-client-gnome/aclocal.m4 + ciphers: + enable: true + method: TLSv1 + timeout: 0 + password: + privatekey: /home/msavard/Development/sflphone/sflphone-client-gnome/config.log + requirecertif: true + server: + verifyclient: true + verifyserver: true + +addressbook: + photo: false + enabled: true + list: 1243608768.30329.0@emilou-desktop/1243456917.15690.23@emilou-desktop/ + max_results: 25 + business: true + home: false + mobile: false + +audio: + alsa: + cardin: 0 + cardout: 0 + cardout: 0 + framesize: 20 + plugin: default + smplrate: 44100 + pulse: + devicePlayback: + deviceRecord: + deviceRingtone: + recordpath: /home/msavard/Bureau + ringchoice: /usr/share/sflphone/ringtones/konga.ul + volumemic: 100 + volumespkr: 100 + +hooks: + iax2Enabled: false + numberAddPrefix: false + numberEnabled: false + sipEnabled: false + urlCommand: x-www-browser + urlSipField: X-sflphone-url + +preferences: + order: 1234/2345 + audioapi: 0 + dialpaddisplay: 0 + historyenabled: 1 + historylimit: 30 + historymaxCalls: 20 + notifyall: true + notifymails: false + zoneToneChoice: North America + registrationexpire: 180 + ringtonesenable: true + portnum: 5060 + searchbardisplay: true + starthidden: 0 + volumedisplay: 0 + windowheight: 332 + windowpopup: 0 + windowposition: 0 + windowposition: 24 + windowwidth: 240 + zeroconfenable: false + md5Hash: false + +voiplink: + playDtmf: true + playTones: true + pulseLength: 250 + sendDTMFas: 0 + stunenable: 0 + stunserver: stun.sflphone.org + symmetric: true + zidFile: sfl.zid \ No newline at end of file