25 #include "exceptions.h"
27 #include <interface/interface.h>
28 #include <interface/message.h>
29 #include <libxml++/libxml++.h>
30 #include <utils/misc/string_conversions.h>
36 using namespace xmlpp;
48 dom =
new DomParser();
50 dom->set_substitute_entities();
51 dom->parse_file(config_filename);
52 root = dom->get_document()->get_root_node();
70 std::vector<InterfaceField>
73 vector<InterfaceField> result;
74 NodeSet set = node->find(
"field");
75 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
78 const Element *el =
dynamic_cast<const Element *
>(*i);
81 const Element::AttributeList &attrs = el->get_attributes();
82 for (Element::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end();
84 const Attribute *attr = *iter;
93 NodeSet nameset = (*i)->find(
"text()");
94 if (nameset.size() == 0) {
98 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(nameset[0]);
105 f.
valid(reserved_names);
108 for (vector<InterfaceField>::iterator i = result.begin(); i != result.end(); ++i) {
109 for (vector<InterfaceField>::iterator j = i + 1; j != result.end(); ++j) {
110 if ((*i).getName() == (*j).getName()) {
125 std::vector<InterfacePseudoMap>
128 vector<InterfacePseudoMap> result;
129 NodeSet set = node->find(
"pseudomap");
130 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
131 const Element *el =
dynamic_cast<const Element *
>(*i);
132 std::string pm_name, pm_type, pm_keytype;
136 attr = el->get_attribute(
"name");
139 pm_name = attr->get_value();
141 attr = el->get_attribute(
"type");
144 pm_type = attr->get_value();
146 attr = el->get_attribute(
"keytype");
149 pm_keytype = attr->get_value();
154 NodeSet comment_set = (*i)->find(
"text()");
155 if (comment_set.size() == 0) {
158 std::string pm_comment =
"";
159 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
161 pm_comment = comment_node->get_content();
168 NodeSet ref_nodes = (*i)->find(
"mapref");
169 for (NodeSet::iterator r = ref_nodes.begin(); r != ref_nodes.end(); ++r) {
170 NodeSet ref_set = (*r)->find(
"text()");
171 if (ref_set.size() == 0) {
175 const Element *el =
dynamic_cast<const Element *
>(*r);
177 attr = el->get_attribute(
"key");
180 std::string mapref_key = attr->get_value();
182 const TextNode *text_node =
dynamic_cast<const TextNode *
>(ref_set[0]);
186 for (vector<InterfaceField>::iterator j = fields.begin(); j != fields.end(); ++j) {
187 if ((*j).getName() == text_node->get_content()) {
189 if (j->getLengthValue() > 0) {
191 "pseudomap references may only point to non-map types");
193 pm.
addRef(text_node->get_content(), mapref_key);
209 result.push_back(pm);
214 for (vector<InterfacePseudoMap>::iterator i = result.begin(); i != result.end(); ++i) {
215 for (vector<InterfacePseudoMap>::iterator j = i + 1; j != result.end(); ++j) {
216 if ((*i).getName() == (*j).getName()) {
220 for (vector<InterfaceField>::iterator f = fields.begin(); f != fields.end(); ++f) {
221 if (i->getName() == f->getName()) {
237 for (vector<InterfaceField>::iterator i = fields.begin(); i != fields.end(); ++i) {
238 cout <<
" Field: name=" << (*i).getName() <<
" type=" << (*i).getType();
239 if ((*i).getLength() !=
"") {
240 cout <<
" length=" << (*i).getLength();
242 if ((*i).getValidFor() !=
"") {
243 cout <<
" validfor=" << (*i).getValidFor();
245 if ((*i).getDefaultValue() !=
"") {
246 cout <<
" default=" << (*i).getDefaultValue();
248 vector<string> flags = (*i).getFlags();
249 if (flags.size() > 0) {
251 vector<string>::iterator j = flags.begin();
252 while (j != flags.end()) {
255 if (j != flags.end()) {
270 for (vector<InterfacePseudoMap>::iterator i = pseudo_maps.begin(); i != pseudo_maps.end(); ++i) {
271 cout <<
" PseudoMap: name=" << i->getName() <<
" type=" << i->getType()
272 <<
" keytype=" << i->getKeyType() << endl;
275 InterfacePseudoMap::RefList::iterator j;
276 for (j = reflist.begin(); j != reflist.end(); ++j) {
277 cout <<
" Ref: field=" << j->first <<
" key=" << j->second << endl;
293 vector<InterfaceEnumConstant> &enum_constants,
294 vector<InterfaceField> & data_fields,
295 vector<InterfacePseudoMap> & pseudo_maps,
296 vector<InterfaceMessage> & messages)
298 cout <<
"Constants" << endl;
299 for (vector<InterfaceConstant>::iterator i = constants.begin(); i != constants.end(); ++i) {
300 cout <<
" Constant: name=" << (*i).getName() <<
" type=" << (*i).getType()
301 <<
" value=" << (*i).getValue() << endl;
304 cout <<
"EnumConstants" << endl;
305 for (vector<InterfaceEnumConstant>::iterator i = enum_constants.begin();
306 i != enum_constants.end();
308 cout <<
" EnumConstant: name=" << (*i).get_name() << endl;
309 vector<InterfaceEnumConstant::EnumItem> items = (*i).get_items();
310 vector<InterfaceEnumConstant::EnumItem>::iterator j;
311 for (j = items.begin(); j != items.end(); ++j) {
312 cout <<
" Item: " << j->name <<
"(" << j->comment <<
")" << endl;
316 cout <<
"Data block" << endl;
317 printFields(data_fields);
318 printPseudoMaps(pseudo_maps);
319 for (vector<InterfaceMessage>::iterator i = messages.begin(); i != messages.end(); ++i) {
320 cout <<
"Message: name=" << (*i).getName() << endl;
321 vector<InterfaceField> msg_fields = (*i).getFields();
322 printFields(msg_fields);
330 printParsed(constants, enum_constants, data_fields, pseudo_maps, messages);
340 enum_constants.clear();
348 const Element *el =
dynamic_cast<const Element *
>(root);
352 attr = el->get_attribute(
"name");
356 name = attr->get_value();
357 if (name.length() > INTERFACE_TYPE_SIZE_) {
359 INTERFACE_TYPE_SIZE_);
362 attr = el->get_attribute(
"author");
364 author = attr->get_value();
366 attr = el->get_attribute(
"year");
368 year = attr->get_value();
370 attr = el->get_attribute(
"created");
372 creation_date = attr->get_value();
382 NodeSet constants_set = root->find(
"/interface/constants");
383 if (constants_set.size() > 1) {
386 if (constants_set.size() == 1) {
388 set = constants_set[0]->find(
"constant");
389 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
391 NodeSet nameset = (*i)->find(
"text()");
392 if (nameset.size() == 0) {
395 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(nameset[0]);
399 std::string const_comment = comment_node->get_content();
405 std::string const_name;
407 el =
dynamic_cast<const Element *
>(*i);
411 attr = el->get_attribute(
"type");
415 type = attr->get_value();
417 attr = el->get_attribute(
"name");
421 const_name = attr->get_value();
423 attr = el->get_attribute(
"value");
427 value = attr->get_value();
435 constants.push_back(constant);
442 for (vector<InterfaceConstant>::iterator i = constants.begin(); i != constants.end(); ++i) {
443 for (vector<InterfaceConstant>::iterator j = i + 1; j != constants.end(); ++j) {
444 if ((*i).getName() == (*j).getName()) {
454 set = constants_set[0]->find(
"enum");
455 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
456 std::string enum_comment;
457 NodeSet comment_set = (*i)->find(
"comment/text()");
458 if (comment_set.size() == 0) {
461 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
463 enum_comment = comment_node->get_content();
470 el =
dynamic_cast<const Element *
>(*i);
474 attr = el->get_attribute(
"name");
478 enum_name = attr->get_value();
487 NodeSet items = (*i)->find(
"item");
488 if (items.size() == 0) {
492 for (NodeSet::iterator j = items.begin(); j != items.end(); ++j) {
493 std::string item_name;
494 std::string item_value;
495 el =
dynamic_cast<const Element *
>(*j);
499 attr = el->get_attribute(
"name");
503 item_name = attr->get_value();
506 val_attr = el->get_attribute(
"value");
508 item_value = val_attr->get_value();
515 comment_set = (*j)->find(
"text()");
516 if (comment_set.size() == 0) {
519 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
521 if (item_value !=
"") {
523 comment_node->get_content(),
526 enum_constant.
add_item(item_name, comment_node->get_content());
533 enum_constants.push_back(enum_constant);
535 vector<InterfaceEnumConstant>::iterator i;
536 for (i = enum_constants.begin(); i != enum_constants.end(); ++i) {
537 vector<InterfaceEnumConstant>::iterator j;
538 for (j = i + 1; j != enum_constants.end(); ++j) {
539 if (i->get_name() == j->get_name()) {
550 set = root->find(
"/interface/data");
551 if (set.size() > 1) {
553 }
else if (set.size() == 0) {
557 data_fields = getFields(set[0], reserved_names_interface());
558 if (data_fields.size() == 0) {
562 pseudo_maps = getPseudoMaps(set[0], data_fields);
564 NodeSet comment_set = root->find(
"/interface/data/comment/text()");
565 if (comment_set.size() == 0) {
568 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
570 data_comment = comment_node->get_content();
579 set = root->find(
"/interface/message");
580 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
581 std::string msg_name;
582 std::string msg_comment;
584 el =
dynamic_cast<const Element *
>(*i);
587 attr = el->get_attribute(
"name");
591 msg_name = attr->get_value();
592 if (msg_name.length() + std::string(
"Message").length() > INTERFACE_MESSAGE_TYPE_SIZE_ - 1) {
594 "Interface message name '%s' too long, max length is %u",
596 INTERFACE_MESSAGE_TYPE_SIZE_ - 1 - std::string(
"Message").length());
602 comment_set = (*i)->find(
"text()");
603 if (comment_set.size() == 0) {
606 comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
608 msg_comment = comment_node->get_content();
613 vector<InterfaceField> msg_fields = getFields(*i, reserved_names_message());
615 NodeSet ref_nodes = (*i)->find(
"ref/text()");
616 for (NodeSet::iterator r = ref_nodes.begin(); r != ref_nodes.end(); ++r) {
617 const TextNode *text_node =
dynamic_cast<const TextNode *
>(*r);
621 for (vector<InterfaceField>::iterator j = data_fields.begin(); j != data_fields.end();
623 if ((*j).getName() == text_node->get_content()) {
625 msg_fields.push_back(*j);
637 for (vector<InterfaceField>::iterator k = msg_fields.begin(); k != msg_fields.end(); ++k) {
638 for (vector<InterfaceField>::iterator j = k + 1; j != msg_fields.end(); ++j) {
639 if ((*k).getName() == (*j).getName()) {
648 messages.push_back(msg);
650 bool duplicateExists =
false;
651 for (
auto msg1 = messages.begin(); msg1 != messages.end(); ++msg1) {
652 for (
auto msg2 = msg1 + 1; msg2 != messages.end(); ++msg2) {
653 if (strncmp(msg1->getName().c_str(),
654 msg2->getName().c_str(),
655 INTERFACE_MESSAGE_TYPE_SIZE_ - 1)
657 cout <<
"Possible duplicate at message network syncing detected:" << endl;
658 cout << msg1->getName() <<
" and " << msg2->getName() << endl << endl;
659 duplicateExists =
true;
665 "Duplicates after serializing by BB network handler exist!");
705 return creation_date;
712 std::vector<InterfaceConstant>
722 std::vector<InterfaceEnumConstant>
725 return enum_constants;
732 std::vector<InterfaceField>
742 std::vector<InterfacePseudoMap>
762 std::vector<InterfaceMessage>