1 // Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # include <simgear_config.h>
22 #include <simgear/compiler.h>
24 #include "HLAOMTXmlVisitor.hxx"
30 #include <simgear/structure/exception.hxx>
31 #include <simgear/xml/easyxml.hxx>
32 #include "HLAArrayDataType.hxx"
33 #include "HLABasicDataType.hxx"
34 #include "HLADataTypeVisitor.hxx"
35 #include "HLAEnumeratedDataType.hxx"
36 #include "HLAFederate.hxx"
37 #include "HLAFixedRecordDataType.hxx"
38 #include "HLAVariantRecordDataType.hxx"
42 HLAOMTXmlVisitor::ObjectClass::ObjectClass(const std::string& name, const std::string& sharing) :
48 HLAOMTXmlVisitor::ObjectClass::~ObjectClass()
53 HLAOMTXmlVisitor::ObjectClass::getName() const
59 HLAOMTXmlVisitor::ObjectClass::getSharing() const
65 HLAOMTXmlVisitor::ObjectClass::getNumAttributes() const
67 return _attributes.size();
70 const HLAOMTXmlVisitor::Attribute*
71 HLAOMTXmlVisitor::ObjectClass::getAttribute(unsigned index) const
73 if (_attributes.size() <= index)
75 return _attributes[index];
78 const HLAOMTXmlVisitor::ObjectClass*
79 HLAOMTXmlVisitor::ObjectClass::getParentObjectClass() const
81 return _parentObjectClass.get();
84 HLAOMTXmlVisitor::InteractionClass::InteractionClass(const std::string& name) :
89 HLAOMTXmlVisitor::InteractionClass::~InteractionClass()
94 HLAOMTXmlVisitor::InteractionClass::getName() const
100 HLAOMTXmlVisitor::InteractionClass::getDimensions() const
106 HLAOMTXmlVisitor::InteractionClass::getSharing() const
112 HLAOMTXmlVisitor::InteractionClass::getTransportation() const
114 return _transportation;
118 HLAOMTXmlVisitor::InteractionClass::getOrder() const
124 HLAOMTXmlVisitor::InteractionClass::getNumParameters() const
126 return _parameters.size();
129 const HLAOMTXmlVisitor::Parameter*
130 HLAOMTXmlVisitor::InteractionClass::getParameter(unsigned index) const
132 if (_parameters.size() <= index)
134 return _parameters[index];
137 const HLAOMTXmlVisitor::InteractionClass*
138 HLAOMTXmlVisitor::InteractionClass::getParentInteractionClass() const
140 return _parentInteractionClass.get();
143 HLAOMTXmlVisitor::HLAOMTXmlVisitor()
147 HLAOMTXmlVisitor::~HLAOMTXmlVisitor()
152 HLAOMTXmlVisitor::setDataTypesToFederate(HLAFederate& federate)
154 // Provide all the data types
155 for (BasicDataMap::iterator i = _basicDataMap.begin(); i != _basicDataMap.end(); ++i)
156 federate.insertDataType(i->first, getDataType(i->first));
157 for (SimpleDataMap::iterator i = _simpleDataMap.begin(); i != _simpleDataMap.end(); ++i)
158 federate.insertDataType(i->first, getDataType(i->first));
159 for (EnumeratedDataMap::iterator i = _enumeratedDataMap.begin(); i != _enumeratedDataMap.end(); ++i)
160 federate.insertDataType(i->first, getDataType(i->first));
161 for (ArrayDataMap::iterator i = _arrayDataMap.begin(); i != _arrayDataMap.end(); ++i)
162 federate.insertDataType(i->first, getDataType(i->first));
163 for (FixedRecordDataMap::iterator i = _fixedRecordDataMap.begin(); i != _fixedRecordDataMap.end(); ++i)
164 federate.insertDataType(i->first, getDataType(i->first));
165 for (VariantRecordDataMap::iterator i = _variantRecordDataMap.begin(); i != _variantRecordDataMap.end(); ++i)
166 federate.insertDataType(i->first, getDataType(i->first));
168 // Finish alignment computations
169 federate.recomputeDataTypeAlignment();
173 HLAOMTXmlVisitor::setToFederate(HLAFederate& federate)
175 setDataTypesToFederate(federate);
177 // Provide all interaction classes
178 unsigned numInteractionClasses = getNumInteractionClasses();
179 for (unsigned i = 0; i < numInteractionClasses; ++i) {
180 const InteractionClass* interactionClass = getInteractionClass(i);
182 SGSharedPtr<HLAInteractionClass> hlaInteractionClass;
183 hlaInteractionClass = federate.createInteractionClass(interactionClass->getName());
184 if (!hlaInteractionClass.valid()) {
185 SG_LOG(SG_IO, SG_INFO, "Ignoring Interaction class \"" << interactionClass->getName() << "\".");
189 hlaInteractionClass->setSubscriptionType(interactionClass->getSubscriptionType());
190 hlaInteractionClass->setPublicationType(interactionClass->getPublicationType());
192 // process the parameters
193 for (unsigned j = 0; j < interactionClass->getNumParameters(); ++j) {
194 const Parameter* parameter = interactionClass->getParameter(j);
195 unsigned index = hlaInteractionClass->addParameter(parameter->getName());
196 hlaInteractionClass->setParameterDataType(index, federate.getDataType(parameter->getDataType()));
200 // Provide all object classes
201 unsigned numObjectClasses = getNumObjectClasses();
202 for (unsigned i = 0; i < numObjectClasses; ++i) {
203 const ObjectClass* objectClass = getObjectClass(i);
205 SGSharedPtr<HLAObjectClass> hlaObjectClass;
206 hlaObjectClass = federate.createObjectClass(objectClass->getName());
207 if (!hlaObjectClass.valid()) {
208 SG_LOG(SG_IO, SG_INFO, "Ignoring Object class \"" << objectClass->getName() << "\".");
212 // process the attributes
213 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
214 const Attribute* attribute = objectClass->getAttribute(j);
216 unsigned index = hlaObjectClass->addAttribute(attribute->getName());
217 hlaObjectClass->setAttributeDataType(index, federate.getDataType(attribute->getDataType()));
219 hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType());
220 hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType());
221 hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType());
227 HLAOMTXmlVisitor::getNumObjectClasses() const
229 return _objectClassList.size();
232 const HLAOMTXmlVisitor::ObjectClass*
233 HLAOMTXmlVisitor::getObjectClass(unsigned i) const
235 if (_objectClassList.size() <= i)
237 return _objectClassList[i];
241 HLAOMTXmlVisitor::getNumInteractionClasses() const
243 return _interactionClassList.size();
246 const HLAOMTXmlVisitor::InteractionClass*
247 HLAOMTXmlVisitor::getInteractionClass(unsigned i) const
249 if (_interactionClassList.size() <= i)
251 return _interactionClassList[i];
254 SGSharedPtr<HLADataType>
255 HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName)
257 StringDataTypeMap::const_iterator i = _dataTypeMap.find(dataTypeName);
258 if (i != _dataTypeMap.end())
261 SGSharedPtr<HLADataType> dataType;
262 dataType = getBasicDataType(dataTypeName);
263 if (dataType.valid()) {
264 _dataTypeMap[dataTypeName] = dataType;
268 dataType = getSimpleDataType(dataTypeName);
269 if (dataType.valid())
272 dataType = getEnumeratedDataType(dataTypeName);
273 if (dataType.valid())
276 dataType = getArrayDataType(dataTypeName);
277 if (dataType.valid())
280 dataType = getFixedRecordDataType(dataTypeName);
281 if (dataType.valid())
284 dataType = getVariantRecordDataType(dataTypeName);
285 if (dataType.valid())
288 SG_LOG(SG_IO, SG_WARN, "Could not resolve dataType \"" << dataTypeName << "\".");
292 SGSharedPtr<HLABasicDataType>
293 HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName)
295 BasicDataMap::const_iterator i = _basicDataMap.find(dataTypeName);
296 if (i == _basicDataMap.end())
298 if (i->second._size == "8") {
299 return new HLAUInt8DataType(dataTypeName);
300 } else if (i->second._size == "16") {
301 if (i->first.find("Unsigned") != std::string::npos) {
302 if (i->second._endian == "Little") {
303 return new HLAUInt16LEDataType(dataTypeName);
305 return new HLAUInt16BEDataType(dataTypeName);
307 } else if (i->first.find("octetPair") != std::string::npos) {
308 if (i->second._endian == "Little") {
309 return new HLAUInt16LEDataType(dataTypeName);
311 return new HLAUInt16BEDataType(dataTypeName);
314 if (i->second._endian == "Little") {
315 return new HLAInt16LEDataType(dataTypeName);
317 return new HLAInt16BEDataType(dataTypeName);
320 } else if (i->second._size == "32") {
321 if (i->first.find("Unsigned") != std::string::npos) {
322 if (i->second._endian == "Little") {
323 return new HLAUInt32LEDataType(dataTypeName);
325 return new HLAUInt32BEDataType(dataTypeName);
327 } else if (i->first.find("float") != std::string::npos) {
328 if (i->second._endian == "Little") {
329 return new HLAFloat32LEDataType(dataTypeName);
331 return new HLAFloat32BEDataType(dataTypeName);
334 if (i->second._endian == "Little") {
335 return new HLAInt32LEDataType(dataTypeName);
337 return new HLAInt32BEDataType(dataTypeName);
340 } else if (i->second._size == "64") {
341 if (i->first.find("Unsigned") != std::string::npos) {
342 if (i->second._endian == "Little") {
343 return new HLAUInt64LEDataType(dataTypeName);
345 return new HLAUInt64BEDataType(dataTypeName);
347 } else if (i->first.find("float") != std::string::npos) {
348 if (i->second._endian == "Little") {
349 return new HLAFloat64LEDataType(dataTypeName);
351 return new HLAFloat64BEDataType(dataTypeName);
354 if (i->second._endian == "Little") {
355 return new HLAInt64LEDataType(dataTypeName);
357 return new HLAInt64BEDataType(dataTypeName);
365 SGSharedPtr<HLADataType>
366 HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName)
368 SimpleDataMap::const_iterator i = _simpleDataMap.find(dataTypeName);
369 if (i == _simpleDataMap.end())
371 return getDataType(i->second._representation);
374 SGSharedPtr<HLAEnumeratedDataType>
375 HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName)
377 EnumeratedDataMap::const_iterator i = _enumeratedDataMap.find(dataTypeName);
378 if (i == _enumeratedDataMap.end())
381 SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = new HLAEnumeratedDataType(dataTypeName);
382 _dataTypeMap[dataTypeName] = enumeratedDataType;
383 enumeratedDataType->setRepresentation(getBasicDataType(i->second._representation));
385 for (EnumeratorList::const_iterator j = i->second._enumeratorList.begin();
386 j != i->second._enumeratorList.end(); ++j) {
387 if (!enumeratedDataType->addEnumerator(j->_name, j->_values)) {
388 SG_LOG(SG_IO, SG_ALERT, "Could not add enumerator \"" << j->_name
389 << "\" to find enumerated data type \"" << dataTypeName << "\".");
394 return enumeratedDataType;
397 SGSharedPtr<HLADataType>
398 HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName)
400 ArrayDataMap::const_iterator i = _arrayDataMap.find(dataTypeName);
401 if (i == _arrayDataMap.end())
403 SGSharedPtr<HLAArrayDataType> arrayDataType;
404 if (i->second._encoding == "HLAvariableArray") {
405 arrayDataType = new HLAVariableArrayDataType(dataTypeName);
406 } else if (i->second._encoding == "HLAfixedArray") {
407 std::stringstream ss(i->second._cardinality);
408 unsigned cardinality;
411 SG_LOG(SG_IO, SG_ALERT, "Could not interpret cardinality \""
412 << i->second._cardinality << "\" for dataType \""
413 << dataTypeName << "\".");
416 SGSharedPtr<HLAFixedArrayDataType> dataType = new HLAFixedArrayDataType(dataTypeName);
417 dataType->setNumElements(cardinality);
418 arrayDataType = dataType;
420 SG_LOG(SG_IO, SG_ALERT, "Can not interpret encoding \""
421 << i->second._encoding << "\" for dataType \""
422 << dataTypeName << "\".");
426 _dataTypeMap[dataTypeName] = arrayDataType;
427 SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType);
428 if (!elementDataType.valid()) {
429 SG_LOG(SG_IO, SG_ALERT, "Could not interpret dataType \""
430 << i->second._dataType << "\" for array data type \""
431 << dataTypeName << "\".");
432 _dataTypeMap.erase(dataTypeName);
435 arrayDataType->setElementDataType(elementDataType.get());
437 // Check if this should be a string data type
438 if (elementDataType->toBasicDataType()) {
439 if (dataTypeName == "HLAopaqueData") {
440 arrayDataType->setIsOpaque(true);
441 } else if (dataTypeName.find("String") != std::string::npos || dataTypeName.find("string") != std::string::npos) {
442 arrayDataType->setIsString(true);
446 return arrayDataType;
449 SGSharedPtr<HLAFixedRecordDataType>
450 HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName)
452 FixedRecordDataMap::const_iterator i = _fixedRecordDataMap.find(dataTypeName);
453 if (i == _fixedRecordDataMap.end())
456 SGSharedPtr<HLAFixedRecordDataType> dataType = new HLAFixedRecordDataType(dataTypeName);
457 _dataTypeMap[dataTypeName] = dataType;
458 for (FieldList::size_type j = 0; j < i->second._fieldList.size(); ++j) {
459 SGSharedPtr<HLADataType> fieldDataType = getDataType(i->second._fieldList[j]._dataType);
460 if (!fieldDataType.valid()) {
461 SG_LOG(SG_IO, SG_ALERT, "Could not get data type \"" << i->second._fieldList[j]._dataType
462 << "\" for field " << j << "of fixed record data type \"" << dataTypeName << "\".");
463 _dataTypeMap.erase(dataTypeName);
466 dataType->addField(i->second._fieldList[j]._name, fieldDataType.get());
471 SGSharedPtr<HLAVariantRecordDataType>
472 HLAOMTXmlVisitor::getVariantRecordDataType(const std::string& dataTypeName)
474 VariantRecordDataMap::const_iterator i = _variantRecordDataMap.find(dataTypeName);
475 if (i == _variantRecordDataMap.end())
477 SGSharedPtr<HLAVariantRecordDataType> dataType = new HLAVariantRecordDataType(dataTypeName);
478 _dataTypeMap[dataTypeName] = dataType;
480 SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = getEnumeratedDataType(i->second._dataType);
481 if (!enumeratedDataType.valid()) {
482 SG_LOG(SG_IO, SG_ALERT, "Could not find enumerted data type \"" << i->second._dataType
483 << "\" for variant data type \"" << dataTypeName << "\".");
486 dataType->setEnumeratedDataType(enumeratedDataType);
488 for (AlternativeList::const_iterator j = i->second._alternativeList.begin();
489 j != i->second._alternativeList.end(); ++j) {
490 SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType);
491 if (!alternativeDataType.valid()) {
492 SG_LOG(SG_IO, SG_ALERT, "Could not resolve alternative dataType \"" << j->_dataType
493 << "\" for alternative \"" << j->_name << "\".");
494 _dataTypeMap.erase(dataTypeName);
497 if (!dataType->addAlternative(j->_name, j->_enumerator, alternativeDataType.get(), j->_semantics)) {
498 SG_LOG(SG_IO, SG_ALERT, "Could not add alternative \"" << j->_name << "\".");
505 HLAOMTXmlVisitor::Mode
506 HLAOMTXmlVisitor::getCurrentMode()
508 if (_modeStack.empty())
510 return _modeStack.back();
514 HLAOMTXmlVisitor::pushMode(HLAOMTXmlVisitor::Mode mode)
516 _modeStack.push_back(mode);
520 HLAOMTXmlVisitor::popMode()
522 _modeStack.pop_back();
526 HLAOMTXmlVisitor::startXML()
532 HLAOMTXmlVisitor::endXML()
534 if (!_modeStack.empty())
535 throw sg_exception("Internal parse error!");
537 // propagate parent attributes to the derived classes
538 // Note that this preserves the order of the attributes starting from the root object
539 for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
540 SGSharedPtr<const ObjectClass> objectClass = (*i)->_parentObjectClass;
541 if (!objectClass.valid())
543 for (AttributeList::const_reverse_iterator j = objectClass->_attributes.rbegin();
544 j != objectClass->_attributes.rend(); ++j) {
545 (*i)->_attributes.insert((*i)->_attributes.begin(), *j);
549 // propagate parent parameter to the derived interactions
550 // Note that this preserves the order of the parameters starting from the root object
551 for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
552 SGSharedPtr<const InteractionClass> interactionClass = (*i)->_parentInteractionClass;
553 if (!interactionClass.valid())
555 for (ParameterList::const_reverse_iterator j = interactionClass->_parameters.rbegin();
556 j != interactionClass->_parameters.rend(); ++j) {
557 (*i)->_parameters.insert((*i)->_parameters.begin(), *j);
563 HLAOMTXmlVisitor::startElement(const char* name, const XMLAttributes& atts)
565 if (strcmp(name, "attribute") == 0) {
566 if (getCurrentMode() != ObjectClassMode)
567 throw sg_exception("attribute tag outside objectClass!");
568 pushMode(AttributeMode);
570 if (_objectClassList.empty())
571 throw sg_exception("attribute tag outside of an objectClass");
573 std::string name = getAttribute("name", atts);
575 throw sg_exception("attribute tag without name attribute");
577 SGSharedPtr<Attribute> attribute = new Attribute(name);
579 attribute->_dataType = getAttribute("dataType", atts);
580 attribute->_updateType = getAttribute("updateType", atts);
581 attribute->_updateCondition = getAttribute("updateCondition", atts);
582 attribute->_ownership = getAttribute("ownership", atts);
583 attribute->_sharing = getAttribute("sharing", atts);
584 attribute->_dimensions = getAttribute("dimensions", atts);
585 attribute->_transportation = getAttribute("transportation", atts);
586 attribute->_order = getAttribute("order", atts);
588 _objectClassStack.back()->_attributes.push_back(attribute);
590 } else if (strcmp(name, "objectClass") == 0) {
591 if (getCurrentMode() != ObjectsMode && getCurrentMode() != ObjectClassMode)
592 throw sg_exception("objectClass tag outside objectClass or objects!");
593 pushMode(ObjectClassMode);
595 std::string name = getAttribute("name", atts);
597 throw sg_exception("objectClass tag without name attribute");
599 std::string sharing = getAttribute("sharing", atts);
601 // The new ObjectClass
602 ObjectClass* objectClass = new ObjectClass(name, sharing);
604 // Inherit all previous attributes
605 if (!_objectClassStack.empty())
606 objectClass->_parentObjectClass = _objectClassStack.back();
608 _objectClassStack.push_back(objectClass);
609 _objectClassList.push_back(objectClass);
611 } else if (strcmp(name, "objects") == 0) {
612 if (getCurrentMode() != ObjectModelMode)
613 throw sg_exception("objects tag outside objectModel!");
614 pushMode(ObjectsMode);
616 } else if (strcmp(name, "parameter") == 0) {
617 if (getCurrentMode() != InteractionClassMode)
618 throw sg_exception("parameter tag outside interactionClass!");
619 pushMode(ParameterMode);
621 if (_interactionClassList.empty())
622 throw sg_exception("parameter tag outside of an interactionClass");
624 std::string name = getAttribute("name", atts);
626 throw sg_exception("parameter tag without name parameter");
628 SGSharedPtr<Parameter> parameter = new Parameter(name);
629 parameter->_dataType = getAttribute("dataType", atts);
631 _interactionClassStack.back()->_parameters.push_back(parameter);
633 } else if (strcmp(name, "interactionClass") == 0) {
634 if (getCurrentMode() != InteractionsMode && getCurrentMode() != InteractionClassMode)
635 throw sg_exception("interactionClass tag outside interactions or interactionClass!");
636 pushMode(InteractionClassMode);
638 std::string name = getAttribute("name", atts);
640 throw sg_exception("interactionClass tag without name attribute");
642 // The new ObjectClass
643 InteractionClass* interactionClass = new InteractionClass(name);
644 interactionClass->_dimensions = getAttribute("dimensions", atts);
645 interactionClass->_transportation = getAttribute("transportation", atts);
646 interactionClass->_order = getAttribute("order", atts);
648 // Inherit all previous attributes
649 if (!_interactionClassStack.empty())
650 interactionClass->_parentInteractionClass = _interactionClassStack.back();
652 _interactionClassStack.push_back(interactionClass);
653 _interactionClassList.push_back(interactionClass);
655 } else if (strcmp(name, "interactions") == 0) {
656 if (getCurrentMode() != ObjectModelMode)
657 throw sg_exception("interactions tag outside objectModel!");
658 pushMode(InteractionsMode);
660 } else if (strcmp(name, "basicData") == 0) {
661 if (getCurrentMode() != BasicDataRepresentationsMode)
662 throw sg_exception("basicData tag outside basicDataRepresentations!");
663 pushMode(BasicDataMode);
665 std::string name = getAttribute("name", atts);
667 throw sg_exception("basicData tag without name attribute");
669 _basicDataMap[name]._size = getAttribute("size", atts);
670 _basicDataMap[name]._endian = getAttribute("endian", atts);
672 } else if (strcmp(name, "basicDataRepresentations") == 0) {
673 if (getCurrentMode() != DataTypesMode)
674 throw sg_exception("basicDataRepresentations tag outside dataTypes!");
675 pushMode(BasicDataRepresentationsMode);
677 } else if (strcmp(name, "simpleData") == 0) {
678 if (getCurrentMode() != SimpleDataTypesMode)
679 throw sg_exception("simpleData tag outside simpleDataTypes!");
680 pushMode(SimpleDataMode);
682 std::string name = getAttribute("name", atts);
684 throw sg_exception("simpleData tag without name attribute");
686 _simpleDataMap[name]._representation = getAttribute("representation", atts);
687 _simpleDataMap[name]._units = getAttribute("units", atts);
688 _simpleDataMap[name]._resolution = getAttribute("resolution", atts);
689 _simpleDataMap[name]._accuracy = getAttribute("accuracy", atts);
691 } else if (strcmp(name, "simpleDataTypes") == 0) {
692 if (getCurrentMode() != DataTypesMode)
693 throw sg_exception("simpleDataTypes tag outside dataTypes!");
694 pushMode(SimpleDataTypesMode);
696 } else if (strcmp(name, "enumerator") == 0) {
697 if (getCurrentMode() != EnumeratedDataMode)
698 throw sg_exception("enumerator tag outside enumeratedData!");
699 pushMode(EnumeratorMode);
701 std::string name = getAttribute("name", atts);
703 throw sg_exception("enumerator tag without name attribute");
705 Enumerator enumerator;
706 enumerator._name = name;
707 enumerator._values = getAttribute("values", atts);
708 _enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
710 } else if (strcmp(name, "enumeratedData") == 0) {
711 if (getCurrentMode() != EnumeratedDataTypesMode)
712 throw sg_exception("enumeratedData tag outside enumeratedDataTypes!");
713 pushMode(EnumeratedDataMode);
715 std::string name = getAttribute("name", atts);
717 throw sg_exception("enumeratedData tag without name attribute");
719 _enumeratedDataName = name;
720 _enumeratedDataMap[_enumeratedDataName]._representation = getAttribute("representation", atts);
722 } else if (strcmp(name, "enumeratedDataTypes") == 0) {
723 if (getCurrentMode() != DataTypesMode)
724 throw sg_exception("enumeratedDataTypes tag outside dataTypes!");
725 pushMode(EnumeratedDataTypesMode);
727 } else if (strcmp(name, "arrayData") == 0) {
728 if (getCurrentMode() != ArrayDataTypesMode)
729 throw sg_exception("arrayData tag outside arrayDataTypes!");
730 pushMode(ArrayDataMode);
732 std::string name = getAttribute("name", atts);
734 throw sg_exception("arrayData tag without name attribute");
736 _arrayDataMap[name]._dataType = getAttribute("dataType", atts);
737 _arrayDataMap[name]._cardinality = getAttribute("cardinality", atts);
738 _arrayDataMap[name]._encoding = getAttribute("encoding", atts);
740 } else if (strcmp(name, "arrayDataTypes") == 0) {
741 if (getCurrentMode() != DataTypesMode)
742 throw sg_exception("arrayDataTypes tag outside dataTypes!");
743 pushMode(ArrayDataTypesMode);
745 } else if (strcmp(name, "field") == 0) {
746 if (getCurrentMode() != FixedRecordDataMode)
747 throw sg_exception("field tag outside fixedRecordData!");
750 std::string name = getAttribute("name", atts);
752 throw sg_exception("field tag without name attribute");
756 field._dataType = getAttribute("dataType", atts);
757 _fixedRecordDataMap[_fixedRecordDataName]._fieldList.push_back(field);
759 } else if (strcmp(name, "fixedRecordData") == 0) {
760 if (getCurrentMode() != FixedRecordDataTypesMode)
761 throw sg_exception("fixedRecordData tag outside fixedRecordDataTypes!");
762 pushMode(FixedRecordDataMode);
764 std::string name = getAttribute("name", atts);
766 throw sg_exception("fixedRecordData tag without name attribute");
768 _fixedRecordDataName = name;
769 _fixedRecordDataMap[name]._encoding = getAttribute("encoding", atts);
771 } else if (strcmp(name, "fixedRecordDataTypes") == 0) {
772 if (getCurrentMode() != DataTypesMode)
773 throw sg_exception("fixedRecordDataTypes tag outside dataTypes!");
774 pushMode(FixedRecordDataTypesMode);
776 } else if (strcmp(name, "alternative") == 0) {
778 if (getCurrentMode() != VariantRecordDataMode)
779 throw sg_exception("alternative tag outside variantRecordData!");
780 pushMode(AlternativeDataMode);
782 std::string name = getAttribute("name", atts);
784 throw sg_exception("alternative tag without name attribute");
786 Alternative alternative;
787 alternative._name = name;
788 alternative._dataType = getAttribute("dataType", atts);
789 alternative._semantics = getAttribute("semantics", atts);
790 alternative._enumerator = getAttribute("enumerator", atts);
791 _variantRecordDataMap[_variantRecordDataName]._alternativeList.push_back(alternative);
793 } else if (strcmp(name, "variantRecordData") == 0) {
794 if (getCurrentMode() != VariantRecordDataTypesMode)
795 throw sg_exception("variantRecordData tag outside variantRecordDataTypes!");
796 pushMode(VariantRecordDataMode);
798 std::string name = getAttribute("name", atts);
800 throw sg_exception("fixedRecordData tag without name attribute");
802 _variantRecordDataName = name;
803 _variantRecordDataMap[name]._encoding = getAttribute("encoding", atts);
804 _variantRecordDataMap[name]._dataType = getAttribute("dataType", atts);
805 _variantRecordDataMap[name]._semantics = getAttribute("semantics", atts);
806 _variantRecordDataMap[name]._discriminant = getAttribute("discriminant", atts);
808 } else if (strcmp(name, "variantRecordDataTypes") == 0) {
809 if (getCurrentMode() != DataTypesMode)
810 throw sg_exception("variantRecordDataTypes tag outside dataTypes!");
811 pushMode(VariantRecordDataTypesMode);
813 } else if (strcmp(name, "dataTypes") == 0) {
814 if (getCurrentMode() != ObjectModelMode)
815 throw sg_exception("dataTypes tag outside objectModel!");
816 pushMode(DataTypesMode);
818 } else if (strcmp(name, "objectModel") == 0) {
819 if (!_modeStack.empty())
820 throw sg_exception("objectModel tag not at top level!");
821 pushMode(ObjectModelMode);
824 _modeStack.push_back(UnknownMode);
829 HLAOMTXmlVisitor::endElement(const char* name)
831 if (strcmp(name, "objectClass") == 0) {
832 _objectClassStack.pop_back();
833 } else if (strcmp(name, "interactionClass") == 0) {
834 _interactionClassStack.pop_back();
835 } else if (strcmp(name, "enumeratedData") == 0) {
836 _enumeratedDataName.clear();
837 } else if (strcmp(name, "fixedRecordData") == 0) {
838 _fixedRecordDataName.clear();
839 } else if (strcmp(name, "variantRecordData") == 0) {
840 _variantRecordDataName.clear();
843 _modeStack.pop_back();
847 HLAOMTXmlVisitor::getAttribute(const char* name, const XMLAttributes& atts)
849 int index = atts.findAttribute(name);
850 if (index < 0 || atts.size() <= index)
851 return std::string();
852 return std::string(atts.getValue(index));
856 HLAOMTXmlVisitor::getAttribute(const std::string& name, const XMLAttributes& atts)
858 int index = atts.findAttribute(name.c_str());
859 if (index < 0 || atts.size() <= index)
860 return std::string();
861 return std::string(atts.getValue(index));
864 } // namespace simgear