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.
18 #include "HLAOMTXmlVisitor.hxx"
24 #include <simgear/structure/exception.hxx>
25 #include <simgear/xml/easyxml.hxx>
26 #include "HLAArrayDataType.hxx"
27 #include "HLABasicDataType.hxx"
28 #include "HLADataTypeVisitor.hxx"
29 #include "HLAEnumeratedDataType.hxx"
30 #include "HLAFederate.hxx"
31 #include "HLAFixedRecordDataType.hxx"
32 #include "HLAVariantRecordDataType.hxx"
36 HLAOMTXmlVisitor::ObjectClass::ObjectClass(const std::string& name, const std::string& sharing) :
42 HLAOMTXmlVisitor::ObjectClass::~ObjectClass()
47 HLAOMTXmlVisitor::ObjectClass::getName() const
53 HLAOMTXmlVisitor::ObjectClass::getSharing() const
59 HLAOMTXmlVisitor::ObjectClass::getNumAttributes() const
61 return _attributes.size();
64 const HLAOMTXmlVisitor::Attribute*
65 HLAOMTXmlVisitor::ObjectClass::getAttribute(unsigned index) const
67 if (_attributes.size() <= index)
69 return _attributes[index];
72 const HLAOMTXmlVisitor::ObjectClass*
73 HLAOMTXmlVisitor::ObjectClass::getParentObjectClass() const
75 return _parentObjectClass.get();
78 HLAOMTXmlVisitor::InteractionClass::InteractionClass(const std::string& name) :
83 HLAOMTXmlVisitor::InteractionClass::~InteractionClass()
88 HLAOMTXmlVisitor::InteractionClass::getName() const
94 HLAOMTXmlVisitor::InteractionClass::getDimensions() const
100 HLAOMTXmlVisitor::InteractionClass::getSharing() const
106 HLAOMTXmlVisitor::InteractionClass::getTransportation() const
108 return _transportation;
112 HLAOMTXmlVisitor::InteractionClass::getOrder() const
118 HLAOMTXmlVisitor::InteractionClass::getNumParameters() const
120 return _parameters.size();
123 const HLAOMTXmlVisitor::Parameter*
124 HLAOMTXmlVisitor::InteractionClass::getParameter(unsigned index) const
126 if (_parameters.size() <= index)
128 return _parameters[index];
131 const HLAOMTXmlVisitor::InteractionClass*
132 HLAOMTXmlVisitor::InteractionClass::getParentInteractionClass() const
134 return _parentInteractionClass.get();
137 HLAOMTXmlVisitor::HLAOMTXmlVisitor()
141 HLAOMTXmlVisitor::~HLAOMTXmlVisitor()
146 HLAOMTXmlVisitor::setDataTypesToFederate(HLAFederate& federate)
148 // Provide all the data types
149 for (BasicDataMap::iterator i = _basicDataMap.begin(); i != _basicDataMap.end(); ++i)
150 federate.insertDataType(i->first, getDataType(i->first));
151 for (SimpleDataMap::iterator i = _simpleDataMap.begin(); i != _simpleDataMap.end(); ++i)
152 federate.insertDataType(i->first, getDataType(i->first));
153 for (EnumeratedDataMap::iterator i = _enumeratedDataMap.begin(); i != _enumeratedDataMap.end(); ++i)
154 federate.insertDataType(i->first, getDataType(i->first));
155 for (ArrayDataMap::iterator i = _arrayDataMap.begin(); i != _arrayDataMap.end(); ++i)
156 federate.insertDataType(i->first, getDataType(i->first));
157 for (FixedRecordDataMap::iterator i = _fixedRecordDataMap.begin(); i != _fixedRecordDataMap.end(); ++i)
158 federate.insertDataType(i->first, getDataType(i->first));
159 for (VariantRecordDataMap::iterator i = _variantRecordDataMap.begin(); i != _variantRecordDataMap.end(); ++i)
160 federate.insertDataType(i->first, getDataType(i->first));
162 // Finish alignment computations
163 federate.recomputeDataTypeAlignment();
167 HLAOMTXmlVisitor::setToFederate(HLAFederate& federate)
169 setDataTypesToFederate(federate);
171 // Provide all interaction classes
172 unsigned numInteractionClasses = getNumInteractionClasses();
173 for (unsigned i = 0; i < numInteractionClasses; ++i) {
174 const InteractionClass* interactionClass = getInteractionClass(i);
176 SGSharedPtr<HLAInteractionClass> hlaInteractionClass;
177 hlaInteractionClass = federate.createInteractionClass(interactionClass->getName());
178 if (!hlaInteractionClass.valid()) {
179 SG_LOG(SG_IO, SG_INFO, "Ignoring Interaction class \"" << interactionClass->getName() << "\".");
183 hlaInteractionClass->setSubscriptionType(interactionClass->getSubscriptionType());
184 hlaInteractionClass->setPublicationType(interactionClass->getPublicationType());
186 // process the parameters
187 for (unsigned j = 0; j < interactionClass->getNumParameters(); ++j) {
188 const Parameter* parameter = interactionClass->getParameter(j);
189 unsigned index = hlaInteractionClass->addParameter(parameter->getName());
190 hlaInteractionClass->setParameterDataType(index, federate.getDataType(parameter->getDataType()));
194 // Provide all object classes
195 unsigned numObjectClasses = getNumObjectClasses();
196 for (unsigned i = 0; i < numObjectClasses; ++i) {
197 const ObjectClass* objectClass = getObjectClass(i);
199 SGSharedPtr<HLAObjectClass> hlaObjectClass;
200 hlaObjectClass = federate.createObjectClass(objectClass->getName());
201 if (!hlaObjectClass.valid()) {
202 SG_LOG(SG_IO, SG_INFO, "Ignoring Object class \"" << objectClass->getName() << "\".");
206 // process the attributes
207 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
208 const Attribute* attribute = objectClass->getAttribute(j);
210 unsigned index = hlaObjectClass->addAttribute(attribute->getName());
211 hlaObjectClass->setAttributeDataType(index, federate.getDataType(attribute->getDataType()));
213 hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType());
214 hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType());
215 hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType());
221 HLAOMTXmlVisitor::getNumObjectClasses() const
223 return _objectClassList.size();
226 const HLAOMTXmlVisitor::ObjectClass*
227 HLAOMTXmlVisitor::getObjectClass(unsigned i) const
229 if (_objectClassList.size() <= i)
231 return _objectClassList[i];
235 HLAOMTXmlVisitor::getNumInteractionClasses() const
237 return _interactionClassList.size();
240 const HLAOMTXmlVisitor::InteractionClass*
241 HLAOMTXmlVisitor::getInteractionClass(unsigned i) const
243 if (_interactionClassList.size() <= i)
245 return _interactionClassList[i];
248 SGSharedPtr<HLADataType>
249 HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName)
251 StringDataTypeMap::const_iterator i = _dataTypeMap.find(dataTypeName);
252 if (i != _dataTypeMap.end())
255 SGSharedPtr<HLADataType> dataType;
256 dataType = getBasicDataType(dataTypeName);
257 if (dataType.valid()) {
258 _dataTypeMap[dataTypeName] = dataType;
262 dataType = getSimpleDataType(dataTypeName);
263 if (dataType.valid())
266 dataType = getEnumeratedDataType(dataTypeName);
267 if (dataType.valid())
270 dataType = getArrayDataType(dataTypeName);
271 if (dataType.valid())
274 dataType = getFixedRecordDataType(dataTypeName);
275 if (dataType.valid())
278 dataType = getVariantRecordDataType(dataTypeName);
279 if (dataType.valid())
282 SG_LOG(SG_IO, SG_WARN, "Could not resolve dataType \"" << dataTypeName << "\".");
286 SGSharedPtr<HLABasicDataType>
287 HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName)
289 BasicDataMap::const_iterator i = _basicDataMap.find(dataTypeName);
290 if (i == _basicDataMap.end())
292 if (i->second._size == "8") {
293 return new HLAUInt8DataType(dataTypeName);
294 } else if (i->second._size == "16") {
295 if (i->first.find("Unsigned") != std::string::npos) {
296 if (i->second._endian == "Little") {
297 return new HLAUInt16LEDataType(dataTypeName);
299 return new HLAUInt16BEDataType(dataTypeName);
301 } else if (i->first.find("octetPair") != std::string::npos) {
302 if (i->second._endian == "Little") {
303 return new HLAUInt16LEDataType(dataTypeName);
305 return new HLAUInt16BEDataType(dataTypeName);
308 if (i->second._endian == "Little") {
309 return new HLAInt16LEDataType(dataTypeName);
311 return new HLAInt16BEDataType(dataTypeName);
314 } else if (i->second._size == "32") {
315 if (i->first.find("Unsigned") != std::string::npos) {
316 if (i->second._endian == "Little") {
317 return new HLAUInt32LEDataType(dataTypeName);
319 return new HLAUInt32BEDataType(dataTypeName);
321 } else if (i->first.find("float") != std::string::npos) {
322 if (i->second._endian == "Little") {
323 return new HLAFloat32LEDataType(dataTypeName);
325 return new HLAFloat32BEDataType(dataTypeName);
328 if (i->second._endian == "Little") {
329 return new HLAInt32LEDataType(dataTypeName);
331 return new HLAInt32BEDataType(dataTypeName);
334 } else if (i->second._size == "64") {
335 if (i->first.find("Unsigned") != std::string::npos) {
336 if (i->second._endian == "Little") {
337 return new HLAUInt64LEDataType(dataTypeName);
339 return new HLAUInt64BEDataType(dataTypeName);
341 } else if (i->first.find("float") != std::string::npos) {
342 if (i->second._endian == "Little") {
343 return new HLAFloat64LEDataType(dataTypeName);
345 return new HLAFloat64BEDataType(dataTypeName);
348 if (i->second._endian == "Little") {
349 return new HLAInt64LEDataType(dataTypeName);
351 return new HLAInt64BEDataType(dataTypeName);
359 SGSharedPtr<HLADataType>
360 HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName)
362 SimpleDataMap::const_iterator i = _simpleDataMap.find(dataTypeName);
363 if (i == _simpleDataMap.end())
365 return getDataType(i->second._representation);
368 SGSharedPtr<HLAEnumeratedDataType>
369 HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName)
371 EnumeratedDataMap::const_iterator i = _enumeratedDataMap.find(dataTypeName);
372 if (i == _enumeratedDataMap.end())
375 SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = new HLAEnumeratedDataType(dataTypeName);
376 _dataTypeMap[dataTypeName] = enumeratedDataType;
377 enumeratedDataType->setRepresentation(getBasicDataType(i->second._representation));
379 for (EnumeratorList::const_iterator j = i->second._enumeratorList.begin();
380 j != i->second._enumeratorList.end(); ++j) {
381 if (!enumeratedDataType->addEnumerator(j->_name, j->_values)) {
382 SG_LOG(SG_IO, SG_ALERT, "Could not add enumerator \"" << j->_name
383 << "\" to find enumerated data type \"" << dataTypeName << "\".");
388 return enumeratedDataType;
391 SGSharedPtr<HLADataType>
392 HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName)
394 ArrayDataMap::const_iterator i = _arrayDataMap.find(dataTypeName);
395 if (i == _arrayDataMap.end())
397 SGSharedPtr<HLAArrayDataType> arrayDataType;
398 if (i->second._encoding == "HLAvariableArray") {
399 arrayDataType = new HLAVariableArrayDataType(dataTypeName);
400 } else if (i->second._encoding == "HLAfixedArray") {
401 std::stringstream ss(i->second._cardinality);
402 unsigned cardinality;
405 SG_LOG(SG_IO, SG_ALERT, "Could not interpret cardinality \""
406 << i->second._cardinality << "\" for dataType \""
407 << dataTypeName << "\".");
410 SGSharedPtr<HLAFixedArrayDataType> dataType = new HLAFixedArrayDataType(dataTypeName);
411 dataType->setNumElements(cardinality);
412 arrayDataType = dataType;
414 SG_LOG(SG_IO, SG_ALERT, "Can not interpret encoding \""
415 << i->second._encoding << "\" for dataType \""
416 << dataTypeName << "\".");
420 _dataTypeMap[dataTypeName] = arrayDataType;
421 SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType);
422 if (!elementDataType.valid()) {
423 SG_LOG(SG_IO, SG_ALERT, "Could not interpret dataType \""
424 << i->second._dataType << "\" for array data type \""
425 << dataTypeName << "\".");
426 _dataTypeMap.erase(dataTypeName);
429 arrayDataType->setElementDataType(elementDataType.get());
431 // Check if this should be a string data type
432 if (elementDataType->toBasicDataType()) {
433 if (dataTypeName == "HLAopaqueData") {
434 arrayDataType->setIsOpaque(true);
435 } else if (dataTypeName.find("String") != std::string::npos || dataTypeName.find("string") != std::string::npos) {
436 arrayDataType->setIsString(true);
440 return arrayDataType;
443 SGSharedPtr<HLAFixedRecordDataType>
444 HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName)
446 FixedRecordDataMap::const_iterator i = _fixedRecordDataMap.find(dataTypeName);
447 if (i == _fixedRecordDataMap.end())
450 SGSharedPtr<HLAFixedRecordDataType> dataType = new HLAFixedRecordDataType(dataTypeName);
451 _dataTypeMap[dataTypeName] = dataType;
452 for (FieldList::size_type j = 0; j < i->second._fieldList.size(); ++j) {
453 SGSharedPtr<HLADataType> fieldDataType = getDataType(i->second._fieldList[j]._dataType);
454 if (!fieldDataType.valid()) {
455 SG_LOG(SG_IO, SG_ALERT, "Could not get data type \"" << i->second._fieldList[j]._dataType
456 << "\" for field " << j << "of fixed record data type \"" << dataTypeName << "\".");
457 _dataTypeMap.erase(dataTypeName);
460 dataType->addField(i->second._fieldList[j]._name, fieldDataType.get());
465 SGSharedPtr<HLAVariantRecordDataType>
466 HLAOMTXmlVisitor::getVariantRecordDataType(const std::string& dataTypeName)
468 VariantRecordDataMap::const_iterator i = _variantRecordDataMap.find(dataTypeName);
469 if (i == _variantRecordDataMap.end())
471 SGSharedPtr<HLAVariantRecordDataType> dataType = new HLAVariantRecordDataType(dataTypeName);
472 _dataTypeMap[dataTypeName] = dataType;
474 SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = getEnumeratedDataType(i->second._dataType);
475 if (!enumeratedDataType.valid()) {
476 SG_LOG(SG_IO, SG_ALERT, "Could not find enumerted data type \"" << i->second._dataType
477 << "\" for variant data type \"" << dataTypeName << "\".");
480 dataType->setEnumeratedDataType(enumeratedDataType);
482 for (AlternativeList::const_iterator j = i->second._alternativeList.begin();
483 j != i->second._alternativeList.end(); ++j) {
484 SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType);
485 if (!alternativeDataType.valid()) {
486 SG_LOG(SG_IO, SG_ALERT, "Could not resolve alternative dataType \"" << j->_dataType
487 << "\" for alternative \"" << j->_name << "\".");
488 _dataTypeMap.erase(dataTypeName);
491 if (!dataType->addAlternative(j->_name, j->_enumerator, alternativeDataType.get(), j->_semantics)) {
492 SG_LOG(SG_IO, SG_ALERT, "Could not add alternative \"" << j->_name << "\".");
499 HLAOMTXmlVisitor::Mode
500 HLAOMTXmlVisitor::getCurrentMode()
502 if (_modeStack.empty())
504 return _modeStack.back();
508 HLAOMTXmlVisitor::pushMode(HLAOMTXmlVisitor::Mode mode)
510 _modeStack.push_back(mode);
514 HLAOMTXmlVisitor::popMode()
516 _modeStack.pop_back();
520 HLAOMTXmlVisitor::startXML()
526 HLAOMTXmlVisitor::endXML()
528 if (!_modeStack.empty())
529 throw sg_exception("Internal parse error!");
531 // propagate parent attributes to the derived classes
532 // Note that this preserves the order og the attributes starting from the root object
533 for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
534 SGSharedPtr<const ObjectClass> objectClass = (*i)->_parentObjectClass;
535 while (objectClass) {
536 for (AttributeList::const_reverse_iterator j = objectClass->_attributes.rbegin();
537 j != objectClass->_attributes.rend(); ++j) {
538 (*i)->_attributes.insert((*i)->_attributes.begin(), *j);
540 objectClass = objectClass->_parentObjectClass;
544 // propagate parent parameter to the derived interactions
545 // Note that this preserves the order og the parameters starting from the root object
546 for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
547 SGSharedPtr<const InteractionClass> interactionClass = (*i)->_parentInteractionClass;
548 while (interactionClass) {
549 for (ParameterList::const_reverse_iterator j = interactionClass->_parameters.rbegin();
550 j != interactionClass->_parameters.rend(); ++j) {
551 (*i)->_parameters.insert((*i)->_parameters.begin(), *j);
553 interactionClass = interactionClass->_parentInteractionClass;
559 HLAOMTXmlVisitor::startElement(const char* name, const XMLAttributes& atts)
561 if (strcmp(name, "attribute") == 0) {
562 if (getCurrentMode() != ObjectClassMode)
563 throw sg_exception("attribute tag outside objectClass!");
564 pushMode(AttributeMode);
566 if (_objectClassList.empty())
567 throw sg_exception("attribute tag outside of an objectClass");
569 std::string name = getAttribute("name", atts);
571 throw sg_exception("attribute tag without name attribute");
573 SGSharedPtr<Attribute> attribute = new Attribute(name);
575 attribute->_dataType = getAttribute("dataType", atts);
576 attribute->_updateType = getAttribute("updateType", atts);
577 attribute->_updateCondition = getAttribute("updateCondition", atts);
578 attribute->_ownership = getAttribute("ownership", atts);
579 attribute->_sharing = getAttribute("sharing", atts);
580 attribute->_dimensions = getAttribute("dimensions", atts);
581 attribute->_transportation = getAttribute("transportation", atts);
582 attribute->_order = getAttribute("order", atts);
584 _objectClassStack.back()->_attributes.push_back(attribute);
586 } else if (strcmp(name, "objectClass") == 0) {
587 if (getCurrentMode() != ObjectsMode && getCurrentMode() != ObjectClassMode)
588 throw sg_exception("objectClass tag outside objectClass or objects!");
589 pushMode(ObjectClassMode);
591 std::string name = getAttribute("name", atts);
593 throw sg_exception("objectClass tag without name attribute");
595 std::string sharing = getAttribute("sharing", atts);
597 // The new ObjectClass
598 ObjectClass* objectClass = new ObjectClass(name, sharing);
600 // Inherit all previous attributes
601 if (!_objectClassStack.empty())
602 objectClass->_parentObjectClass = _objectClassStack.back();
604 _objectClassStack.push_back(objectClass);
605 _objectClassList.push_back(objectClass);
607 } else if (strcmp(name, "objects") == 0) {
608 if (getCurrentMode() != ObjectModelMode)
609 throw sg_exception("objects tag outside objectModel!");
610 pushMode(ObjectsMode);
612 } else if (strcmp(name, "parameter") == 0) {
613 if (getCurrentMode() != InteractionClassMode)
614 throw sg_exception("parameter tag outside interactionClass!");
615 pushMode(ParameterMode);
617 if (_interactionClassList.empty())
618 throw sg_exception("parameter tag outside of an interactionClass");
620 std::string name = getAttribute("name", atts);
622 throw sg_exception("parameter tag without name parameter");
624 SGSharedPtr<Parameter> parameter = new Parameter(name);
625 parameter->_dataType = getAttribute("dataType", atts);
627 _interactionClassStack.back()->_parameters.push_back(parameter);
629 } else if (strcmp(name, "interactionClass") == 0) {
630 if (getCurrentMode() != InteractionsMode && getCurrentMode() != InteractionClassMode)
631 throw sg_exception("interactionClass tag outside interactions or interactionClass!");
632 pushMode(InteractionClassMode);
634 std::string name = getAttribute("name", atts);
636 throw sg_exception("interactionClass tag without name attribute");
638 // The new ObjectClass
639 InteractionClass* interactionClass = new InteractionClass(name);
640 interactionClass->_dimensions = getAttribute("dimensions", atts);
641 interactionClass->_transportation = getAttribute("transportation", atts);
642 interactionClass->_order = getAttribute("order", atts);
644 // Inherit all previous attributes
645 if (!_interactionClassStack.empty())
646 interactionClass->_parentInteractionClass = _interactionClassStack.back();
648 _interactionClassStack.push_back(interactionClass);
649 _interactionClassList.push_back(interactionClass);
651 } else if (strcmp(name, "interactions") == 0) {
652 if (getCurrentMode() != ObjectModelMode)
653 throw sg_exception("interactions tag outside objectModel!");
654 pushMode(InteractionsMode);
656 } else if (strcmp(name, "basicData") == 0) {
657 if (getCurrentMode() != BasicDataRepresentationsMode)
658 throw sg_exception("basicData tag outside basicDataRepresentations!");
659 pushMode(BasicDataMode);
661 std::string name = getAttribute("name", atts);
663 throw sg_exception("basicData tag without name attribute");
665 _basicDataMap[name]._size = getAttribute("size", atts);
666 _basicDataMap[name]._endian = getAttribute("endian", atts);
668 } else if (strcmp(name, "basicDataRepresentations") == 0) {
669 if (getCurrentMode() != DataTypesMode)
670 throw sg_exception("basicDataRepresentations tag outside dataTypes!");
671 pushMode(BasicDataRepresentationsMode);
673 } else if (strcmp(name, "simpleData") == 0) {
674 if (getCurrentMode() != SimpleDataTypesMode)
675 throw sg_exception("simpleData tag outside simpleDataTypes!");
676 pushMode(SimpleDataMode);
678 std::string name = getAttribute("name", atts);
680 throw sg_exception("simpleData tag without name attribute");
682 _simpleDataMap[name]._representation = getAttribute("representation", atts);
683 _simpleDataMap[name]._units = getAttribute("units", atts);
684 _simpleDataMap[name]._resolution = getAttribute("resolution", atts);
685 _simpleDataMap[name]._accuracy = getAttribute("accuracy", atts);
687 } else if (strcmp(name, "simpleDataTypes") == 0) {
688 if (getCurrentMode() != DataTypesMode)
689 throw sg_exception("simpleDataTypes tag outside dataTypes!");
690 pushMode(SimpleDataTypesMode);
692 } else if (strcmp(name, "enumerator") == 0) {
693 if (getCurrentMode() != EnumeratedDataMode)
694 throw sg_exception("enumerator tag outside enumeratedData!");
695 pushMode(EnumeratorMode);
697 std::string name = getAttribute("name", atts);
699 throw sg_exception("enumerator tag without name attribute");
701 Enumerator enumerator;
702 enumerator._name = name;
703 enumerator._values = getAttribute("values", atts);
704 _enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
706 } else if (strcmp(name, "enumeratedData") == 0) {
707 if (getCurrentMode() != EnumeratedDataTypesMode)
708 throw sg_exception("enumeratedData tag outside enumeratedDataTypes!");
709 pushMode(EnumeratedDataMode);
711 std::string name = getAttribute("name", atts);
713 throw sg_exception("enumeratedData tag without name attribute");
715 _enumeratedDataName = name;
716 _enumeratedDataMap[_enumeratedDataName]._representation = getAttribute("representation", atts);
718 } else if (strcmp(name, "enumeratedDataTypes") == 0) {
719 if (getCurrentMode() != DataTypesMode)
720 throw sg_exception("enumeratedDataTypes tag outside dataTypes!");
721 pushMode(EnumeratedDataTypesMode);
723 } else if (strcmp(name, "arrayData") == 0) {
724 if (getCurrentMode() != ArrayDataTypesMode)
725 throw sg_exception("arrayData tag outside arrayDataTypes!");
726 pushMode(ArrayDataMode);
728 std::string name = getAttribute("name", atts);
730 throw sg_exception("arrayData tag without name attribute");
732 _arrayDataMap[name]._dataType = getAttribute("dataType", atts);
733 _arrayDataMap[name]._cardinality = getAttribute("cardinality", atts);
734 _arrayDataMap[name]._encoding = getAttribute("encoding", atts);
736 } else if (strcmp(name, "arrayDataTypes") == 0) {
737 if (getCurrentMode() != DataTypesMode)
738 throw sg_exception("arrayDataTypes tag outside dataTypes!");
739 pushMode(ArrayDataTypesMode);
741 } else if (strcmp(name, "field") == 0) {
742 if (getCurrentMode() != FixedRecordDataMode)
743 throw sg_exception("field tag outside fixedRecordData!");
746 std::string name = getAttribute("name", atts);
748 throw sg_exception("field tag without name attribute");
752 field._dataType = getAttribute("dataType", atts);
753 _fixedRecordDataMap[_fixedRecordDataName]._fieldList.push_back(field);
755 } else if (strcmp(name, "fixedRecordData") == 0) {
756 if (getCurrentMode() != FixedRecordDataTypesMode)
757 throw sg_exception("fixedRecordData tag outside fixedRecordDataTypes!");
758 pushMode(FixedRecordDataMode);
760 std::string name = getAttribute("name", atts);
762 throw sg_exception("fixedRecordData tag without name attribute");
764 _fixedRecordDataName = name;
765 _fixedRecordDataMap[name]._encoding = getAttribute("encoding", atts);
767 } else if (strcmp(name, "fixedRecordDataTypes") == 0) {
768 if (getCurrentMode() != DataTypesMode)
769 throw sg_exception("fixedRecordDataTypes tag outside dataTypes!");
770 pushMode(FixedRecordDataTypesMode);
772 } else if (strcmp(name, "alternative") == 0) {
774 if (getCurrentMode() != VariantRecordDataMode)
775 throw sg_exception("alternative tag outside variantRecordData!");
776 pushMode(AlternativeDataMode);
778 std::string name = getAttribute("name", atts);
780 throw sg_exception("alternative tag without name attribute");
782 Alternative alternative;
783 alternative._name = name;
784 alternative._dataType = getAttribute("dataType", atts);
785 alternative._semantics = getAttribute("semantics", atts);
786 alternative._enumerator = getAttribute("enumerator", atts);
787 _variantRecordDataMap[_variantRecordDataName]._alternativeList.push_back(alternative);
789 } else if (strcmp(name, "variantRecordData") == 0) {
790 if (getCurrentMode() != VariantRecordDataTypesMode)
791 throw sg_exception("variantRecordData tag outside variantRecordDataTypes!");
792 pushMode(VariantRecordDataMode);
794 std::string name = getAttribute("name", atts);
796 throw sg_exception("fixedRecordData tag without name attribute");
798 _variantRecordDataName = name;
799 _variantRecordDataMap[name]._encoding = getAttribute("encoding", atts);
800 _variantRecordDataMap[name]._dataType = getAttribute("dataType", atts);
801 _variantRecordDataMap[name]._semantics = getAttribute("semantics", atts);
802 _variantRecordDataMap[name]._discriminant = getAttribute("discriminant", atts);
804 } else if (strcmp(name, "variantRecordDataTypes") == 0) {
805 if (getCurrentMode() != DataTypesMode)
806 throw sg_exception("variantRecordDataTypes tag outside dataTypes!");
807 pushMode(VariantRecordDataTypesMode);
809 } else if (strcmp(name, "dataTypes") == 0) {
810 if (getCurrentMode() != ObjectModelMode)
811 throw sg_exception("dataTypes tag outside objectModel!");
812 pushMode(DataTypesMode);
814 } else if (strcmp(name, "objectModel") == 0) {
815 if (!_modeStack.empty())
816 throw sg_exception("objectModel tag not at top level!");
817 pushMode(ObjectModelMode);
820 _modeStack.push_back(UnknownMode);
825 HLAOMTXmlVisitor::endElement(const char* name)
827 if (strcmp(name, "objectClass") == 0) {
828 _objectClassStack.pop_back();
829 } else if (strcmp(name, "interactionClass") == 0) {
830 _interactionClassStack.pop_back();
831 } else if (strcmp(name, "enumeratedData") == 0) {
832 _enumeratedDataName.clear();
833 } else if (strcmp(name, "fixedRecordData") == 0) {
834 _fixedRecordDataName.clear();
835 } else if (strcmp(name, "variantRecordData") == 0) {
836 _variantRecordDataName.clear();
839 _modeStack.pop_back();
843 HLAOMTXmlVisitor::getAttribute(const char* name, const XMLAttributes& atts)
845 int index = atts.findAttribute(name);
846 if (index < 0 || atts.size() <= index)
847 return std::string();
848 return std::string(atts.getValue(index));
852 HLAOMTXmlVisitor::getAttribute(const std::string& name, const XMLAttributes& atts)
854 int index = atts.findAttribute(name.c_str());
855 if (index < 0 || atts.size() <= index)
856 return std::string();
857 return std::string(atts.getValue(index));
860 } // namespace simgear