X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fhla%2FHLADataType.cxx;h=1eaf045655f52eb5e1382f95c902cfe002afa07e;hb=201cb61f842ef50a19438e3872ba22e588fa1afc;hp=b22fb218be97f16a72140e0ea6d7b31696ac5b52;hpb=baf511684119e219906fa37f3e7c7f43151bb435;p=simgear.git diff --git a/simgear/hla/HLADataType.cxx b/simgear/hla/HLADataType.cxx index b22fb218..1eaf0456 100644 --- a/simgear/hla/HLADataType.cxx +++ b/simgear/hla/HLADataType.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -15,6 +15,12 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + #include "HLADataType.hxx" #include "HLADataElement.hxx" @@ -39,12 +45,6 @@ HLADataType::accept(HLADataTypeVisitor& visitor) const visitor.apply(*this); } -const HLADataTypeReference* -HLADataType::toDataTypeReference() const -{ - return 0; -} - const HLABasicDataType* HLADataType::toBasicDataType() const { @@ -69,36 +69,205 @@ HLADataType::toFixedRecordDataType() const return 0; } -const HLAVariantDataType* -HLADataType::toVariantDataType() const +const HLAVariantRecordDataType* +HLADataType::toVariantRecordDataType() const { return 0; } +bool +HLADataType::recomputeAlignment() +{ + unsigned alignment = getAlignment(); + _recomputeAlignmentImplementation(); + return alignment != getAlignment(); +} + void -HLADataType::setAlignment(unsigned alignment) +HLADataType::releaseDataTypeReferences() { - /// FIXME: more checks - if (alignment == 0) - _alignment = 1; - else - _alignment = alignment; } -HLADataTypeReference::~HLADataTypeReference() +class HLADataType::_DataElementIndexVisitor : public HLADataTypeVisitor { +public: + _DataElementIndexVisitor(HLADataElementIndex& index, const std::string& path, std::string::size_type offset) : + _index(index), + _path(path), + _offset(offset), + _success(false) + { } + virtual ~_DataElementIndexVisitor() + { } + + virtual void apply(const HLADataType& dataType) + { + if (_path.size() == _offset) + _success = true; + } + virtual void apply(const HLAArrayDataType& dataType) + { + if (_path.size() == _offset) { + _success = true; + return; + } + if (_path.size() < _offset) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected array subscript at the end of the path!"); + return; + } + if (_path[_offset] != '[') { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected array subscript at the end of the path!"); + return; + } + ++_offset; + if (_path.size() <= _offset) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected closing array subscript at the end of the path!"); + return; + } + unsigned index = 0; + bool closed = false; + while (_offset <= _path.size()) { + if (_path[_offset] == ']') { + ++_offset; + closed = true; + break; + } + unsigned v = _path[_offset] - '0'; + // Error, no number + if (10 <= v) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Array subscript is not a number!"); + return; + } + index *= 10; + index += v; + ++_offset; + } + if (!closed) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected closing array subscript at the end of the path!"); + return; + } + if (!dataType.getElementDataType()) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Undefined array element data type!"); + return; + } + _index.push_back(index); + _success = dataType.getElementDataType()->getDataElementIndex(_index, _path, _offset); + } + + virtual void apply(const HLAFixedRecordDataType& dataType) + { + if (_path.size() == _offset) { + _success = true; + return; + } + if (_path.size() < _offset) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected field name at the end of the path!"); + return; + } + if (_path[_offset] == '.') + ++_offset; + if (_path.size() <= _offset) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected field name at the end of the path!"); + return; + } + std::string::size_type len = std::min(_path.find_first_of("[.", _offset), _path.size()) - _offset; + unsigned index = 0; + while (index < dataType.getNumFields()) { + if (_path.compare(_offset, len, dataType.getFieldName(index)) == 0) + break; + ++index; + } + if (dataType.getNumFields() <= index) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Field \"" << _path.substr(_offset, len) << "\" not found in fixed record data type \"" + << dataType.getName() << "\"!"); + return; + } + if (!dataType.getFieldDataType(index)) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Undefined field data type in variant record data type \"" + << dataType.getName() << "\" at field \"" << dataType.getFieldName(index) << "\"!"); + return; + } + _index.push_back(index); + _success = dataType.getFieldDataType(index)->getDataElementIndex(_index, _path, _offset + len); + } + + virtual void apply(const HLAVariantRecordDataType& dataType) + { + if (_path.size() == _offset) { + _success = true; + return; + } + if (_path.size() < _offset) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected alternative name at the end of the path!"); + return; + } + if (_path[_offset] == '.') + ++_offset; + if (_path.size() <= _offset) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Expected alternative name at the end of the path!"); + return; + } + std::string::size_type len = std::min(_path.find_first_of("[.", _offset), _path.size()) - _offset; + unsigned index = 0; + while (index < dataType.getNumAlternatives()) { + if (_path.compare(_offset, len, dataType.getAlternativeName(index)) == 0) + break; + ++index; + } + if (dataType.getNumAlternatives() <= index) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Alternative \"" << _path.substr(_offset, len) << "\" not found in variant record data type \"" + << dataType.getName() << "\"!"); + return; + } + if (!dataType.getAlternativeDataType(index)) { + SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n" + << "Undefined alternative data type in variant record data type \"" + << dataType.getName() << "\" at alternative \"" << dataType.getAlternativeName(index) << "\"!"); + return; + } + _index.push_back(index); + _success = dataType.getAlternativeDataType(index)->getDataElementIndex(_index, _path, _offset + len); + } + + HLADataElementIndex& _index; + const std::string& _path; + std::string::size_type _offset; + bool _success; +}; + +bool +HLADataType::getDataElementIndex(HLADataElementIndex& index, const std::string& path, std::string::size_type offset) const { + _DataElementIndexVisitor visitor(index, path, offset); + accept(visitor); + return visitor._success; } void -HLADataTypeReference::accept(HLADataTypeVisitor& visitor) const +HLADataType::setAlignment(unsigned alignment) { - visitor.apply(*this); + /// FIXME: more checks + if (alignment == 0) + _alignment = 1; + else + _alignment = alignment; } -const HLADataTypeReference* -HLADataTypeReference::toDataTypeReference() const +void +HLADataType::_recomputeAlignmentImplementation() { - return this; } }