1 // Copyright (C) 2009 - 2011 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 "HLAFixedRecordDataType.hxx"
31 #include "HLAVariantDataType.hxx"
35 HLAOMTXmlVisitor::ObjectClass::ObjectClass(const std::string& name, const std::string& sharing) :
41 HLAOMTXmlVisitor::ObjectClass::~ObjectClass()
46 HLAOMTXmlVisitor::ObjectClass::getName() const
52 HLAOMTXmlVisitor::ObjectClass::getSharing() const
58 HLAOMTXmlVisitor::ObjectClass::getNumAttributes() const
60 return _attributes.size();
63 const HLAOMTXmlVisitor::Attribute*
64 HLAOMTXmlVisitor::ObjectClass::getAttribute(unsigned index) const
66 if (_attributes.size() <= index)
68 return _attributes[index];
71 const HLAOMTXmlVisitor::Attribute*
72 HLAOMTXmlVisitor::ObjectClass::getAttribute(const std::string& name) const
74 for (AttributeList::const_iterator i = _attributes.begin(); i != _attributes.end(); ++i) {
75 if ((*i)->_name != name)
79 SG_LOG(SG_IO, SG_ALERT, "Could not find class attribute \"" << name << "\".");
83 const HLAOMTXmlVisitor::ObjectClass*
84 HLAOMTXmlVisitor::ObjectClass::getParentObjectClass() const
86 return _parentObjectClass.get();
89 HLAOMTXmlVisitor::InteractionClass::InteractionClass(const std::string& name) :
94 HLAOMTXmlVisitor::InteractionClass::~InteractionClass()
99 HLAOMTXmlVisitor::InteractionClass::getName() const
105 HLAOMTXmlVisitor::InteractionClass::getDimensions() const
111 HLAOMTXmlVisitor::InteractionClass::getTransportation() const
113 return _transportation;
117 HLAOMTXmlVisitor::InteractionClass::getOrder() const
123 HLAOMTXmlVisitor::InteractionClass::getNumParameters() const
125 return _parameters.size();
128 const HLAOMTXmlVisitor::Parameter*
129 HLAOMTXmlVisitor::InteractionClass::getParameter(unsigned index) const
131 if (_parameters.size() <= index)
133 return _parameters[index];
136 const HLAOMTXmlVisitor::Parameter*
137 HLAOMTXmlVisitor::InteractionClass::getParameter(const std::string& name) const
139 for (ParameterList::const_iterator i = _parameters.begin(); i != _parameters.end(); ++i) {
140 if ((*i)->_name != name)
144 SG_LOG(SG_IO, SG_ALERT, "Could not find parameter \"" << name << "\".");
148 const HLAOMTXmlVisitor::InteractionClass*
149 HLAOMTXmlVisitor::InteractionClass::getParentInteractionClass() const
151 return _parentInteractionClass.get();
154 HLAOMTXmlVisitor::HLAOMTXmlVisitor()
158 HLAOMTXmlVisitor::~HLAOMTXmlVisitor()
163 HLAOMTXmlVisitor::getNumObjectClasses() const
165 return _objectClassList.size();
168 const HLAOMTXmlVisitor::ObjectClass*
169 HLAOMTXmlVisitor::getObjectClass(unsigned i) const
171 if (_objectClassList.size() <= i)
173 return _objectClassList[i];
176 const HLAOMTXmlVisitor::ObjectClass*
177 HLAOMTXmlVisitor::getObjectClass(const std::string& name) const
179 for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
180 if ((*i)->_name != name)
184 SG_LOG(SG_IO, SG_ALERT, "Could not resolve ObjectClass \"" << name << "\".");
188 const HLAOMTXmlVisitor::Attribute*
189 HLAOMTXmlVisitor::getAttribute(const std::string& objectClassName, const std::string& attributeName) const
191 const ObjectClass* objectClass = getObjectClass(objectClassName);
194 return objectClass->getAttribute(attributeName);
198 HLAOMTXmlVisitor::getAttributeDataType(const std::string& objectClassName, const std::string& attributeName) const
200 const Attribute* attribute = getAttribute(objectClassName, attributeName);
203 return getDataType(attribute->_dataType);
207 HLAOMTXmlVisitor::getNumInteractionClasses() const
209 return _interactionClassList.size();
212 const HLAOMTXmlVisitor::InteractionClass*
213 HLAOMTXmlVisitor::getInteractionClass(unsigned i) const
215 if (_interactionClassList.size() <= i)
217 return _interactionClassList[i];
220 const HLAOMTXmlVisitor::InteractionClass*
221 HLAOMTXmlVisitor::getInteractionClass(const std::string& name) const
223 for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
224 if ((*i)->_name != name)
228 SG_LOG(SG_IO, SG_ALERT, "Could not resolve InteractionClass \"" << name << "\".");
232 const HLAOMTXmlVisitor::Parameter*
233 HLAOMTXmlVisitor::getParameter(const std::string& interactionClassName, const std::string& parameterName) const
235 const InteractionClass* interactionClass = getInteractionClass(interactionClassName);
236 if (!interactionClass)
238 return interactionClass->getParameter(parameterName);
242 HLAOMTXmlVisitor::getParameterDataType(const std::string& interactionClassName, const std::string& parameterName) const
244 const Parameter* parameter = getParameter(interactionClassName, parameterName);
247 return getDataType(parameter->_dataType);
251 HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName) const
253 SGSharedPtr<HLADataType> dataType;
255 // Playing dirty things with reference counts
256 StringDataTypeMap dataTypeMap;
257 dataType = getDataType(dataTypeName, dataTypeMap);
259 return dataType.release();
262 SGSharedPtr<HLADataType>
263 HLAOMTXmlVisitor::getDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
265 StringDataTypeMap::const_iterator i = dataTypeMap.find(dataTypeName);
266 if (i != dataTypeMap.end())
267 return new HLADataTypeReference(i->second);
269 SGSharedPtr<HLADataType> dataType;
270 dataType = getBasicDataType(dataTypeName);
271 if (dataType.valid())
274 dataType = getSimpleDataType(dataTypeName);
275 if (dataType.valid())
278 dataType = getEnumeratedDataType(dataTypeName);
279 if (dataType.valid())
282 dataType = getArrayDataType(dataTypeName, dataTypeMap);
283 if (dataType.valid())
286 dataType = getFixedRecordDataType(dataTypeName, dataTypeMap);
287 if (dataType.valid())
290 dataType = getVariantDataType(dataTypeName, dataTypeMap);
291 if (dataType.valid())
294 SG_LOG(SG_IO, SG_WARN, "Could not resolve dataType \"" << dataTypeName << "\".");
298 SGSharedPtr<HLABasicDataType>
299 HLAOMTXmlVisitor::getBasicDataType(const std::string& dataTypeName) const
301 BasicDataMap::const_iterator i = _basicDataMap.find(dataTypeName);
302 if (i == _basicDataMap.end())
304 if (i->second._size == "8") {
305 return new HLAUInt8DataType(dataTypeName);
306 } else if (i->second._size == "16") {
307 if (i->first.find("Unsigned") != std::string::npos) {
308 if (i->second._endian == "Little") {
309 return new HLAUInt16LEDataType(dataTypeName);
311 return new HLAUInt16BEDataType(dataTypeName);
313 } else if (i->first.find("octetPair") != std::string::npos) {
314 if (i->second._endian == "Little") {
315 return new HLAUInt16LEDataType(dataTypeName);
317 return new HLAUInt16BEDataType(dataTypeName);
320 if (i->second._endian == "Little") {
321 return new HLAInt16LEDataType(dataTypeName);
323 return new HLAInt16BEDataType(dataTypeName);
326 } else if (i->second._size == "32") {
327 if (i->first.find("Unsigned") != std::string::npos) {
328 if (i->second._endian == "Little") {
329 return new HLAUInt32LEDataType(dataTypeName);
331 return new HLAUInt32BEDataType(dataTypeName);
333 } else if (i->first.find("float") != std::string::npos) {
334 if (i->second._endian == "Little") {
335 return new HLAFloat32LEDataType(dataTypeName);
337 return new HLAFloat32BEDataType(dataTypeName);
340 if (i->second._endian == "Little") {
341 return new HLAInt32LEDataType(dataTypeName);
343 return new HLAInt32BEDataType(dataTypeName);
346 } else if (i->second._size == "64") {
347 if (i->first.find("Unsigned") != std::string::npos) {
348 if (i->second._endian == "Little") {
349 return new HLAUInt64LEDataType(dataTypeName);
351 return new HLAUInt64BEDataType(dataTypeName);
353 } else if (i->first.find("float") != std::string::npos) {
354 if (i->second._endian == "Little") {
355 return new HLAFloat64LEDataType(dataTypeName);
357 return new HLAFloat64BEDataType(dataTypeName);
360 if (i->second._endian == "Little") {
361 return new HLAInt64LEDataType(dataTypeName);
363 return new HLAInt64BEDataType(dataTypeName);
371 SGSharedPtr<HLADataType>
372 HLAOMTXmlVisitor::getSimpleDataType(const std::string& dataTypeName) const
374 SimpleDataMap::const_iterator i = _simpleDataMap.find(dataTypeName);
375 if (i == _simpleDataMap.end())
377 return getDataType(i->second._representation);
380 SGSharedPtr<HLAEnumeratedDataType>
381 HLAOMTXmlVisitor::getEnumeratedDataType(const std::string& dataTypeName) const
383 EnumeratedDataMap::const_iterator i = _enumeratedDataMap.find(dataTypeName);
384 if (i == _enumeratedDataMap.end())
387 SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = new HLAEnumeratedDataType(dataTypeName);
388 enumeratedDataType->setRepresentation(getBasicDataType(i->second._representation));
390 for (EnumeratorList::const_iterator j = i->second._enumeratorList.begin();
391 j != i->second._enumeratorList.end(); ++j) {
392 if (!enumeratedDataType->addEnumerator(j->_name, j->_values)) {
393 SG_LOG(SG_IO, SG_ALERT, "Could not add enumerator \"" << j->_name
394 << "\" to find enumerated data type \"" << dataTypeName << "\".");
399 return enumeratedDataType;
402 SGSharedPtr<HLADataType>
403 HLAOMTXmlVisitor::getArrayDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
405 ArrayDataMap::const_iterator i = _arrayDataMap.find(dataTypeName);
406 if (i == _arrayDataMap.end())
408 SGSharedPtr<HLAArrayDataType> arrayDataType;
409 if (i->second._encoding == "HLAvariableArray") {
410 arrayDataType = new HLAVariableArrayDataType(dataTypeName);
411 } else if (i->second._encoding == "HLAfixedArray") {
412 std::stringstream ss(i->second._cardinality);
413 unsigned cardinality;
416 SG_LOG(SG_IO, SG_ALERT, "Could not interpret cardinality \""
417 << i->second._cardinality << "\" for dataType \""
418 << dataTypeName << "\".");
421 SGSharedPtr<HLAFixedArrayDataType> dataType = new HLAFixedArrayDataType(dataTypeName);
422 dataType->setNumElements(cardinality);
423 arrayDataType = dataType;
425 SG_LOG(SG_IO, SG_ALERT, "Can not interpret encoding \""
426 << i->second._encoding << "\" for dataType \""
427 << dataTypeName << "\".");
431 dataTypeMap[dataTypeName] = arrayDataType;
432 SGSharedPtr<HLADataType> elementDataType = getDataType(i->second._dataType, dataTypeMap);
433 if (!elementDataType.valid()) {
434 SG_LOG(SG_IO, SG_ALERT, "Could not interpret dataType \""
435 << i->second._dataType << "\" for array data type \""
436 << dataTypeName << "\".");
437 dataTypeMap.erase(dataTypeName);
440 arrayDataType->setElementDataType(elementDataType.get());
442 // Check if this should be a string data type
443 if (elementDataType->toBasicDataType()) {
444 if (dataTypeName == "HLAopaqueData") {
445 arrayDataType->setIsOpaque(true);
446 } else if (dataTypeName.find("String") != std::string::npos || dataTypeName.find("string") != std::string::npos) {
447 arrayDataType->setIsString(true);
451 return arrayDataType;
454 SGSharedPtr<HLAFixedRecordDataType>
455 HLAOMTXmlVisitor::getFixedRecordDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
457 FixedRecordDataMap::const_iterator i = _fixedRecordDataMap.find(dataTypeName);
458 if (i == _fixedRecordDataMap.end())
461 SGSharedPtr<HLAFixedRecordDataType> dataType = new HLAFixedRecordDataType(dataTypeName);
462 dataTypeMap[dataTypeName] = dataType;
463 for (FieldList::size_type j = 0; j < i->second._fieldList.size(); ++j) {
464 SGSharedPtr<HLADataType> fieldDataType = getDataType(i->second._fieldList[j]._dataType, dataTypeMap);
465 if (!fieldDataType.valid()) {
466 SG_LOG(SG_IO, SG_ALERT, "Could not get data type \"" << i->second._fieldList[j]._dataType
467 << "\" for field " << j << "of fixed record data type \"" << dataTypeName << "\".");
468 dataTypeMap.erase(dataTypeName);
471 dataType->addField(i->second._fieldList[j]._name, fieldDataType.get());
476 SGSharedPtr<HLAVariantDataType>
477 HLAOMTXmlVisitor::getVariantDataType(const std::string& dataTypeName, HLAOMTXmlVisitor::StringDataTypeMap& dataTypeMap) const
479 VariantRecordDataMap::const_iterator i = _variantRecordDataMap.find(dataTypeName);
480 if (i == _variantRecordDataMap.end())
482 SGSharedPtr<HLAVariantDataType> dataType = new HLAVariantDataType(dataTypeName);
483 dataTypeMap[dataTypeName] = dataType;
485 SGSharedPtr<HLAEnumeratedDataType> enumeratedDataType = getEnumeratedDataType(i->second._dataType);
486 if (!enumeratedDataType.valid()) {
487 SG_LOG(SG_IO, SG_ALERT, "Could not find enumerted data type \"" << i->second._dataType
488 << "\" for variant data type \"" << dataTypeName << "\".");
491 dataType->setEnumeratedDataType(enumeratedDataType);
493 for (AlternativeList::const_iterator j = i->second._alternativeList.begin();
494 j != i->second._alternativeList.end(); ++j) {
495 SGSharedPtr<HLADataType> alternativeDataType = getDataType(j->_dataType, dataTypeMap);
496 if (!alternativeDataType.valid()) {
497 SG_LOG(SG_IO, SG_ALERT, "Could not resolve alternative dataType \"" << j->_dataType
498 << "\" for alternative \"" << j->_name << "\".");
499 dataTypeMap.erase(dataTypeName);
502 if (!dataType->addAlternative(j->_name, j->_enumerator, alternativeDataType.get(), j->_semantics)) {
503 SG_LOG(SG_IO, SG_ALERT, "Could not add alternative \"" << j->_name << "\".");
510 HLAOMTXmlVisitor::Mode
511 HLAOMTXmlVisitor::getCurrentMode()
513 if (_modeStack.empty())
515 return _modeStack.back();
519 HLAOMTXmlVisitor::pushMode(HLAOMTXmlVisitor::Mode mode)
521 _modeStack.push_back(mode);
525 HLAOMTXmlVisitor::popMode()
527 _modeStack.pop_back();
531 HLAOMTXmlVisitor::startXML()
537 HLAOMTXmlVisitor::endXML()
539 if (!_modeStack.empty())
540 throw sg_exception("Internal parse error!");
542 // propagate parent attributes to the derived classes
543 for (ObjectClassList::const_iterator i = _objectClassList.begin(); i != _objectClassList.end(); ++i) {
544 SGSharedPtr<const ObjectClass> objectClass = (*i)->_parentObjectClass;
545 while (objectClass) {
546 for (AttributeList::const_reverse_iterator j = objectClass->_attributes.rbegin();
547 j != objectClass->_attributes.rend(); ++j) {
548 (*i)->_attributes.insert((*i)->_attributes.begin(), *j);
550 objectClass = objectClass->_parentObjectClass;
554 // propagate parent parameter to the derived interactions
555 for (InteractionClassList::const_iterator i = _interactionClassList.begin(); i != _interactionClassList.end(); ++i) {
556 SGSharedPtr<const InteractionClass> interactionClass = (*i)->_parentInteractionClass;
557 while (interactionClass) {
558 for (ParameterList::const_reverse_iterator j = interactionClass->_parameters.rbegin();
559 j != interactionClass->_parameters.rend(); ++j) {
560 (*i)->_parameters.insert((*i)->_parameters.begin(), *j);
562 interactionClass = interactionClass->_parentInteractionClass;
568 HLAOMTXmlVisitor::startElement(const char* name, const XMLAttributes& atts)
570 if (strcmp(name, "attribute") == 0) {
571 if (getCurrentMode() != ObjectClassMode)
572 throw sg_exception("attribute tag outside objectClass!");
573 pushMode(AttributeMode);
575 if (_objectClassList.empty())
576 throw sg_exception("attribute tag outside of an objectClass");
578 std::string name = getAttribute("name", atts);
580 throw sg_exception("attribute tag without name attribute");
582 SGSharedPtr<Attribute> attribute = new Attribute(name);
584 attribute->_dataType = getAttribute("dataType", atts);
585 attribute->_updateType = getAttribute("updateType", atts);
586 attribute->_updateCondition = getAttribute("updateCondition", atts);
587 attribute->_ownership = getAttribute("ownership", atts);
588 attribute->_sharing = getAttribute("sharing", atts);
589 attribute->_dimensions = getAttribute("dimensions", atts);
590 attribute->_transportation = getAttribute("transportation", atts);
591 attribute->_order = getAttribute("order", atts);
593 _objectClassStack.back()->_attributes.push_back(attribute);
595 } else if (strcmp(name, "objectClass") == 0) {
596 if (getCurrentMode() != ObjectsMode && getCurrentMode() != ObjectClassMode)
597 throw sg_exception("objectClass tag outside objectClass or objects!");
598 pushMode(ObjectClassMode);
600 std::string name = getAttribute("name", atts);
602 throw sg_exception("objectClass tag without name attribute");
604 std::string sharing = getAttribute("sharing", atts);
606 // The new ObjectClass
607 ObjectClass* objectClass = new ObjectClass(name, sharing);
609 // Inherit all previous attributes
610 if (!_objectClassStack.empty())
611 objectClass->_parentObjectClass = _objectClassStack.back();
613 _objectClassStack.push_back(objectClass);
614 _objectClassList.push_back(objectClass);
616 } else if (strcmp(name, "objects") == 0) {
617 if (getCurrentMode() != ObjectModelMode)
618 throw sg_exception("objects tag outside objectModel!");
619 pushMode(ObjectsMode);
621 } else if (strcmp(name, "parameter") == 0) {
622 if (getCurrentMode() != InteractionClassMode)
623 throw sg_exception("parameter tag outside interactionClass!");
624 pushMode(ParameterMode);
626 if (_interactionClassList.empty())
627 throw sg_exception("parameter tag outside of an interactionClass");
629 std::string name = getAttribute("name", atts);
631 throw sg_exception("parameter tag without name parameter");
633 SGSharedPtr<Parameter> parameter = new Parameter(name);
634 parameter->_dataType = getAttribute("dataType", atts);
636 _interactionClassStack.back()->_parameters.push_back(parameter);
638 } else if (strcmp(name, "interactionClass") == 0) {
639 if (getCurrentMode() != InteractionsMode && getCurrentMode() != InteractionClassMode)
640 throw sg_exception("interactionClass tag outside interactions or interactionClass!");
641 pushMode(InteractionClassMode);
643 std::string name = getAttribute("name", atts);
645 throw sg_exception("interactionClass tag without name attribute");
647 // The new ObjectClass
648 InteractionClass* interactionClass = new InteractionClass(name);
649 interactionClass->_dimensions = getAttribute("dimensions", atts);
650 interactionClass->_transportation = getAttribute("transportation", atts);
651 interactionClass->_order = getAttribute("order", atts);
653 // Inherit all previous attributes
654 if (!_interactionClassStack.empty())
655 interactionClass->_parentInteractionClass = _interactionClassStack.back();
657 _interactionClassStack.push_back(interactionClass);
658 _interactionClassList.push_back(interactionClass);
660 } else if (strcmp(name, "interactions") == 0) {
661 if (getCurrentMode() != ObjectModelMode)
662 throw sg_exception("interactions tag outside objectModel!");
663 pushMode(InteractionsMode);
665 } else if (strcmp(name, "basicData") == 0) {
666 if (getCurrentMode() != BasicDataRepresentationsMode)
667 throw sg_exception("basicData tag outside basicDataRepresentations!");
668 pushMode(BasicDataMode);
670 std::string name = getAttribute("name", atts);
672 throw sg_exception("basicData tag without name attribute");
674 _basicDataMap[name]._size = getAttribute("size", atts);
675 _basicDataMap[name]._endian = getAttribute("endian", atts);
677 } else if (strcmp(name, "basicDataRepresentations") == 0) {
678 if (getCurrentMode() != DataTypesMode)
679 throw sg_exception("basicDataRepresentations tag outside dataTypes!");
680 pushMode(BasicDataRepresentationsMode);
682 } else if (strcmp(name, "simpleData") == 0) {
683 if (getCurrentMode() != SimpleDataTypesMode)
684 throw sg_exception("simpleData tag outside simpleDataTypes!");
685 pushMode(SimpleDataMode);
687 std::string name = getAttribute("name", atts);
689 throw sg_exception("simpleData tag without name attribute");
691 _simpleDataMap[name]._representation = getAttribute("representation", atts);
692 _simpleDataMap[name]._units = getAttribute("units", atts);
693 _simpleDataMap[name]._resolution = getAttribute("resolution", atts);
694 _simpleDataMap[name]._accuracy = getAttribute("accuracy", atts);
696 } else if (strcmp(name, "simpleDataTypes") == 0) {
697 if (getCurrentMode() != DataTypesMode)
698 throw sg_exception("simpleDataTypes tag outside dataTypes!");
699 pushMode(SimpleDataTypesMode);
701 } else if (strcmp(name, "enumerator") == 0) {
702 if (getCurrentMode() != EnumeratedDataMode)
703 throw sg_exception("enumerator tag outside enumeratedData!");
704 pushMode(EnumeratorMode);
706 std::string name = getAttribute("name", atts);
708 throw sg_exception("enumerator tag without name attribute");
710 Enumerator enumerator;
711 enumerator._name = name;
712 enumerator._values = getAttribute("values", atts);
713 _enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
715 } else if (strcmp(name, "enumeratedData") == 0) {
716 if (getCurrentMode() != EnumeratedDataTypesMode)
717 throw sg_exception("enumeratedData tag outside enumeratedDataTypes!");
718 pushMode(EnumeratedDataMode);
720 std::string name = getAttribute("name", atts);
722 throw sg_exception("enumeratedData tag without name attribute");
724 _enumeratedDataName = name;
725 _enumeratedDataMap[_enumeratedDataName]._representation = getAttribute("representation", atts);
727 } else if (strcmp(name, "enumeratedDataTypes") == 0) {
728 if (getCurrentMode() != DataTypesMode)
729 throw sg_exception("enumeratedDataTypes tag outside dataTypes!");
730 pushMode(EnumeratedDataTypesMode);
732 Enumerator enumerator;
733 enumerator._name = getAttribute("name", atts);
734 enumerator._values = getAttribute("values", atts);
735 _enumeratedDataMap[_enumeratedDataName]._enumeratorList.push_back(enumerator);
737 } else if (strcmp(name, "arrayData") == 0) {
738 if (getCurrentMode() != ArrayDataTypesMode)
739 throw sg_exception("arrayData tag outside arrayDataTypes!");
740 pushMode(ArrayDataMode);
742 std::string name = getAttribute("name", atts);
744 throw sg_exception("arrayData tag without name attribute");
746 _arrayDataMap[name]._dataType = getAttribute("dataType", atts);
747 _arrayDataMap[name]._cardinality = getAttribute("cardinality", atts);
748 _arrayDataMap[name]._encoding = getAttribute("encoding", atts);
750 } else if (strcmp(name, "arrayDataTypes") == 0) {
751 if (getCurrentMode() != DataTypesMode)
752 throw sg_exception("arrayDataTypes tag outside dataTypes!");
753 pushMode(ArrayDataTypesMode);
755 } else if (strcmp(name, "field") == 0) {
756 if (getCurrentMode() != FixedRecordDataMode)
757 throw sg_exception("field tag outside fixedRecordData!");
760 std::string name = getAttribute("name", atts);
762 throw sg_exception("field tag without name attribute");
766 field._dataType = getAttribute("dataType", atts);
767 _fixedRecordDataMap[_fixedRecordDataName]._fieldList.push_back(field);
769 } else if (strcmp(name, "fixedRecordData") == 0) {
770 if (getCurrentMode() != FixedRecordDataTypesMode)
771 throw sg_exception("fixedRecordData tag outside fixedRecordDataTypes!");
772 pushMode(FixedRecordDataMode);
774 std::string name = getAttribute("name", atts);
776 throw sg_exception("fixedRecordData tag without name attribute");
778 _fixedRecordDataName = name;
779 _fixedRecordDataMap[name]._encoding = getAttribute("encoding", atts);
781 } else if (strcmp(name, "fixedRecordDataTypes") == 0) {
782 if (getCurrentMode() != DataTypesMode)
783 throw sg_exception("fixedRecordDataTypes tag outside dataTypes!");
784 pushMode(FixedRecordDataTypesMode);
786 } else if (strcmp(name, "alternative") == 0) {
788 if (getCurrentMode() != VariantRecordDataMode)
789 throw sg_exception("alternative tag outside variantRecordData!");
790 pushMode(AlternativeDataMode);
792 std::string name = getAttribute("name", atts);
794 throw sg_exception("alternative tag without name attribute");
796 Alternative alternative;
797 alternative._name = name;
798 alternative._dataType = getAttribute("dataType", atts);
799 alternative._semantics = getAttribute("semantics", atts);
800 alternative._enumerator = getAttribute("enumerator", atts);
801 _variantRecordDataMap[_variantRecordDataName]._alternativeList.push_back(alternative);
803 } else if (strcmp(name, "variantRecordData") == 0) {
804 if (getCurrentMode() != VariantRecordDataTypesMode)
805 throw sg_exception("variantRecordData tag outside variantRecordDataTypes!");
806 pushMode(VariantRecordDataMode);
808 std::string name = getAttribute("name", atts);
810 throw sg_exception("fixedRecordData tag without name attribute");
812 _variantRecordDataName = name;
813 _variantRecordDataMap[name]._encoding = getAttribute("encoding", atts);
814 _variantRecordDataMap[name]._dataType = getAttribute("dataType", atts);
815 _variantRecordDataMap[name]._semantics = getAttribute("semantics", atts);
816 _variantRecordDataMap[name]._discriminant = getAttribute("discriminant", atts);
818 } else if (strcmp(name, "variantRecordDataTypes") == 0) {
819 if (getCurrentMode() != DataTypesMode)
820 throw sg_exception("variantRecordDataTypes tag outside dataTypes!");
821 pushMode(VariantRecordDataTypesMode);
823 } else if (strcmp(name, "dataTypes") == 0) {
824 if (getCurrentMode() != ObjectModelMode)
825 throw sg_exception("dataTypes tag outside objectModel!");
826 pushMode(DataTypesMode);
828 } else if (strcmp(name, "objectModel") == 0) {
829 if (!_modeStack.empty())
830 throw sg_exception("objectModel tag not at top level!");
831 pushMode(ObjectModelMode);
834 _modeStack.push_back(UnknownMode);
839 HLAOMTXmlVisitor::endElement(const char* name)
841 if (strcmp(name, "objectClass") == 0) {
842 _objectClassStack.pop_back();
843 } else if (strcmp(name, "interactionClass") == 0) {
844 _interactionClassStack.pop_back();
845 } else if (strcmp(name, "enumeratedData") == 0) {
846 _enumeratedDataName.clear();
847 } else if (strcmp(name, "fixedRecordData") == 0) {
848 _fixedRecordDataName.clear();
849 } else if (strcmp(name, "variantRecordData") == 0) {
850 _variantRecordDataName.clear();
853 _modeStack.pop_back();
857 HLAOMTXmlVisitor::getAttribute(const char* name, const XMLAttributes& atts)
859 int index = atts.findAttribute(name);
860 if (index < 0 || atts.size() <= index)
861 return std::string();
862 return std::string(atts.getValue(index));
866 HLAOMTXmlVisitor::getAttribute(const std::string& name, const XMLAttributes& atts)
868 int index = atts.findAttribute(name.c_str());
869 if (index < 0 || atts.size() <= index)
870 return std::string();
871 return std::string(atts.getValue(index));
874 } // namespace simgear